我一直在实施各种形式的简单碰撞检测,结果各不相同。我有一个相当不错的碰撞检测工作版本,但有些奇怪的行为让我无法解决。
仅供参考,我正在制作一个简单的乒乓球比赛,并试图改善碰撞。我得到的问题是球在顶部或底部碰撞桨。在这些情况下,球在桨的上方(或下方)盘旋并且不移动。我猜这是因为我正在检查碰撞以及我如何改变球的移动速度。
我想实现一种区分顶部/底部和左/右碰撞的方法,但这是唯一可行的方法:
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
答案 0 :(得分:6)
Pong非常简单,不是每一帧移动球并检查与桨的碰撞,实际上你可以解决桨和球碰撞时的等式 - 如果那个时候小于一帧,发生碰撞。
这完全消除了球在球拍中移动速度过快的问题,这个问题困扰着使用天真碰撞检测方法的许多乒乓球克隆。
此解决方案称为continuous collision detection - 有关详细信息,请参阅this answer。
答案 1 :(得分: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;
}