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

问题描述:

我有一个libgdx应用程序,其中包含类ButtonButton的构造函数需要三个参数:图形,位置和游戏的文件名(后者用于各种回调)。点击检测和按钮图形之间的偏移量libgdx

该按钮根据提供的图形缩放自身,从而根据图形的属性设置其宽度和高度。

主类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一个相关的片段。它监听输入并传递事件。请注意,垂直点击位置被从屏幕的垂直大小减去,作为垂直0是相反在InputHandler:

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

ClickTracker(如tracker在上述代码段中引用),即不将所述类点击和clickables之间实际的比较:

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像素处。

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


编辑:

由于马切伊Dziuban要求,这里是绘制的UI元素的文档片断。 batchSpriteBatch由libgdx提供:

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指底部中心。

+0

你如何画你的按钮?在'getClickArea()'中,'pos'看起来像是实体的中心,而它通常是左下角。 –

+0

@MaciejDziuban根据您的要求添加。 – Jarmund

+0

'新的纹理()'不应该出现在你的渲染循环中的任何地方。除了不必要地加载完全相同纹理的许多副本之外,您在每个帧上都会泄漏多个纹理。 – Tenfour04

你有不一致处在你的位置变换:

  • 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(注意它可能是小项目中的矫枉过正)。

+0

添加'height/2'是解决可点击区域在没有它的情况下垂直错位的一种解决方法。我没有找到原因,但它的工作原理与解决方法一致。手头的问题是水平排列。 +1用于关于资源处理的优化指针,因为这是我的待办事项列表中的下一个。 – Jarmund

+1

你看过你的相机/视口设置吗?当我忘记在ApplicationListener中重写'resize()'方法时,我曾经遇到这种问题。 –

+0

你接受了我的回答。这确实是相机问题吗? –