LibGDX中Tiled地图物体不显示(无报错)技术求助
问题分析与修复方案
嘿,我帮你梳理下代码里的核心问题——这就是为什么你的自定义ObjectCreater没法正常创建刚体,或者创建了也看不到的原因:
1. 最大的坑:ObjectCreater用了全新的对象实例,而非复用Screens里的资源
你在ObjectCreater的构造函数里做了这些操作:
screens=new Screens(); player=new Player(); game=new MyGdxGame();
这会生成完全独立的新对象,和你在Screens类里初始化的world、map、player没有半毛钱关系!比如:
- 新创建的
Screens实例压根没调用show()方法,它的map根本没加载,遍历图层的时候自然找不到任何对象 - 你用
player.world.createBody(grpund)创建刚体,这个player.world是新Player实例里的世界,不是Screens里那个你实际要用到的物理世界
修复方式:
把需要的资源通过构造函数传递给ObjectCreater,而不是自己新建:
// 重构ObjectCreater的构造函数 public class ObjectCreater { public static Body Groundbody; World world; TiledMap map; public ObjectCreater(World world, TiledMap map){ this.world = world; this.map = map; BodyDef groundDef = new BodyDef(); FixtureDef fixtureDef = new FixtureDef(); PolygonShape polygonShape = new PolygonShape(); for (MapObject object : map.getLayers().get(4).getObjects().getByType(RectangleMapObject.class)){ Rectangle rect = ((RectangleMapObject) object).getRectangle(); groundDef.type = BodyDef.BodyType.StaticBody; // 注意坐标转换要和你的渲染缩放保持一致 groundDef.position.set( (rect.getX() + rect.getWidth() / 2)/100f, (rect.getY() + rect.getHeight() / 2)/100f ); Groundbody = world.createBody(groundDef); polygonShape.setAsBox( (rect.getWidth()/2)/100f, (rect.getHeight()/2)/100f ); fixtureDef.shape = polygonShape; fixtureDef.filter.categoryBits = 16; Groundbody.createFixture(fixtureDef).setUserData("backw"); } polygonShape.dispose(); // 记得释放形状资源,避免内存泄漏 } }
然后在Screens的show()方法里初始化ObjectCreater时,把已有的world和map传进去:
// Screens类的show方法中 objectCreater = new ObjectCreater(world, map);
2. 没加Box2D调试渲染器,刚体创建了也看不到
Box2D的刚体默认是不可见的,你必须添加调试渲染器才能直观看到它们的存在。
修复方式:
在Screens类里添加调试渲染器,并在render()中渲染调试信息:
public class Screens implements Screen { // 新增Box2D调试渲染器 Box2DDebugRenderer debugRenderer; @Override public void show() { // ... 其他初始化代码 world = new World(new Vector2(0,-10), true); debugRenderer = new Box2DDebugRenderer(); objectCreater = new ObjectCreater(world, map); } @Override public void render(float delta) { movecam(); cam.update(); Gdx.gl.glClearColor(1, 1, 1, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); tiledMapRenderer.setView(cam); tiledMapRenderer.render(); // 渲染Box2D调试刚体 debugRenderer.render(world, cam.combined); } @Override public void dispose() { // 记得释放调试渲染器资源 debugRenderer.dispose(); // ... 其他资源(texture、map、world等)的释放 } }
3. Viewport与Camera未绑定,可能导致视口错位
你在Screens里初始化了viewport,但没把相机绑定到视口上,这可能导致相机的视口范围不正确,就算刚体在正确位置,你也看不到。
修复方式:
在show()里添加视口与相机的绑定:
@Override public void show() { cam = new OrthographicCamera(400/100f, 200/100f); viewport = new StretchViewport(400/100f, 900/100f); viewport.setCamera(cam); // 绑定相机到视口 cam.position.set(1,1,0); // ... 其他代码 }
额外的小建议
Screens里的game=new MyGdxGame();完全没必要,应该通过构造函数把MyGdxGame的实例传进来,而不是新建一个- 务必在
dispose()方法里释放所有资源(texture、map、world、tiledMapRenderer等),避免内存泄漏
按照这些修改后,你的刚体应该能正常创建,并且在调试模式下显示出来了。
内容的提问来源于stack exchange,提问作者Grinning Trout
相关产品推荐
相关产品推荐

