Search code examples
javalibgdx

libgdx input method not called


I have a screen class which sets the input processor to the stage class Gdx.input.setInputProcessor(gameStage);, and my stage class implements inputProcessor public class GameStage extends Stage implements InputProcessor. The input methods in my stage class are not called and I can't figure out why. I tested it with this method

@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
    batch.begin();
    font.draw(batch, "text", 200, 50);
    batch.end();
    return super.touchDown(screenX, screenY, pointer, button);
}

But the text is not drawn, when I try it with Gdx.input.isTouched() in the act method, it does work.

Thanks

EDIT: All the code

public class GameScreen implements Screen {
        private Game game;
        private GameStage gameStage;
        private OrthographicCamera camera;
        private Viewport viewport;

        private Box2DDebugRenderer renderer;

        public GameScreen(Game game) {
            this.game = game;
            this.camera = new OrthographicCamera();
            this.viewport = new ScreenViewport(camera);
            this.gameStage = new GameStage(viewport);
            this.renderer = new Box2DDebugRenderer();
            Gdx.input.setInputProcessor(gameStage);
        }

        public OrthographicCamera getCamera() {
            return this.camera;
        }

        @Override
        public void show() {

        }

        @Override
        public void render(float delta) {
            Gdx.gl.glClearColor(247/255.0f, 247/255.0f, 247/255.0f, 1);
            Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

            gameStage.act();
            renderer.render(gameStage.getWorld(), camera.combined);
            gameStage.draw();
        }

        @Override
        public void resize(int width, int height) {

        }

        @Override
        public void pause() {

        }

        @Override
        public void resume() {

        }

        @Override
        public void hide() {

        }

        @Override
        public void dispose() {

        }
    }

Stage class:

public class GameStage extends Stage {
    private World world;
    private Player player;
    private BitmapFont font;

    private Box2DDebugRenderer renderer;

    public GameStage(Viewport viewport) {
        super(viewport);
        font = new BitmapFont();
        setUpWorld();
    }

    public void setUpWorld() {
        world = WorldUtils.createWorld();
        player = new Player(WorldUtils.createPlayer(world));
    }

    @Override
    public void draw() {
        super.draw();

        getBatch().begin();
        font.draw(getBatch(), "Position: X=" + player.getX() + " Y=" + player.getY(), 200, 50);
        getBatch().end();
    }

    @Override
    public void act(float delta) {
        super.act(delta);
        world.step(1 / 300f, 6, 2);
    }

    public World getWorld() {
        return this.world;
    }

    public Player getPlayer() {
        return this.player;
    }

    @Override
    public boolean touchDown(int screenX, int screenY, int pointer, int button) {
        player.move();
        super.touchDown(screenX, screenY, pointer, button);
        return true;
    }

    @Override
    public boolean touchDragged(int screenX, int screenY, int pointer) {
        return super.touchDragged(screenX, screenY, pointer);
    }

    @Override
    public boolean touchUp(int screenX, int screenY, int pointer, int button) {
        return super.touchUp(screenX, screenY, pointer, button);
    }
}

Player class:

public class Player extends Actor{
    private Body body;

    public Player(Body body) {
        this.body = body;
    }

    public void move() {
        body.applyForceToCenter(50000, 200, true);
    }
}

Solution

  • Don't draw inside your input handlers. Just store the coordinates. It's not working because you're trying to draw outside of the game loop. Also return false not the parent method, when you return true the input processor calls all the other matched input handlers. Something like this should do it.

    boolean touched;
    void draw(Batch batch)
        if(touched){
            batch.begin();
            font.draw(batch, "text", 200, 50);
            batch.end();
        }
    }
    @Override
    public boolean touchDown(int screenX, int screenY, int      
    pointer , int button) {
        super.touchDown(screenX, screenY, pointer, button);
        touched = true;
        return false;
    }
    @Override
    public boolean touchUp(int screenX, int screenY, int      
    pointer , int button) {
        super.touchUp(screenX, screenY, pointer, button);
        touched = false;
        return false;
    }
    

    Edit: Also remove implements InputProcessor The stage class already implements that class so you don't have to. This is probably what causing you handlers to be ignored. You're set input processor of the parent class as main handler but you're override the input handlers of interface not the parent so they aren't being seen.

    Edit 2: Try implementing InputProcessor and not extending Stage.

    public class GameStage InputProcessor {
        private Stage stage;
        private InputMultiplexer input;
        private World world;
        private Player player;
        private BitmapFont font;
    
        private Box2DDebugRenderer renderer;
    
        public GameStage(Viewport viewport) {
            stage = new Stage(viewport);
            font = new BitmapFont();
            setUpWorld();
            input = new InputMultiplexer();
            input.addProcessor(this);
            input.addProcessor(stage);
        }
    
        public void setUpWorld() {
            world = WorldUtils.createWorld();
            player = new Player(WorldUtils.createPlayer(world));
            stage.addActor(player)
        }
    
        @Override
        public void draw() {
            stage.draw();
    
            getBatch().begin();
            font.draw(getBatch(), "Position: X=" + player.getX() + " Y=" + player.getY(), 200, 50);
            getBatch().end();
        }
    
        @Override
        public void act(float delta) {
            stage.act(delta);
            world.step(1 / 300f, 6, 2);
        }
    
        public World getWorld() {
            return this.world;
        }
    
        public Player getPlayer() {
            return this.player;
        }
    
        public InputAdapter getInput(){
            return this.input;
        }
    
        public Stage getStage(){
            return this stage;
        }
    
        @Override
        public boolean touchDown(int screenX, int screenY, int pointer, int button) {
            player.move();
            return true;
        }
    
        @Override
        public boolean touchDragged(int screenX, int screenY, int pointer) {
            return true;
        }
    
        @Override
        public boolean touchUp(int screenX, int screenY, int pointer, int button) {
            return true;
        }
    }