2010-10-05 115 views
0

我在编写一个小2D游戏时遇到了一些问题。我目前正在研究一个函数,我想查找玩家角色是否与一个块碰撞,以及他碰撞的块的哪一侧。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; 
    } 
} 

难道我这里有一些逻辑错误?或者我只是在我的代码中写错了什么?

高于碰撞的作品,但它不应该认识到它应该时横向碰撞,有时它应该不应该。

这款游戏是SuperMario克隆版,所以它是一款双面打印2D平台游戏。

+1

如果你能提供真实的代码,你的问题会更容易回答。请做。编辑:我认为PLAYER_BOX_RIGHT_SIDE从玩家的x坐标(玩家x +精灵宽度)正确偏移? – 2010-10-05 16:38:35

+0

是的所有抵消都妥善处理。 – EClaesson 2010-10-05 16:48:52

回答

2

我猜这个问题是方向。

你真正想要做的是先考虑“玩家”的方向,然后做你的支票。

如果你不知道玩家的移动方向,你可以得到一个虚假命中的数字,这取决于你的精灵如何“快速”移动。

例如,如果你有运动方向(上下左,右),那么你的代码可能是这样的:

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

    etc 

} 
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; 

} 

这种做法将会给你很多更好的结果,如果您的播放器不断移动非常快,因为你基本上计算,如果玩家将碰撞,而不是如果他们DID碰撞。