LibGDX camera.project()异常:Box2D物体上方Label位置偏移
Box2D物体坐标转屏幕坐标显示Label位置偏移问题
我用Box2D管理游戏世界,想在物体(body)上方显示文本,打算用Label实现。但物体在游戏世界中,Label在Stage(UI层),所以尝试用camera.project()方法把世界坐标转成屏幕坐标。不过Label显示位置有偏移,相对目标位置向左下方偏,调整窗口大小后位置还是不对。另外我用相同方式调用camera.unproject()一切正常,搞不懂反向转换没问题,正向就出问题。
代码如下:
this.camera = new OrthographicCamera(ScreenManager.WIDTH * SCALE, ScreenManager.HEIGHT * SCALE); this.viewport = new FitViewport(ScreenManager.WIDTH, ScreenManager.HEIGHT); this.stage = new Stage(viewport, batch); this.world = new World(Vector2.Zero, true); // ... Vector3 worldPosition = new Vector3(x, y, 0); Vector3 screenPosition = camera.project(worldPosition, viewport.getScreenX(), viewport.getScreenY(), viewport.getScreenWidth(), viewport.getScreenHeight()); label.setPosition(screenPosition.x, screenPosition.y);
resize方法:
@Override public void resize(int width, int height) { viewport.update(width, height, true); }
我已经在render方法里调用了Stage的act()和draw()方法,请问哪里出错了?
解决方案
- 修正坐标转换的视口参数使用
你当前直接用camera.project()传入视口的屏幕参数,但你的Stage已经绑定了FitViewport,而相机的初始化尺寸是ScreenManager.WIDTH * SCALE,这会导致坐标转换时的缩放比例不匹配。正确的做法是直接使用视口的相机来做投影,或者确保投影时的参数和视口的实际变换一致。
替换坐标转换代码为:
Vector3 worldPosition = new Vector3(x, y, 0); // 直接使用stage的视口相机进行投影,无需手动传入视口参数 viewport.getCamera().project(worldPosition); // 或者如果坚持用自己的camera,要确保和视口同步 // camera.project(worldPosition, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); label.setPosition(worldPosition.x, worldPosition.y);
- 调整Label的锚点(Alignment)
Label默认的锚点是左上角(0,0),而你转换后的坐标是物体的世界坐标点,直接设置位置会导致Label的左上角对齐物体位置,看起来就会向左下方偏移。需要把Label的锚点设为中心或者底部中心,让Label的对应位置对齐物体上方:
// 初始化Label时设置对齐方式 Label.LabelStyle style = new Label.LabelStyle(font, Color.WHITE); label = new Label("文本内容", style); // 设置锚点为底部中心,这样Label的底部中心会对齐转换后的坐标 label.setAlignment(Align.center); label.setPosition(screenPosition.x - label.getWidth()/2, screenPosition.y); // 或者使用setCenter方法更方便 label.setCenter(screenPosition.x, screenPosition.y);
- 确保相机和视口同步
在resize方法中,除了更新视口,还要确保相机的位置和视口保持一致,或者直接使用视口的相机来管理游戏世界:
@Override public void resize(int width, int height) { viewport.update(width, height, true); // 如果使用自定义camera,需要同步视口的投影矩阵 camera.setToOrtho(false, viewport.getWorldWidth(), viewport.getWorldHeight()); camera.update(); }
另外,unproject正常是因为反向转换时,屏幕坐标的原点和Stage的坐标系统匹配,但正向转换时因为相机缩放和Label锚点的双重问题导致偏移。
内容的提问来源于stack exchange,提问作者Adixe
相关产品推荐
相关产品推荐

