点击检测和按钮图形之间的偏移量libgdx
我有一个libgdx应用程序,其中包含类Button
。 Button
的构造函数需要三个参数:图形,位置和游戏的文件名(后者用于各种回调)。点击检测和按钮图形之间的偏移量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元素的文档片断。 batch
是SpriteBatch
由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指底部中心。
你有不一致处在你的位置变换:
- 你
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(注意它可能是小项目中的矫枉过正)。
添加'height/2'是解决可点击区域在没有它的情况下垂直错位的一种解决方法。我没有找到原因,但它的工作原理与解决方法一致。手头的问题是水平排列。 +1用于关于资源处理的优化指针,因为这是我的待办事项列表中的下一个。 – Jarmund
你看过你的相机/视口设置吗?当我忘记在ApplicationListener中重写'resize()'方法时,我曾经遇到这种问题。 –
你接受了我的回答。这确实是相机问题吗? –
你如何画你的按钮?在'getClickArea()'中,'pos'看起来像是实体的中心,而它通常是左下角。 –
@MaciejDziuban根据您的要求添加。 – Jarmund
'新的纹理()'不应该出现在你的渲染循环中的任何地方。除了不必要地加载完全相同纹理的许多副本之外,您在每个帧上都会泄漏多个纹理。 – Tenfour04