如何在Java libGDX中检测精灵是否被触摸?

7
在过去的几天里,我一直在将我的游戏(Apopalypse)移植到Android移动平台。我在谷歌上快速搜索了精灵触摸检测,但没有找到有用的信息。每个气球被触摸后都会破裂,我只需要检测是否被触摸。
这是我的气球生成代码:
渲染(x、y、宽度和高度是随机的):
public void render() {
    y += 2;
    balloon.setX(x);
    balloon.setY(y);
    balloon.setSize(width, height);
    batch.begin();
    balloon.draw(batch);
    batch.end();
}

在主游戏类中生成:

addBalloon(new Balloon());

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

你尝试过什么? 你读过wiki了吗?(https://github.com/libgdx/libgdx/wiki -- 检查输入处理部分。) - P.T.
7个回答

8
在你的类中,有一个名为render的方法,你可以使用以下代码:
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
     }
    }
   }

3

这是我完成它的方式,但根据您使用的场景和可触摸的元素,可能有稍微更优化的方法:

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

代码中的windowWidth和WindowHeight未定义。 - ejectamenta
1
有效的声明,如果我没记错的话,它们是直接从Gdx.graphics.getWidth()和Gdx.graphics.getHeight()初始化的。 - EpicPandaForce
对我来说可以工作,但没有内置处理这个的东西真是太疯狂了! - rococo

2
我写了一个小类用于我的游戏,检测Sprite是否被触摸到。
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;
 }

这是我如何使用它的方法

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

使用同样的逻辑,您可以检测精灵释放,并且您可以在精灵被触摸时自定义效果大小等更多内容...

希望这对您有所帮助!


0

这是我在精灵类中使用的代码。我将点击的向量传递给它:camera.unproject(new Vector3().set(x,y,0));。如果点击在精灵区域内,则返回 true。

    /***
     * 
     * @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;
    }
}

0

我有一个简单的解决方案

首先创建一个小矩形,大小为1像素乘1像素

Rectangle rect;

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

然后创建一个名为

touching_checking();

的方法,在这个方法中我们将做三件事情

第一步检查屏幕是否被触摸

第二步将矩形放在你触摸屏幕的位置

最后检查你的矩形是否与精灵矩形重叠。

private void touching_checking() { if (Gdx.input.isTouched()) { rect.setPosition(Gdx.input.getX(), Gdx.input.getY()); if (rect.overlaps(back.getBoundingRectangle())) { //在这里执行你想要的操作 } } } 我有一个名为levels的精灵数组,我检查我按下了哪一个,就像这样

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

简单而不失优雅的解决方案。感谢提供代码示例。在测试.overlaps()之前,可能需要转置触摸坐标和绘制坐标(或反之亦然)。 - rockhammer

0
你有 Gdx.input.getX()Gdx.input.getY()。它们是最后一次触摸的 X 和 Y 坐标。只需将它们与气球框架进行比较即可。

0
你可以添加一个1x1像素的小矩形到你的鼠标上,并检查它是否与其他框相交或包含。你需要对想要用这种方式使其可点击的所有对象使用框。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接