[英]Collision Detection Tmx Maps using libgdx (java)
因此,我尝试在游戏中实现碰撞检测,并且tmx文件中有一个名为Collision的图层。 LIBGDX现场教程并未涵盖与对象层的交互,因此一开始就很难弄清楚如何渲染地图。 这就是我渲染屏幕的方式,我想学习如何获取碰撞层,然后让我的精灵与之交互。
@Override
public void render(float delta) {
translateCamera();
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
camera.update();
renderer.setView(camera);
renderer.render(bgLayers);
// renderer.render();
batch.begin();
batch.draw(playerDirect, Gdx.graphics.getWidth() / 2,
Gdx.graphics.getHeight() / 2);
batch.end();
renderer.render(fgLayers);
}
有一种使用对象层的方法。 不要放弃希望!
与使用图块属性相比,此方法的一个主要优点是可以轻松生成更少,更大的实体以提高Box2d的效率。 另外,更好的是,这些身体可以是您想要的任何形状! 现在,我在游戏中的采样级别不再是数十个ChainShape
的ChainShape
而是只有三个基于有趣形状(基于有机外观)的ChainShape
。
前几天,我在网络丛林深处进行了认真的狩猎之后,在GameDev上回答了相同的问题 。 我发现的教程对我来说并不十分有效,因此稍后进行了一些编辑:
public class MapBodyBuilder {
// The pixels per tile. If your tiles are 16x16, this is set to 16f
private static float ppt = 0;
public static Array<Body> buildShapes(Map map, float pixels, World world) {
ppt = pixels;
MapObjects objects = map.getLayers().get("Obstacles").getObjects();
Array<Body> bodies = new Array<Body>();
for(MapObject object : objects) {
if (object instanceof TextureMapObject) {
continue;
}
Shape shape;
if (object instanceof RectangleMapObject) {
shape = getRectangle((RectangleMapObject)object);
}
else if (object instanceof PolygonMapObject) {
shape = getPolygon((PolygonMapObject)object);
}
else if (object instanceof PolylineMapObject) {
shape = getPolyline((PolylineMapObject)object);
}
else if (object instanceof CircleMapObject) {
shape = getCircle((CircleMapObject)object);
}
else {
continue;
}
BodyDef bd = new BodyDef();
bd.type = BodyType.StaticBody;
Body body = world.createBody(bd);
body.createFixture(shape, 1);
bodies.add(body);
shape.dispose();
}
return bodies;
}
private static PolygonShape getRectangle(RectangleMapObject rectangleObject) {
Rectangle rectangle = rectangleObject.getRectangle();
PolygonShape polygon = new PolygonShape();
Vector2 size = new Vector2((rectangle.x + rectangle.width * 0.5f) / ppt,
(rectangle.y + rectangle.height * 0.5f ) / ppt);
polygon.setAsBox(rectangle.width * 0.5f / ppt,
rectangle.height * 0.5f / ppt,
size,
0.0f);
return polygon;
}
private static CircleShape getCircle(CircleMapObject circleObject) {
Circle circle = circleObject.getCircle();
CircleShape circleShape = new CircleShape();
circleShape.setRadius(circle.radius / ppt);
circleShape.setPosition(new Vector2(circle.x / ppt, circle.y / ppt));
return circleShape;
}
private static PolygonShape getPolygon(PolygonMapObject polygonObject) {
PolygonShape polygon = new PolygonShape();
float[] vertices = polygonObject.getPolygon().getTransformedVertices();
float[] worldVertices = new float[vertices.length];
for (int i = 0; i < vertices.length; ++i) {
worldVertices[i] = vertices[i] / ppt;
}
polygon.set(worldVertices);
return polygon;
}
private static ChainShape getPolyline(PolylineMapObject polylineObject) {
float[] vertices = polylineObject.getPolyline().getTransformedVertices();
Vector2[] worldVertices = new Vector2[vertices.length / 2];
for (int i = 0; i < vertices.length / 2; ++i) {
worldVertices[i] = new Vector2();
worldVertices[i].x = vertices[i * 2] / ppt;
worldVertices[i].y = vertices[i * 2 + 1] / ppt;
}
ChainShape chain = new ChainShape();
chain.createChain(worldVertices);
return chain;
}
}
假设您已经设置好东西,以使Box2d World
中的瓷砖大小对应于1平方米(如果需要,则为1平方单位),则生成的静态Body
正是您在Tiled中绘制它们的位置。 看到它运行起来真是令人满足,相信你。
我建议将阻止的属性添加到实际的图块本身-您可以通过实际图块集上的Tiled编辑器添加图块属性。 您可以在图块上检索其属性。 我将引用文档:
TiledMap包含一个或多个TiledMapTileSet实例。 一个图块集包含许多TiledMapTile实例。 磁贴有多种实现,例如静态磁贴,动画磁贴等。您还可以为特殊的应用创建自己的实现
图块层中的单元引用这些图块。 一层内的像元可以引用多个图块集的图块。 但是,建议每层坚持使用单个图块集以减少纹理切换。
具体来说,在磁贴集中的磁贴上调用getProperty。 这将检索属性-然后您可以与自定义属性进行比较,并且可以告诉您是否阻止了特定的图块-然后您可以继续执行自己的碰撞逻辑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.