LibGDX如何实现仅点击指定Rectangle矩形区域时打印文本
问题原因
原代码仅判断了「屏幕是否处于被触摸状态」,未校验触摸点坐标是否落在碰撞盒范围内,点击任意位置都会触发打印。另外LibGDX存在坐标系差异,直接使用原始触摸坐标判断会出现位置偏移:
- 输入模块返回的触摸坐标原点在屏幕左上角,y轴向下递增
- 矩形碰撞盒默认使用世界坐标系,原点在左下角,y轴向上递增
不做坐标转换直接比对,判断结果必然不准。另外Gdx.input.isTouched()在手指按住屏幕的每帧都会返回true,会导致按住时重复触发逻辑。
正确实现方式
核心逻辑是:检测到触摸事件时,先把屏幕触摸坐标转换成和碰撞盒一致的世界坐标,再调用Rectangle自带的contains()方法判断点是否落在矩形范围内即可。
未使用视口适配的最简实现
如果项目没有做复杂的屏幕适配,直接用屏幕尺寸渲染,直接在render()方法里加如下逻辑:
// 仅在触摸刚按下的瞬间触发判断,避免按住时重复执行 if (Gdx.input.justTouched()) { float touchX = Gdx.input.getX(); // 反转y轴对齐世界坐标系 float touchY = Gdx.graphics.getHeight() - Gdx.input.getY(); if (rectangle_hitbox.contains(touchX, touchY)) { System.out.println("Done"); } else { System.out.println("Missed"); } }
使用Viewport做屏幕适配的实现
如果用了LibGDX的Viewport组件做多分辨率适配,不要手动反转y轴,用视口自带的方法转坐标,避免不同分辨率下判断偏移:
// 先把这个变量声明为类成员,不要每帧new,避免频繁GC private final Vector3 touchPos = new Vector3(); @Override public void render() { // 其他原有渲染逻辑... if (Gdx.input.justTouched()) { touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0); // 将屏幕坐标转换为当前视口对应的世界坐标 viewport.unproject(touchPos); if (rectangle_hitbox.contains(touchPos.x, touchPos.y)) { System.out.println("Done"); } else { System.out.println("Missed"); } } }
注意事项
- 不要每帧新建Vector3这类临时对象,提为类成员复用可以减少GC卡顿
- 如果碰撞盒跟着敌人做过平移、缩放,要确保矩形的坐标值和渲染时的坐标实时同步,不然会出现碰撞盒和显示位置不匹配的问题
- 如果需要支持多点触控,不要用无参的
justTouched()/isTouched(),要传入对应手指的索引做判断
内容的提问来源于stack exchange,提问作者witsel
相关产品推荐
相关产品推荐

