libgdx中点击检测和按钮图形之间的偏移

时间:2016-08-03 09:44:21

标签: java graphics libgdx controls

我有一个包含类Button的libgdx应用程序。 Button的构造函数有三个参数:图形,位置和游戏的文件名(后者用于各种类型的回调)。

按钮根据提供的图形进行缩放,从而根据图形的属性设置宽度和高度。

检测到点击时,主要类Game会将点击的坐标与按钮的坐标以及宽度和高度进行比较。

现在,主要问题是按钮和点击坐标之间有一点水平偏移,因此效果是图形显示可点击区域右侧的几个像素。我不能为我的生活弄清楚这种差异的根源,所以我非常欣赏一些新鲜的眼睛,看看我在哪里出错了。

可点击区域的按钮,构造函数和轮询方法。

public Rectangle getClickArea() {
    return new Rectangle(pos.x - (img.getWidth() / 2), pos.y + (img.getHeight() / 2), w, h);
}

public Button(String assetfile, int x, int y, Game game) {
    this.game = game;
    img = new Pixmap(new FileHandle(assetfile));
    pos = new Vector2(x, y);
    this.w = img.getWidth();
    this.h = img.getHeight();
}

来自InputHandler的相关代码段。它侦听输入并传递事件。请注意,垂直点击位置是从屏幕的垂直尺寸中减去的,因为在InputHandler中垂直0是相反的:

public boolean touchDown(int screenX, int screenY, int pointer, int button) {
    tracker.click(screenX, Settings.windowSize_Y - screenY);
    return false;
}

ClickTracker(在上面的代码段中引用为tracker,这是在点击次数和点击次数之间进行实际比较的类:

public void click(int x, int y) {
    Vector2 clickPos = new Vector2(x, y);
    for (Tickable c : world.getPaintables())
    {
        if (!(c instanceof Unit))
            continue;

         if (((Clickable)c).getClickArea().contains(clickPos)) {
             System.out.println("Clicked on unit");
         }


    }
    for (Clickable c : clickables)
    {
        if (c.getClickArea().contains(clickPos)) {
            c.clicked(x, y);
        }
    }

简而言之:垂直对齐按预期工作,但水平稍微偏离。按钮图形可能出现在可点击区域右侧大约10-20像素处。

如果需要,我很乐意发布更多信息或代码,但我相信我已经涵盖了相关部分。

修改

正如Maciej Dziuban所要求的那样,这里是剪辑的UI元素。 batch是由libgdx提供的SpriteBatch

    for (Paintable p : ui) {
        batch.draw(new Texture(p.getImg()), p.getImgPos().x, p.getImgPos().y);
    }

getImgPos()是由所有可绘制项实现的接口方法:

public Vector2 getImgPos() {
    return new Vector2(pos.x - (getImg().getWidth() / 2), pos.y);
}

值得注意的是,从X pos中减去一半的水平图像尺寸,因为X pos指的是底部中心。

1 个答案:

答案 0 :(得分:1)

您的职位转换不一致:

  • clickArea的角落pos[-width/2, height/2]向量翻译。
  • 您的drawArea角落由pos
  • 翻译[-width/2, 0]

它们显然应该相同,因此如果您希望pos代表实体的底部中心(正如您明确说明的那样),则必须将getClickArea()方法更改为,所以它匹配getImgPos()

  public Rectangle getClickArea() {
      return new Rectangle(pos.x - (img.getWidth() / 2), pos.y, w, h);
  }

旁注:正如Tenfour04注意到的那样,每帧都会创建新的纹理,这是巨大的内存泄漏。您应该将它作为在构造函数中初始化的字段,或者甚至是静态变量,因为某些按钮共享纹理。别忘了给资源打dispose()。对于更强大的资产管理,请查看this article(请注意,在小型项目中可能会出现过度杀伤)。