2012-03-07 22 views
1

我一直在實現各種形式的簡單碰撞檢測,其結果各不相同。我有一個相當好的碰撞檢測工作版本,但有一些奇怪的行爲,我無法解決。碰撞檢測和保持對象上的動量

只是一個參考,我正在做一個簡單的乒乓球比賽,並試圖提煉碰撞。我得到的問題是球在頂部或底部碰撞槳時。在這些情況下,球懸停在槳的上方(或下方)並且不移動。我猜這是因爲我如何檢查碰撞以及我如何改變球的移動速度。

我想實現一種方法,我頂部/底部和左側/右側碰撞之間的區別,但這是工作體面的唯一方法:我猜

static void CheckCollision(PActor object1, PActor object2, PInput pinput) 
{ 
    if (CheckObjectCollision(object1, object2)) 
    { 
     AdjustMoveSpeed(object1, object2, pinput); 
    } 
} 



static bool CheckObjectCollision(PActor object1, PActor object2) 
{ 
    int object1LeftBound = object1.position.x; 
    int object1RightBound = object1.position.x + object1.actorTextureXSize; 
    int object1TopBound = object1.position.y; 
    int object1BottomBound = object1.position.y + object1.actorTextureYSize; 

    int object2LeftBound = object2.position.x; 
    int object2RightBound = object2.position.x + object1.actorTextureXSize; 
    int object2TopBound = object2.position.y; 
    int object2BottomBound = object2.position.y + object2.actorTextureYSize; 

    if (object1RightBound < object2LeftBound) 
     return false; 

    if (object1LeftBound > object2RightBound) 
     return false; 

    if (object1BottomBound < object2TopBound) 
     return false; 

    if (object1TopBound > object2BottomBound) 
     return false; 

    return true;   
} 

說的一些問題的根源我遇到的是功能AdjustMoveSpeed,那就是:

static void AdjustMoveSpeed(PActor object1, PActor object2, PInput pinput) 
{ 
    PVector prevMouseLocation = pinput.GetPrevMouseLocation(); 
    PVector currMouseLocation = pinput.GetCurrMouseLocation(); 

    int currentMoveSpeed; 
    int nextMoveSpeed; 

    if (typeid(object1) == typeid(PBall)) 
    { 

     object1.moveSpeed.x *= -1; 

     if (typeid(object2) == typeid(PPlayer)) 
     { 
      currentMoveSpeed = object1.moveSpeed.y; 
      nextMoveSpeed = prevMouseLocation.y - currMouseLocation.y; 

      object1.moveSpeed.y = (prevMouseLocation.y - currMouseLocation.y) * -1; 

     } 
     else 
     { 
      if (object1.moveSpeed.y > 0) 
       object1.moveSpeed.y *= -1; 
     } 
    } 
    else if (typeid(object2) == typeid(PBall)) 
    { 

     object2.moveSpeed.x *= -1; 

     if (typeid(object1) == typeid(PPlayer)) 
     { 
      currentMoveSpeed = object1.moveSpeed.y; 
      nextMoveSpeed = prevMouseLocation.y - currMouseLocation.y; 

      object2.moveSpeed.y = (prevMouseLocation.y - currMouseLocation.y) * -1; 
     } 
     else 
     { 
      if (object2.moveSpeed.y > 0) 
       object2.moveSpeed.y *= -1; 
     } 
    }  
} 

我試圖用AdjustMoveSpeed要做的,就是先檢查,看看哪個對象球,在此之後,通過乘以X移動速度 - 1逆轉其方向。在此之後,我檢查另一個對象是否爲播放器,如果是這樣,我將y移動速度設置爲前一個鼠標位置與當前鼠標位置之間的差異。這是爲了讓玩家選擇改變球的速度,或者增加旋轉。

我試過檢查對象之間的交集,這樣我可以得到一個特定的側面,其結果僅僅是在屏幕的中間飛行而無需實際擊球或者槳球。

如何正確檢查兩個正方形對象的碰撞檢測?

我該如何修復AdjustMoveSpeed,以便它在碰撞檢測中正常工作?

最後,我該如何保持其當前速度的球的勢頭比鼠標位置的命中前後差別較大?

我試圖採取比較currentMoveSpeed和nextMoveSpeed的絕對值,但隨後的球不修改y速度。這樣的事情:

if (abs(currentMoveSpeed) < abs(nextMoveSpeed) 
    object1.moveSpeed.y = (prevMouseLocation.y - currMouseLocation.y) * -1; 
else 
    object1.moveSpeed.y *= -1 

回答

6

傍非常簡單,而不是移動球每一幀,並檢查了槳式的碰撞,你其實可以解決當槳和球會碰撞方程 - 如果那個時候少於一幀,就會發生碰撞。

這完全消除了球的移動這麼快移動通過槳,困擾使用碰撞檢測的天真方法很多乒乓克隆問題的問題。

該解決方案被稱爲continuous collision detection - 見this answer以獲取更多信息。

+0

非常感謝你。 – RedShft 2012-03-07 20:33:27

2

如果球卡在槳而不是彈起它可能是因爲它不斷地改變方向來回。如果球正朝向槳,球應該反彈。

if (sgn(object1.moveSpeed.x) == sgn(object1.x - object2.x)) { 
    // Ball is already moving away from the paddle, don't bounce! 
} 
else { 
    // Ok to bounce! 
    object1.moveSpeed.x *= -1; 
} 
+0

謝謝你,這是正確的,只要來回改變方向。什麼是sgn(object1.moveSpeed.x)?我還沒有在D中遇到過。假設它有一個D函數。 – RedShft 2012-03-07 20:33:18

+0

我不知道D,但sgn是符號函數,它返回+1表示正數,-1表示負數。 – 2012-03-07 22:24:28