Search code examples
javalibgdxtouchactor

Libgdx Actor undetected touch input


I am looking for touch detection. The code showed below is what I did to set a circle in my app. I want detect touch on this circle and not around or on the entire texture. The strange thing is that touch isn't detected, in nowhere I can detect it Circle class:

public class Circle_Obj extends Actor{
    private Vector2 position;
    private float radius;

    private com.badlogic.gdx.math.Circle circle;
    private Texture texture;

    public Circle_Obj(float x, float y, float radius) {

        position = new Vector2(x,y);
        this.radius = radius;

        circle = new com.badlogic.gdx.math.Circle(x,y,radius);
        texture = new Texture(Gdx.files.internal("texture.png"));

        addListener(new InputListener(){
            @Override
            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
                Gdx.app.log("TOUCHED", " TOUCHED ");
                return true;
            }
        });

    }

    @Override
    public void draw(Batch batch, float parentAlpha) {
        batch.draw(texture,0, 0);
}
}

Screen class :

public class GameScreen implements Screen {
    private Stage stage;
    private Circle_Obj circle_obj;

    public GameScreen() {
        circle_obj = new Circle_Obj(Static_values.Width/2, Static_values.Height/2, Static_values.Width / 100 * 10);

        stage = new Stage(new FitViewport(Static_values.Width/3, Static_values.Height/3));
        stage.addActor(circle_obj);

        Gdx.input.setInputProcessor(stage);

    }

    @Override
    public void render(float delta) {
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        stage.draw();    
        }
    @Override
    public void dispose() {
        stage.dispose();
        }
/** other methods **/
}

Solution

  • You can use libgdx's touch detection in a circle class.Only touched circle will affected.

        public boolean is_touched() {
        if (Gdx.input.justTouched()) {
            float xx = Gdx.input.getX();
            float yy = Gdx.input.getY();
            float x = position.x;
            float y = position.y;
            return (xx - x) * (xx - x) + (yy - y) * (yy - y) < radius * radius;
        }
    }
    

    If you are using a lot of circles so it is better for performance to take touch position as a parameter.

    in the circle class

    public boolean is_touched(float xx,float yy) {
                float x = position.x;
                float y = position.y;
                return (xx - x) * (xx - x) + (yy - y) * (yy - y) < radius * radius;
            }
        }
    

    and in another class

    if (Gdx.input.justTouched()) {
                float xx = Gdx.input.getX();
                float yy = Gdx.input.getY();
                if (circle0.is_touched(xx, yy)) {
                    // do something about circle0
                }
                if (circle1.is_touched(xx, yy)) {
                    // do something about circle1
                }
                if (circle2.is_touched(xx, yy)) {
                    // do something about circle2
                }
            }
    

    You can also ignore one of the touched circles when two circles overlaps and user touchs the overlapping area.

    if (Gdx.input.justTouched()) {
                    float xx = Gdx.input.getX();
                    float yy = Gdx.input.getY();
                    if (circle0.is_touched(xx, yy)) {
                        // do something about circle0
                    }
                    else if (circle1.is_touched(xx, yy)) {
                        // do something about circle1
                    }
                    else if (circle2.is_touched(xx, yy)) {
                        // do something about circle2
                    }
                }