miguel.renaud
miguel.renaud

Reputation: 85

How do I detect if a sprite was touched in Java libGDX?

In the past few days I've been porting my game (Apopalypse) to the Android Mobile platform. I've did a quick search on Google of sprite touch detection but didn't find anything helpful. Each balloon will pop once touched and I just need to detect if it's touched. Here's my balloon spawning code:

Rendering (x, y, width, and height are randomized):

public void render() {
    y += 2;
    balloon.setX(x);
    balloon.setY(y);
    balloon.setSize(width, height);
    batch.begin();
    balloon.draw(batch);
    batch.end();
}

Spawning in main game class:

addBalloon(new Balloon());

public static void addBalloon(Balloon b) {
    balloons.add(b);
}

Upvotes: 7

Views: 19024

Answers (7)

Kumar Saurabh
Kumar Saurabh

Reputation: 2305

in your class having the render method use can do following code:

Vector3 touchPoint=new Vector3();

void update()
{
  if(Gdx.input.justTouched())
   {
    //unprojects the camera
    camera.unproject(touchPoint.set(Gdx.input.getX(),Gdx.input.getY(),0));
    if(balloon.getBoundingRectangles().contains(touchPoint.x,touchPoint.y))
     {
      // will be here when balloon will be touched
     }
    }
   }

Upvotes: 8

markus schwarzer
markus schwarzer

Reputation: 1

Here is what i use in my sprite class. I give it the vector where i clicked camera.unproject(new Vector3().set(x,y,0));. returns true if clicked in the area of the sprite.

    /***
     * 
     * @param v3 Vector with MouseClickPosition
     * @return true if click was inside rectangle x --> x + width, y --> y + 
     * height
     */

    public boolean clicked(Vector3 v3){
    Rectangle rec = getBoundingRectangle();

    if(v3.x >= rec.x && v3.x < rec.x + getWidth()){
        if(v3.y >= rec.y && v3.y < rec.y + getHeight()){
            System.out.println("click_on\t" + v3.x + ", " + v3.y);
            return true;
        }
        else{
            return false;
        }
    }
    else{
        return false;
    }
}

Upvotes: 0

Kareem Hammad
Kareem Hammad

Reputation: 36

i have a simple solution it's like that create a small rectangle 1 pixel by one pixel

Rectangle rect;

rect = new Rectangle(0, 0, 1, 1);

then make a method called

touching_checking();

in this method we will do three things

first check if screen is touched

second put the rectangle where you touch the screen

then at last check if your rectangle overlaps with the sprite rectangle. like that

private void touching_checking() { if (Gdx.input.isTouched()) { rect.setPosition(Gdx.input.getX(), Gdx.input.getY()); if (rect.overlaps(back.getBoundingRectangle())) { //do what you want here } } } i have an array of sprites called levels i check which one i pressed like that

private void touching_checking() {
    if (Gdx.input.isTouched()) {
        rect.setPosition(Gdx.input.getX(), Gdx.graphics.getWidth() - Gdx.input.getY());
        for (int i = 0; i < levels.size; i++) {
            if (rect.overlaps(levels.get(i).getBoundingRectangle())) {
                //do what you want here
            }
        }
    }
}

Upvotes: 0

Netero
Netero

Reputation: 3819

i made a little class that i use for my games to detect is Sprite is touched

public class SpriteTouchable extends Sprite {

    public SpriteTouchable(Texture texture) {
        super(texture);
    }

    public SpriteTouchable(Sprite sprite) {
        set(sprite);
    }

    public static float xTrans(float x)
    {
        return x*Gdx.graphics.getWidth()/480;
    }

    public static float yTrans(float y)
    {
        return y*Gdx.graphics.getHeight()/320;
    }

    private boolean isTouched;

    /**
     * Type: Input Listener function
     * listen if this sprite button was pressed (touched)
     * @param marge : the extra touchable space out of sprite
     * @param x     : x position touched by user
     * @param y     : y position touched by user
     * 
     * return true  : Sprite touched
     * return false : Sprite not touched
     */
    public boolean isPressing(int marge,int x, int y) {
        if((x>getX() -xTrans(marge))&& x<getX() +getWidth()+xTrans(marge)) {
            if((y>getY() -yTrans(marge))&& y<getY()+getHeight()+yTrans(marge)) {
                return true;
            }
        }
        return false;
    }
}

 public boolean isTouched() {
    return isTouched;
 }

here how i use it

Gdx.input.setInputProcessor(new GameInputListener() {

            @Override
            public boolean touchUp(int screenX, int screenY, int pointer, int button) {

                return false;
            }

            @Override
            public boolean touchDown(int x, int yy, int pointer, int button) {
                int y = Gdx.graphics.getHeight() - yy;
                // if sprite + 10 of px marge is touched
                if(mySpriteTouchable.isPressing(10, x, y)) {
                    // sprite is touched down
                }
                return false;
            }
}

with the same logic you can detect sprite releasing and also you can customize it for effect size when the sprite is touched and more...

hope this was helpfull !

Upvotes: 2

EpicPandaForce
EpicPandaForce

Reputation: 81539

This is how I did it, but depending on the scene you are using and the elements that can be touched, there can be slightly more optimized ways of doing this:

public GameScreen implements Screen, InputProcessor
{

  @Override
  public void show()
  {
      Gdx.input.setInputProcessor(this);
  }

  @Override
  public boolean touchDown(int screenX, int screenY, int pointer, int button)
  {
      float pointerX = InputTransform.getCursorToModelX(windowWidth, screenX);
      float pointerY = InputTransform.getCursorToModelY(windowHeight, screenY);
      for(int i = 0; i < balloons.size(); i++)
      {
          if(balloons.get(i).contains(pointerX, pointerY))
          {
              balloons.get(i).setSelected(true);
          }
      }
      return true;
   }

   @Override
   public boolean touchUp(int screenX, int screenY, int pointer, int button)
   {
       float pointerX = InputTransform.getCursorToModelX(windowWidth, screenX);
       float pointerY = InputTransform.getCursorToModelY(windowHeight, screenY);
       for(int i = 0; i < balloons.size(); i++)
       {
           if(balloons.get(i).contains(pointerX, pointerY) && balloons.get(i).getSelected())
           {
               balloons.get(i).execute();
           }
           balloons.get(i).setSelected(false);
       }
       return true;
    }

public class InputTransform
{
    private static int appWidth = 480;
    private static int appHeight = 320;

    public static float getCursorToModelX(int screenX, int cursorX) 
    {
        return (((float)cursorX) * appWidth) / ((float)screenX); 
    }

    public static float getCursorToModelY(int screenY, int cursorY) 
    {
        return ((float)(screenY - cursorY)) * appHeight / ((float)screenY) ; 
    }
}

Upvotes: 3

Madmenyo
Madmenyo

Reputation: 8584

You could add a tiny 1x1 pixel rectangle to your mouse and check if it intersects or contains other boxes. You do need to use boxes for all your objects you want to make clickable this way.

Upvotes: 0

Hoodrij
Hoodrij

Reputation: 1

You have Gdx.input.getX() and Gdx.input.getY(). The X and Y coordinates of the last touch. Just compare them with balloon frame.

Upvotes: 0

Related Questions