2

我正在制作一个类似于马里奥的游戏,我已经得到了由数组和图像生成的这张地图。但我的问题是我不知道如何为所有瓷砖制作一个碰撞箱系统。我试图根据您在地图上的位置建立基于位置的碰撞系统

像这样

if(xpos > 10*mapX && xpos < 14 * mapX){
    ypos -= 1;
}

但我不想对每一堵墙或每一个洞都这样做。那么有没有办法检查角色的前面,下面和上面是否有一个碰撞箱,如果有你不能移动那个方向或跌倒?

谢谢

4

2 回答 2

1

如果它是一个简单的 2D 游戏,我建议将地图划分为方形图块。您可以将地图作为二维数组存储在内存中,并在每一帧期间检查与玩家相邻的图块。当然他在移动过程中最多可以占据4个格子,但它让你最多只能检查12个位置,这很容易做到。

使用图像位置和尺寸可以轻松完成进一步的碰撞检查。

请记住,无需检查静态对象(环境)是否与某物发生碰撞,您只需检查自上一帧以来已移动的对象,即玩家和精灵。

编辑:

假设您有以下 map 部分(变量map):

...
.pe
ooo

在哪里

. = nothing
p = player
o = floor
e = enemy

您还有一对(x, y)代表玩家的瓷砖索引(不是确切位置)。在这种情况下,您必须执行以下操作:

if ("o".equals(map[y + 1, x + 1]))
//floor is under
if ("e".equals(map[y, x + 1]))
//enemy is on the right
if ("o".equals(map[y - 1, x]))
//floor is above us

如果满足这些条件中的任何一个,则必须检查图像位置并处理碰撞。

于 2013-08-19T12:20:34.313 回答
0

注意:最后一个帖子发出后点击提交方式...

正如 Mateusz 所说,2D 数组最适合这种类型的游戏:

例如使用字符:

 0123456789012
0           ==
1        * ===
2===== =======

所以在这种情况下 tileMap[8][1] == '*'。您可能最好使用枚举而不是字符,例如 Tile.SPRING 用于 Sonic 风格的弹簧板。

如果您的地图由常规大小的图块组成,您可以说:

int xInFrontOfPlayer = playerX + PLAYER_WIDTH;
int xBehindPlayer = playerX - PLAYER_WIDTH;

Tile tileInFrontOfPlayer = getTileAtWorldCoord(xInFrontOfPlayer, playerY);
Tile tileBehindPlayer = getTileAtWorldCoord(xBehindPlayer, playerY);

...

public Tile getTileAtWorldCoord(int worldX, worldY) {
    return tileMap[worldX / TILE_WIDTH][worldY / TILE_HEIGHT];
}

其中 TILE_WIDTH 和 TILE_HEIGHT 是图块的尺寸(以像素为单位)。然后对 yAbovePlayer 和 yBelowPlayer 使用类似的数学运算。

然后,您的游戏循环中可能会有一些逻辑:

if user is pressing the "go right" key:
      if the tile to the right is Tile.SPACE:
            move player right
      else if the tile to the right is Tile.WALL:
            don't do anything

if the tile below is Tile.SPACE:
    fall
于 2013-08-19T13:08:23.830 回答