LibGDX中正交相机跟随ShapeRenderer绘制对象的实现问题
LibGDX中正交相机跟随ShapeRenderer绘制对象的实现问题
完全可以不用Sprite让正交相机跟随ShapeRenderer绘制的对象,你的代码里其实就差几个关键小步骤没做,导致相机看起来没反应,我帮你捋捋问题和修改方案:
先说说你代码里的核心问题
- ShapeRenderer没关联相机的投影矩阵:你更新了相机,但ShapeRenderer默认还是用屏幕原生坐标系绘制,根本没理会相机的变化,所以不管相机怎么动,画面看起来都没变化。
- 相机初始化没设置视口大小:OrthographicCamera默认的视口是1x1的极小区域,你没设置和屏幕匹配的视口,坐标缩放会乱套,相机移动也看不出效果。
lookAt方法用错场景:lookAt是3D相机用来调整朝向的,2D正交相机只需要平移位置就行,用它反而可能搞乱相机的姿态。
具体修改步骤
第一步:正确初始化相机
在create()方法里,给相机设置合适的视口大小,并且让相机初始对准玩家的中心:
@Override public void create() { sr = new ShapeRenderer(); g = new Ground(0, 20,Gdx.graphics.getWidth(), 5, new Color(Color.WHITE)); square = new Player(20, 25, 50,50, new Color(Color.PURPLE), 3); // 设置相机视口为屏幕大小,也可以用虚拟分辨率比如800x480适配不同屏幕 camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); // 让相机初始位置对准玩家的中心(玩家的x+宽/2,y+高/2) camera.position.set(square.getX() + square.getWidth()/2, square.getY() + square.getHeight()/2, 0); camera.update(); }
第二步:让ShapeRenderer使用相机的投影矩阵
在每次绘制ShapeRenderer之前,一定要把相机的combined矩阵传给它,这样绘制的内容才会跟着相机移动:
@Override public void render() { ScreenUtils.clear(0.15f, 0.15f, 0.2f, 1f); float dt = Gdx.graphics.getDeltaTime(); square.moveplayer(g, dt); // 先处理相机跟随逻辑:让相机中心始终对准玩家中心 camera.position.x = square.getX() + square.getWidth()/2; camera.position.y = square.getY() + square.getHeight()/2; // 如果你需要手动移动相机,把handleInput放在这里,比如手动平移后再更新相机 handleInput(); camera.update(); // 关键:把相机的投影矩阵传给ShapeRenderer sr.setProjectionMatrix(camera.combined); // 尽量把所有绘制放在同一个begin/end里,减少性能开销 sr.begin(ShapeRenderer.ShapeType.Filled); g.draw(sr); square.draw(sr); sr.end(); }
第三步:调整手动相机控制的逻辑(可选)
你的handleInput里是手动平移相机,如果要同时支持手动移动和自动跟随,可能需要调整逻辑;如果只是自动跟随,其实可以去掉这段;如果保留,注意用deltaTime让移动速度和帧率无关:
private void handleInput() { float moveSpeed = 100 * Gdx.graphics.getDeltaTime(); if (Gdx.input.isKeyPressed(Input.Keys.DPAD_LEFT)) { camera.translate(-moveSpeed, 0, 0); } if (Gdx.input.isKeyPressed(Input.Keys.DPAD_RIGHT)) { camera.translate(moveSpeed, 0, 0); } }
最后补充几个注意点
- 记得在
dispose()方法里销毁ShapeRenderer资源,避免内存泄漏:
@Override public void dispose() { sr.dispose(); }
- 如果需要适配不同屏幕,后期可以用
Viewport来设置虚拟分辨率,比直接设置相机视口更灵活,不过先把基础的相机跟随弄好再说。
这样修改后,相机就能正确跟随你用ShapeRenderer绘制的玩家矩形了,试试看!
备注:内容来源于stack exchange,提问作者Macbethy
相关产品推荐
相关产品推荐

