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

白昼怎懂夜的黑 提交于 2019-11-26 23:10:55

问题


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);
}

回答1:


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) ; 
    }
}



回答2:


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

Vector3 touchPoint=new Vector3();

void update()
{
  if(Gdx.input.justTouched())
   {
    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
     }
    }
   }



回答3:


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 !




回答4:


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




回答5:


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.




回答6:


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
            }
        }
    }
}



回答7:


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;
    }
}


来源:https://stackoverflow.com/questions/24501268/how-do-i-detect-if-a-sprite-was-touched-in-java-libgdx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!