0

在我正在编写的一个小型 2D 游戏中,我遇到了一些碰撞问题。我目前正在研究一个函数,我想查找玩家角色是否与块碰撞,以及他与块的哪一侧发生碰撞。

目前我有类似(伪代码):

if(PLAYER_BOX IS WITHIN THE BLOCKS Y_RANGE)
{
    if(PLAYER_BOX_RIGHT_SIDE >= BLOCK_LEFT_SIDE && PLAYER_BOX_RIGHT_SIDE <= BLOCK_RIGHT_SIDE)
    {
        return LEFT;
    }
    else if(PLAYER_LEFT_SIDE <= BLOCK_RIGHT_SIDE && PLAYER_LEFT_SIDE >= BLOCK_LEFT_SIDE)
    {
        return RIGHT;
    }
}
else if(PLAYER_BOX IS WITHIN BLOCK X_RANGE)
{
    if(PLAYER_BOTTOM_SIDE >= BLOCK_TOP_SIDE && PLAYER_BOTTOM_SIDE <= BLOCK_BOTTOM_SIDE)
    {
        return ABOVE;
    }
    else if(PLAYER_TOP_SIDE <= BLOCK_BOTTOM_SIDE && PLAYER_TOP_SIDE >= BLOCK_TOP_SIDE)
    {
        return BELOW;
    }
 }

我这里有一些逻辑错误吗?还是我只是在我的代码中写错了什么?

ABOVE 碰撞有效,但它不应该识别侧面碰撞,有时它不应该识别侧面碰撞。

该游戏是 SuperMario 的克隆版,因此它是一款横向卷轴 2D 平台游戏。

4

2 回答 2

2

我猜问题是方向。

您真正想要做的是首先考虑“玩家”方向,然后进行检查。

如果您不知道玩家移动的方向,您可能会根据精灵移动的“速度”获得错误命中数。

例如,如果您有移动方向(从左到右),那么您的代码可能如下所示:

select movedir
(
   case up:
     //check if hitting bottom of box
     break;
   case down:
     //check if hitting top of box

    etc

}
于 2010-10-05T16:43:35.173 回答
0

您可能需要考虑使用移动增量来修改您的计算。

像这样的东西(也是伪的):


// assuming player graphics are centered
player_right = player.x + player.width / 2;
player_left = player.x - player.width / 2;

player_top = player.y - player.height / 2;
player_bottom = player.y + player.height / 2;

// assuming block graphics are centered as well
block_right = box.x + box.width / 2;
...

// determine initial orientation
if (player_right  block_right) orientationX = 'right';

if (player_top  block_top) orientationY = 'top';

// calculate movement delta
delta.x = player.x * force.x - player.x;
delta.y = player.y * force.y - player.y;

// define a rect containing where your player WAS before moving, and where he WILL BE after moving
movementRect = new Rect(player_left, player_top, delta.x + player.width / 2, delta.y + player.height / 2);

// make sure you rect is using all positive values
normalize(movementRect);

if (movementRect.contains(new Point(block_top, block_left)) || movementRect.contains(new Point(block_right, block_bottom))) {

    // there was a collision, move the player back to the point of collision
    if (orientationX == 'left') player.x = block_right - player.width / 2;
    else if (orientationX == 'right') player.x = block_left + player.width / 2;

    if (orientationY == 'top') player.y = block_top - player.height / 2;
    else if (orientationY == 'bottom') player.y = block_bottom + player.height / 2;

    // you could also do some calculation here to see exactly how far the movementRect goes past the given block, and then use that to apply restitution (bounce back)

} else {

    // no collision, move the player
    player.x += delta.x;
    player.y += delta.y;

}

如果您的玩家移动得非常快,这种方法将为您提供更好的结果,因为您实际上是在计算玩家是否会发生碰撞,而不是他们是否会发生碰撞。

于 2010-10-07T16:01:59.557 回答