2012-03-07 68 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