【发布时间】:2013-01-06 00:51:15
【问题描述】:
我正在开发一款使用平铺地图的平台游戏,我不知道这是否是个好主意!
我已经制作了一个简洁的瓷砖地图编辑器,其中包含用于设置生成点等的工具,但现在我希望能够在编辑地图后测试玩游戏并以备将来使用,我当然需要集成物理,我'已经完成了 LibGDX 附带的 Box2D!
我正在创建一种方法来从瓦片地图创建碰撞地图,如果瓦片是否可碰撞,该地图具有数据!
所以我想出了这个好主意:
循环遍历地图,如果我们找到一个碰撞的瓦片循环遍历它的相邻瓦片并查看它们是否也在碰撞,并且这样做直到当我们为碰撞矩形设置宽度和高度时找到非碰撞瓦片
在我们得到一堆矩形之后,我按从最大的正方形到最小的顺序对它们进行排序,这样我们就得到了最大的部分,然后我将矩形添加到最终列表中,并检查最终矩形是否与当前主体重叠,所以我不t有重叠的身体
但你知道,代码能说出 1000 多个单词,对吧?
public void createBody() {
List<Rectangle> allRects = new ArrayList<Rectangle>();
for(int x = 0; x < info.getWidth(); x++) {
for(int y = 0; y < info.getHeight(); y++) {
if(tiles[x][y].getInfo().isColliding()) {
int width = 1;
int height = 1;
//loop through neighbors horizontally
for(int i = 0; i < info.getWidth() - x; i++) {
if(!tiles[x + i][y].getInfo().isColliding()) {
//if tile is not clipped, we set width to i which is current x offset
width = i;
break;
}
}
//only if width is bigger than zero can the rect have any tiels..
if(width > 0) {
boolean breakingBad = false;
//loop through neighbors horizontally
for(int j = 0; j < info.getHeight() - y; j++) {
//loop though neigbors vertizally
for(int i = 0; i < width; i++) {
//check if tile is not colliding
if(!tiles[x + i][y + j].getInfo().isColliding()) {
//and if so, we set height to j which is current y offset
height = j;
//breaking bad aka leaving both loops
breakingBad = true;
break;
}
}
if(breakingBad) {
break;
}
}
}
if(width * height > 0)
allRects.add(new Rectangle(x, y, width, height));
}
}
}
Collections.sort(allRects, new Comparator<Rectangle>() {
@Override
public int compare(Rectangle o1, Rectangle o2) {
Integer o1Square = o1.width * o1.height;
Integer o2Square = o2.width * o2.height;
return o2Square.compareTo(o1Square);
}
});
List<Rectangle> finalRects = new ArrayList<Rectangle>();
mainloop:
for(Rectangle rect: allRects) {
for(Rectangle finalRect: finalRects) {
if(finalRect.contains(rect)) {
continue mainloop;
}
}
finalRects.add(rect);
}
for(Rectangle rect: finalRects) {
PolygonShape polyShape = new PolygonShape();
polyShape.setAsBox((float)rect.getWidth() / 2, (float)rect.getHeight() / 2, Vector2.tmp.set((float)rect.getCenterX(), (float)rect.getCenterY()), 0f);
mapBody.createFixture(polyShape, 1);
polyShape.dispose();
}
}
然而,这个门槛似乎相当低效,因为由于某些原因,它仍然会创建比可能的更小的固定装置,例如在右上角
它还在中心矩形的角落创建了单个灯具,我不知道为什么!
整个想法都是低效的,我应该使用其他方法还是手动创建碰撞贴图,或者最好的想法是什么?
最初每个瓷砖都是自己的固定装置,这会在它们的边缘造成奇怪的错误,正如预期的那样
【问题讨论】:
-
当我们谈论效率低下时,在“compareTo”方法中,您执行了大量的自动装箱。 'Rectangle.width' 是 int 还是 Integer ?
-
我尝试了您的比较方法,结果发现它比仅使用整数的类似比较贵 2 倍。
标签: java box2d libgdx tiles game-physics