2010-10-05 359 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碰撞。