You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 23:24:23