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

LibGDX如何获取世界坐标系下的鼠标坐标?解决Y轴翻转问题

问题根源

你之前手动翻转Y轴不生效的核心原因是取值错误:Toolkit.getDefaultToolkit().getScreenSize().height获取的是物理显示器的总高度,但Gdx.input.getY()返回的是游戏窗口渲染区域的相对坐标(原点在窗口左上角,Y轴向下),当窗口非全屏、存在标题栏、系统开启窗口缩放时,物理屏幕高度和窗口渲染区高度完全不匹配,计算结果自然错误。

另外注意:LibGDX自带的camera.unproject()、Viewport.unproject()方法本身已经内置了Y轴翻转逻辑,要求输入的就是Gdx.input返回的原生窗口坐标,不需要提前手动做Y值翻转,提前翻转再传入会导致两次翻转,结果完全颠倒。

正确实现方案

标准写法(推荐)

LibGDX项目中相机一般都会绑定Viewport做分辨率适配,直接调用视口的unproject方法即可自动处理Y轴翻转、视口黑边偏移等所有逻辑,不需要额外计算:

// 声明为类成员,避免每帧创建新对象
private final Vector3 tmpVec = new Vector3();
// 假设你已经初始化了绑定orthographicCamera的Viewport实例,比如fitViewport、extendViewport等
public Vector2 getWorldPositionFromScreen(float screenX, float screenY){
    tmpVec.set(screenX, screenY, 0);
    gameViewport.unproject(tmpVec);
    return new Vector2(tmpVec.x, tmpVec.y);
}

调用时直接传入输入的原生坐标即可:

// 调用示例
Vector2 worldPos = getWorldPositionFromScreen(Gdx.input.getX(), Gdx.input.getY());

无Viewport的裸相机写法

如果你没有使用Viewport,直接操作OrthographicCamera,不需要额外手动计算Y值翻转,直接传入原生输入坐标即可:

private final Vector3 tmpVec = new Vector3();
public Vector2 getWorldPositionFromScreen(float screenX, float screenY){
    tmpVec.set(screenX, screenY, 0);
    orthographicCamera.unproject(tmpVec);
    return new Vector2(tmpVec.x, tmpVec.y);
}

如果上述写法仍然存在Y翻转,检查相机初始化参数:如果你调用setToOrtho()时传入了yDown=true,会把世界坐标Y轴设置为向下,和屏幕坐标方向一致,此时需要把相机up参数改回默认Y向上:

// 正确的正交相机初始化(Y轴向上,和LibGDX默认渲染逻辑一致)
orthographicCamera.setToOrtho(false, worldWidth, worldHeight);
排查注意点
  • 窗口尺寸相关的取值全部从Gdx.graphics接口获取,不要用Java AWT、Swing相关的API,这类API不兼容LibGDX跨平台特性,取值也不符合游戏窗口的实际渲染范围。
  • 窗口大小改变时要同步更新相机/视口参数:桌面端拖拽窗口改变尺寸时,需要调用viewport.update(width, height)或者更新相机的viewport宽高后调用camera.update(),否则投影矩阵计算错误会导致坐标转换偏差。
  • 不要重复做Y轴翻转:unproject系列方法已经处理了屏幕坐标到世界坐标的Y轴方向转换,提前手动计算height - y再传入会导致方向错误。

坐标问题调试参考图

内容的提问来源于stack exchange,提问作者user19296869

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 12:24:24