我在写一个小型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平台游戏。
答案 0 :(得分:2)
我猜这个问题是方向。
你真正想做的是首先考虑“玩家”的方向,然后进行检查。
如果你不知道玩家的移动方向,你可能会得到一个虚假命中的数字,具体取决于你的精灵移动的速度。
例如,如果您有移动方向(向上向下),那么您的代码可能如下所示:
select movedir
(
case up:
//check if hitting bottom of box
break;
case down:
//check if hitting top of box
etc
}
答案 1 :(得分: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;
}
如果您的玩家移动得非常快,这种方法会给你带来更好的效果,因为你实际上是在计算玩家是否会碰撞,而不是他们发生碰撞。