I recently asked this question, it works perfectly, the only problem I'm having is that the whole game is based on touch events, when a user touches the screen, an object gets created.
What's happening now is that when a user touches the pause button (texture packer), an object gets created and the game is paused. I want to prevent objects from being created if the pause is touched. I used to be able to do something like this:
private Vector3 touchPos;
touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touchPos);
if (Gdx.input.justTouched()) {
if (touchPos.x > pauseX && touchPos.x < pauseX + pauseX) {
if (touchPos.y > pauseY && touchPos.y < pauseX + pauseY) {
setGamePause(!getGamePause());
}}}
But doesn't seem to be working with texture packer, maybe my implementation is wrong, not sure, is there another approach?
private float pauseY = Gdx.graphics.getHeight() - 115;
private float pauseX = Gdx.graphics.getWidth() / 6;
button.setSize(150, 150)
It's on the top left of the screen
If pauseX and pauseY is left position and right position of a rectangle/button respectively then
you need width and height of button/rectangular area, like suppose that buttonWidth, buttonHeight.
if(Gdx.input.justTouched()) {
if (touchPos.x > pauseX && touchPos.x < pauseX + button.getWidth()) {
if (touchPos.y > pauseY && touchPos.y < pauseY + button.getHeight()) {
setGamePause(!getGamePause());
}
}
}
Please Check Test :
public class GdxTest extends Game implements InputProcessor{
private Stage stage;
Vector3 vector3;
TextButton button;
float pauseX,pauseY;
#Override
public void create() {
vector3=new Vector3();
ExtendViewport extendViewport=new ExtendViewport(700,1200,new OrthographicCamera());
stage=new Stage(extendViewport);
Skin skin=new Skin(Gdx.files.internal("skin/uiskin.json"));
skin.get("font-label", BitmapFont.class).getRegion().getTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
pauseX=300;
pauseY=500;
button=new TextButton("Pause",skin);
button.setPosition(pauseX,pauseY);
stage.addActor(button);
Gdx.input.setInputProcessor(this);
}
#Override
public void render() {
super.render();
Gdx.gl.glClearColor(0,1,1,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.draw();
stage.act();
////Touch Detection without processor
vector3.set(Gdx.input.getX(),Gdx.input.getY(),0);
stage.getCamera().unproject(vector3);
if(Gdx.input.justTouched()){
if(vector3.x>pauseX && vector3.x<pauseX+button.getWidth() && vector3.y>pauseY && vector3.y<pauseY+button.getHeight())
System.out.println("TOuched");
}
///////
}
#Override
public void resize(int width, int height) {
super.resize(width,height);
stage.getViewport().update(width,height);
}
#Override
public void dispose() {
stage.dispose();
}
#Override
public boolean keyDown(int keycode) {
return false;
}
#Override
public boolean keyUp(int keycode) {
return false;
}
#Override
public boolean keyTyped(char character) {
return false;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button1) {
vector3.set(screenX,screenY,0);
stage.getCamera().unproject(vector3);
if(vector3.x>pauseX && vector3.x<pauseX+button.getWidth() && vector3.y>pauseY && vector3.y<pauseY+button.getHeight())
System.out.println("TOuched");
return false;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
return false;
}
#Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}
#Override
public boolean scrolled(int amount) {
return false;
}
}
Related
I am new to LibGDX library,
I am building the Snakes and ladders game with it.
I have a player class, it extends itself from Sprite class.
I want it to move when a dice is thrown.
But it becomes suddenly, I cannot see the movement.
public void updatePlayer(){
//this.setPosition(body.getPosition().x, body.getPosition().y);
game.getBatch().begin();
draw(game.getBatch());
game.getBatch().end();
}
public void updatePlayer(int dice){
if (dice > 0 && dice <= 6){
for (int i = 0; i < dice; i++){
float laterX = getX() + 48;
if (laterX > GameInfo.WIDTH - 20){
//setPosition(3, getY() + 5f);
translateY(5);
updatePlayer();
}else {
translateX(5);
//setPosition(getX() + 5, getY());
updatePlayer();
}
}
}
}
You cannot see movement 'cause you set the position. Use translate to move it.
doc
Sprite#setPosition() //Sets the position where the sprite will be drawn
Sprite#translate() //Sets the position relative to the current position where the sprite will be drawn.
My loop class:
public class Game extends ScreenAdapter {
private static String worldName;
private EntityPlayer player;
private FlatWorld flatWorld;
public static World world;
// private Box2DDebugRenderer debugRenderer;
private static boolean pauseGame;
public Game(String worldName){
world = new World(new Vector2(0, 0), false);
//this.debugRenderer = new Box2DDebugRenderer();
this.worldName = worldName;
this.player = PlayerDiskUtils.readPlayerFromDisk(this.worldName);
this.flatWorld = FlatWorldUtils.loadFlatWorld(this.worldName);
this.player.setCamera(this.flatWorld.getWorldSize());
this.flatWorld.setBlocksCourt(FlatWorldUtils.readBlocksCourt(this.flatWorld.getWorldSize().getWidth(), this.flatWorld.getWorldSize().getHeight(), this.worldName));
Gdx.input.setInputProcessor(new GameInputAdapter());
}
#Override
public void render(float delta) {
world.step(1/60f, 6, 2);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
Gdx.gl.glClearColor(0f, 0f, 0f, 1f);
this.flatWorld.getBlocksCourt().renderWorld(player.getCamera());
this.player.update(this.flatWorld, this.flatWorld.getWorldSize().getWidth(), this.flatWorld.getWorldSize().getHeight());
this.flatWorld.blocks.renderBlocks(this.player.getCamera());
this.player.renderInventory();
this.player.playerHud.render(this.player.states.getHealth(), this.player.states.getHungry(), this.player.states.getThirsty());
}
#Override
public void dispose() {
this.pause();
world = null;
worldName = null;
this.flatWorld.blocks.disposeBlocks();
}
#Override
public void pause() {
super.pause();
PlayerDiskUtils.writePlayerToDisk(this.worldName, this.player);
FlatWorldUtils.saveFlatWorld(this.worldName, this.flatWorld);
}
public static String getWorldName() { return worldName; }
public static boolean isPauseGame() { return pauseGame; }
public static void setPauseGame(boolean pauseGame) { Game.pauseGame = pauseGame; }
/**
* This is the input adapter of the player.
* Here keys and input event are set
*/
private class GameInputAdapter extends InputAdapter{
#Override //Mouse moving
public boolean mouseMoved(int screenX, int screenY) { return player.rotatePlayerToMouse(); }
#Override //Keys
public boolean keyDown(int keycode) {
if(keycode == Input.Keys.ESCAPE){ if(player.inventoryOpen) player.inventoryOpen = false;}
if(keycode == Input.Keys.E){ player.inventoryOpen = !player.inventoryOpen; }
return true;
}
#Override //Mouse buttons
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
Vector3 mouseCords3 = player.getCamera().unproject(new Vector3(screenX, screenY, 0));
return onBodyClick(new Vector2(mouseCords3.x, mouseCords3.y), button);
}
private boolean onBodyClick(Vector2 mouseCords, int button){
if(player.inventoryOpen) return false;
final Body[] body = new Body[1];
//Save inside body[0] the body which has been clicked
world.QueryAABB(fixture -> {
if(fixture.testPoint(mouseCords)){
body[0] = fixture.getBody();
}
return true;
}, mouseCords.x, mouseCords.y, mouseCords.x + 0.5f, mouseCords.y + 0.5f);
if(body[0] == null){
if(button == Input.Buttons.RIGHT){
player.onPlayerRightClick(flatWorld, mouseCords);
}
}else{
if(button == Input.Buttons.RIGHT){
((Block)body[0].getUserData()).onBlockClicked(player);
}else if(button == Input.Buttons.LEFT){
player.onPlayerBlockDestroying(flatWorld, (Block)body[0].getUserData(), mouseCords);
}
}
return true;
}
}
}
My code about player moving(it is 3d model, but it coult help you):
public void move(FlatWorld flatWorld, int worldWidth, int worldHeight) {
int x = 0, y = 0;
if (Gdx.input.isKeyPressed(Input.Keys.W))
y = 1;
if (Gdx.input.isKeyPressed(Input.Keys.S))
y = -1;
if (Gdx.input.isKeyPressed(Input.Keys.A))
x = -1;
if (Gdx.input.isKeyPressed(Input.Keys.D))
x = 1;
if(x != 0 || y != 0) {
if (this.canPlayerMove(flatWorld, new Vector3(x, y, 0), worldWidth, worldHeight)) {
this.modelInstance.transform.translate(x, y, 0);
this.moveCamera(worldWidth, worldHeight);
}
}
this.renderModel(null);
}
As you can see, I translate my model without call setPosition()
foreword: on desktop everything works just perfect.
Trouble appers when i'm testing my project on phone
I start the game. Here is some buttons on screen: button_1, button_2, button_3. For example i'm touching button_1: with very first touch after app start nothing happing at all. If i'm touching button_1 again, it works fine -> touchDown (button image goes down for 10px) then touchUp (button image goes up for 10px and button code run). But if i touch another button instead, for example button_2, only touchDown of button_1 occurs (button_1 image goes down for 10px and up) and nothing else. It's happens for every button, so i need to touch button twice to make it work.
Button class:
public class myButton {
private float x, y, width, height;
private Texture buttonUp;
public Rectangle bounds;
private boolean isPressed = false;
public myButton(float x, float y, float width, float height, Texture buttonUp) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.buttonUp = buttonUp;
bounds = new Rectangle(x, y, width, height);
}
public boolean isClicked(int screenX, int screenY) {
return bounds.contains(screenX, screenY);
}
public void draw(SpriteBatch batch) {
if (isPressed) {
batch.draw(buttonUp, x, y - 10, width, height);
} else {
batch.draw(buttonUp, x, y, width, height);
}
}
public boolean isTouchDown(int screenX, int screenY) {
if (bounds.contains(screenX, screenY)) {
isPressed = true;
return true;
}
return false;
}
public boolean isTouchUp(int screenX, int screenY) {
if (bounds.contains(screenX, screenY) && isPressed) {
isPressed = false;
return true;
}
isPressed = false;
return false;
}
}
InputHandlerer:
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
screenX = (int) touchPos.x;
screenY = (int) touchPos.y;
playButton.isTouchDown(screenX, screenY);
return true;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
screenX = (int) touchPos.x;
screenY = (int) touchPos.y;
if (playButton.isTouchUp(screenX, screenY)) {
start();
return true;
}
}
in create() method i've got:
touchPos = new Vector3();
Gdx.input.setInputProcessor(new InputHandlerer());
camera = new OrthographicCamera();
viewport = new FitViewport(1080, 1920, camera);
in render() method i've got:
touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touchPos);
batch.setProjectionMatrix(camera.combined);
I repeat - on desktop every button works properly, but on phone not. What could be the problem?
Maybe on desktop is working because you can do only one click at a time, instead on phone you should manage the pointers, also if you don't want to use the multitouch.
On your InputHandlerer class you have to initilize:
private int button1pointer = -1;
private boolean button1isPressed = false;
Then you have to manage the pointers on your tochDown/Up methods:
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
for (int i = 0; i < 2; i++) { //here you can choose how many touches you can manage
if (Gdx.input.isTouched(i)) {
screenX = (int) touchPos.x;
screenY = (int) touchPos.y;
if (playButton.isTouchDown(screenX, screenY) && (button1pointer != i) && (!button1isPressed)) {
button1pointer = i;
button1isPressed = true;
}
return true;
}
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
if (!(Gdx.input.isTouched(pointer)) && (button1pointer == pointer) && (button1isPressed)) {
button1pointer = -1;
button1isPressed = false;
start();
return true;
}
}
I recently started programming an app in LibGDX. With this app, one can only now press on boxes which are then filled in blue.
In principle everything works. The problem is only if I move the orthographic camera, or start to zoom, then my input processor still remains in the same place.
In short. Because the camera is moved or zoomed, the input does not work properly.
I have two times here Schreenshots attached so you can see what I mean.
The red dots are always where I pressed.
Regards Timux ;D
Here it works correctly
No more
No problem when I move or zoom my camera, I've tested, you can check this.
May be you're not using unproject() method of camera that translate a point given in screen coordinates to world space.
public class GdxText extends ApplicationAdapter implements InputProcessor {
OrthographicCamera cam;
Texture texture;
Sprite firstSprite,secondSprite;
SpriteBatch spriteBatch;
Vector3 vector3;
#Override
public void create() {
vector3=new Vector3();
cam=new OrthographicCamera();
texture=new Texture("badlogic.jpg");
float w=Gdx.graphics.getWidth();
float h=Gdx.graphics.getHeight();
spriteBatch=new SpriteBatch();
firstSprite=new Sprite(texture);
firstSprite.setSize(100,100);
firstSprite.setPosition(w/2-150,h/2-50);
secondSprite=new Sprite(texture);
secondSprite.setSize(100,100);
secondSprite.setPosition(w/2+50,h/2-50);
Gdx.input.setInputProcessor(this);
}
#Override
public void render() {
Gdx.gl.glClearColor(1,1,1,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
spriteBatch.setProjectionMatrix(cam.combined);
spriteBatch.begin();
firstSprite.draw(spriteBatch);
secondSprite.draw(spriteBatch);
spriteBatch.end();
}
#Override
public void resize(int width, int height) {
cam.setToOrtho(false,width,height);
cam.update();
}
#Override
public boolean keyDown(int keycode) {
if(keycode== Input.Keys.UP) {
cam.zoom -= cam.zoom * .1;
cam.update();
}else if(keycode==Input.Keys.DOWN) {
cam.zoom += cam.zoom * .1;
cam.update();
}
if(keycode== Input.Keys.LEFT) {
cam.position.add(2f,0,0);
cam.update();
}else if(keycode==Input.Keys.RIGHT) {
cam.position.add(-2f,0,0);
cam.update();
}
return false;
}
#Override
public boolean keyUp(int keycode) {
return false;
}
#Override
public boolean keyTyped(char character) {
return false;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
vector3.set(screenX,screenY,0);
Vector3 ori=cam.unproject(vector3);
if(firstSprite.getBoundingRectangle().contains(ori.x,ori.y))
System.out.println("Touch on First Sprite");
if(secondSprite.getBoundingRectangle().contains(ori.x,ori.y))
System.out.println("Touch on Second Sprite");
return false;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
return false;
}
#Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}
#Override
public boolean scrolled(int amount) {
return false;
}
#Override
public void dispose() {
spriteBatch.dispose();
texture.dispose();
}
}
I'm developing a cross-plattform application in java (focusing on android right now) and I'm mainly using libgdx to achieve this. Right now I have a screen that consists of rows of clickable buttons where the rows extend below the screen. I want to allow the user to touch/flick scroll up and down in order for them to view all the different buttons available.
Some relevant information: I'm using an Orthographic Camera and an InputProcessor.
Right now I'm thinking that the camera is supposed to move up and down based on the touchDragged method in the InputProcessor.
I'll attach the relevant code in the GameRenderer and InputHandler classes below. (with a lot of unrelevant code removed.) Any help or suggestions would be great, I've googled like a mad man and been stuck for a day now.
GameRenderer
public class GameRenderer {
private GameWorld myWorld;
private OrthographicCamera cam;
private SpriteBatch batcher;
private ArrayList<Element> elements = new ArrayList<Element>();
private int gameHeight;
public GameRenderer(GameWorld world, int gameHeight) {
myWorld = world;
elements = myWorld.getElement();
this.gameHeight = gameHeight;
cam = new OrthographicCamera();
cam.setToOrtho(true, 136, gameHeight);
batcher = new SpriteBatch();
batcher.setProjectionMatrix(cam.combined);
}
public void render() {
Gdx.gl.glClearColor(0, 191, 255, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batcher.begin();
for (int i = 0; i < elements.size(); i++) {
Element e = (Element) elements.get(i);
batcher.draw(AssetLoader.element, e.getLocationX(), e.getLocationY(), e.getElementWidth(), e.getElementHeight());
AssetLoader.font.draw(batcher, e.getFormula(), e.getLocationX() + 4, e.getLocationY() + 3);
}
batcher.end();
}
}
InputHandler
public class InputHandler implements InputProcessor
{
private Element myElement;
private float scaleX, scaleY;
private ArrayList<Element> elements;
GameWorld myWorld;
GameRenderer myRenderer;
public InputHandler(GameWorld game, GameRenderer renderer, ArrayList elementList, float x, float y) {
myWorld = game;
myRenderer = renderer;
elements = elementList;
scaleX = x;
scaleY = y;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
return true;
}
#Override
public boolean keyDown(int keycode) {
return false;
}
#Override
public boolean keyUp(int keycode) {
return false;
}
#Override
public boolean keyTyped(char character) {
return false;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
return false;
}
#Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}
#Override
public boolean scrolled(int amount) {
return false;
}
}
I have written the following code. It is simple rectangle in middle of the screen. I want the rectangle to move -50 in y direction onClick (direction is just for illustration purposes only). Despite trying various methods. I cannot get the code to work. I am not sure if I am doing something fundamentally wrong. I would appreciate some direction from better learned minds.
package com.mygdx.gameobjects;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
public class Hero extends Rectangle implements InputProcessor{
private Rectangle hero;
private Vector2 position;
public Hero(){
position = new Vector2(x, y);
hero = new Rectangle(position.x+68-10, position.y+204-30-20, 20, 20);
}
public void update (float delta) {
}
public void onClick() {
position.y = -50;
}
public Rectangle getHero() {
return hero;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
onClick();
return true;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
return false;
}
#Override
public boolean keyDown(int keycode) {
return false;
}
#Override
public boolean keyUp(int keycode) {
return false;
}
#Override
public boolean keyTyped(char character) {
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
return false;
}
#Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}
#Override
public boolean scrolled(int amount) {
return false;
}
}