Search code examples
javaandroidlibgdxtouchbox2d

libgdx - Check if body is touch


I have some bodies around the screen(Ball[] balls), and I would like to delete them when user touches them.

Also, I have an Image as userData of the bodies.

I dont want to make a function to all Image, because the balls have to be deleted in an order.

What is the best way to detect if a body is touch?


Solution

  • There is at least two ways I know you can use to accomplish this.

    Method 1: If you are using Box2D.

    In your touchDown function you could have something like this:

        Vector3 point;
        Body bodyThatWasHit;
    
        @Override
        public boolean touchDown (int x, int y, int pointer, int newParam) {
    
            point.set(x, y, 0); // Translate to world coordinates.
    
            // Ask the world for bodies within the bounding box.
            bodyThatWasHit = null;
            world.QueryAABB(callback, point.x - someOffset, point.y - someOffset, point.x + someOffset, point.y + someOffset);
    
            if(bodyThatWasHit != null) {
                // Do something with the body
            }
    
            return false;
        }
    

    The QueryCallback from the QueryAABB function can be overriden like this:

    QueryCallback callback = new QueryCallback() {
        @Override
        public boolean reportFixture (Fixture fixture) {
            if (fixture.testPoint(point.x, point.y)) {
                bodyThatWasHit = fixture.getBody();
                return false;
            } else
                return true;
        }
    };
    

    So, to sum up, you use the world object's function QueryAABB to check for a fixture on a position. Then we override the callback to get the body from the reportFixture function in the QueryCallback.

    If you want to see an implementation of this method, you can check out this: https://github.com/libgdx/libgdx/blob/master/tests/gdx-tests/src/com/badlogic/gdx/tests/Box2DTest.java

    Method 2:

    If you are using Scene2D or your objects extends Actor in some way and can use a clickListener.

    You can add a clickListener to your Ball objects, or images, if you are using Scene2D and the Actor class.

    private void addClickListener() {
        this.addListener(new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                wasTouched(); // Call a function in the Ball/Image object.
            }
        });
    }