0

I have a collision Rectangle (the libgdx one, not awt) set to a ball's coordinates. What I want to do is check if I've tapped on it. Two problems:
a.) I don't know where the origin of the rectangle's coordinates is.
b.) I can't find a way of correct way of correcting for the tap location.
What can I do?

Edit per request:

public void create() {
camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());

...

camera.unproject(tmpPos);
}

public void render() {
if (Gdx.input.isTouched()) {
            float x = Gdx.input.getX();
            float y = Gdx.input.getY();
            tmpPos.set(x, y, 0);
            camera.unproject(tmpPos);
            // now the world coordinates are tmpPos.x and tmpPos.y
            if (target.contains(tmpPos.x, tmpPos.y)) {
                System.out.println("Touched. ");
                score++;
            }

            System.out.println("Score: " + score + "..." + "X: " + (int) tmpPos.x + "...Y: " + (int) tmpPos.y);
        ...
        }
IHazABone
  • 525
  • 2
  • 6
  • 20
  • 1.) `setOrigin(0, 0);` 2.) http://stackoverflow.com/questions/24501268/how-do-i-detect-if-a-sprite-was-touched-in-java-libgdx – EpicPandaForce Sep 17 '14 at 08:39
  • although technically if you are using a `Camera` rather than your own `Matrix3` for orthographic transformation, then I think `camera.unproject()` can give you the coordinates of the tap. – EpicPandaForce Sep 17 '14 at 08:41
  • Thanks for the reply. I'll take a look and try these when I can. – IHazABone Sep 17 '14 at 17:15

2 Answers2

0

I assume that you have a orthographic camera. (you really can't make a game without it)

You don't need to know its origin to check if is touched, but if you want to, the origin is

float originX = rectangle.x + rectangle.width / 2f;
float originY = rectangle.y + rectangle.height / 2f;

Anyways, you will need to unproject your touch coordinates, this means that you need to translate from the screen position to the camera position (world position). For this you need a Vector3, is prefered to declare it somewhere outside of the method you are using, because initializing a object in every frame is not recommended.

Vector3 tmpPos=new Vector3();

And now check if your rectangle is touched, anywhere you want. You have 2 ways to do this.

  1. Do this in the render / update method, checking the position of the finger / cursor.

public void render(float delta) {

   if (Gdx.input.isTouched() { // use .isJustTouched to check if the screen is touched down in this frame
            // so you will only check if the rectangle is touched just when you touch your screen.
            float x = Gdx.input.getX();
            float y = Gdx.input.getY();
            tmpPos.set(x, y, 0);
            camera.unproject(tmpPos);
            // now the world coordinates are tmpPos.x and tmpPos.y
            if (rectangle.contains(tmpPos.x, tmpPos.y)) {
                // your rectangle is touched
                System.out.println("YAAAY I'm TOUCHED");
            }

        }
    }

Options 2, use a input listener, so you only check when a touch event is triggered. In the show / create method of your screen / game add your input listener

public void show() {

// .....
Gdx.input.setInputProcessor(new InputProcessor() {

    // and in the method that you want check if the rectangle is touched
    @override
    public void touchDown(int screenX, int screenY, int pointer, int button) {
        tmpPos.set(screenX, screenY, 0);
        camera.unproject(tmpPos);
        // now the world coordinates are tmpPos.x and tmpPos.y
        if (rectangle.contains(tmpPos.x, tmpPos.y)) {
            // your rectangle is touched
            System.out.println("YAAAY I'm TOUCHED");
        }
    }

    // and the rest of the methods
    // ....
    //

});

}

I would use the second way. let me know if it worked for you.

Boldijar Paul
  • 5,405
  • 9
  • 46
  • 94
  • I have `camera.unproject(tmpPos);` in my create() method, and your first method in render(). It doesn't seem to be working. It's reporting the coordinates from the center, and the only thing thus far that's doing so. I have my rectangle at `50, 50` which is the bottom left corner, and that's `-300, -460` with this. – IHazABone Sep 17 '14 at 21:45
  • Added in original question. – IHazABone Sep 18 '14 at 05:14
  • That is not full code, is just a part of it. Provide the full class. Pastebin it and link here – Boldijar Paul Sep 18 '14 at 16:38
  • The full class is thousands of lines already. That's the only even remotely relevant part. – IHazABone Sep 18 '14 at 16:44
  • If your class is 1000 + lines that is bad..you don't want to make such a big class, using more classes is a better ideea. Anyways, that code should be working, 1) how do you draw your rectangle? 2) is the render method that you wrote called ? – Boldijar Paul Sep 18 '14 at 16:46
  • I am using multiple classes, the main one just happens to be big. Not why I came here. Render is called every frame, yes. `target = new Rectangle(x, y, 64, 64);` is how I create the rectangle, and then I draw a texture on the same coordinates. – IHazABone Sep 18 '14 at 16:52
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/61512/discussion-between-boldijar-paul-and-ihazabone). – Boldijar Paul Sep 18 '14 at 17:47
0

My eventual solution was this:

Set the vector to the touch coordinates, however, with this correction: (Gdx.input.getY() * -1) + cy where cy is the height of the screen. I then unproject that vector, and draw it. Instead of the inverse y location I got without the correction, the circle follows directly under my finger and communicates with other objects in the world perfectly.

IHazABone
  • 525
  • 2
  • 6
  • 20