这是一个简单的盒子碰撞测试。显然很简单,等你做多边形碰撞测试!
//! (collision detection)
inline BOOL Sprite::TestCollision(Sprite* pTestSprite)
{
//! Get the collision box.
RECT& rcTest = pTestSprite->GetCollision();
//! box collision check.
return m_rcCollision.left <= rcTest.right && rcTest.left <= m_rcCollision.right &&
m_rcCollision.top <= rcTest.bottom && rcTest.top <= m_rcCollision.bottom;
}
现在至于如何停止精灵或反弹或其他什么,它是这样的:(注意:这种情况是检查与边界的碰撞,但基本上与其他对象执行相同的操作)。如果它只是轴对齐的盒子碰撞,您所要做的就是将碰撞对象与另一个碰撞对象的水平或垂直边缘对齐。如果对象从左侧碰撞,则与另一个对象的左边缘对齐。简单的。如果您想要反弹或停止,请相应地更改速度。
在此示例中,我使用更新的位置创建测试变量,然后进行碰撞测试,然后执行下面的例程,或者如果没有碰撞则设置新位置。所以我们实际上是在碰撞发生之前修复它。
// Update the position
POINT ptNewPosition, ptSpriteSize, ptBoundsSize;
ptNewPosition.x = m_rcPosition.left + m_ptVelocity.x;
ptNewPosition.y = m_rcPosition.top + m_ptVelocity.y;
ptSpriteSize.x = m_rcPosition.right - m_rcPosition.left;
ptSpriteSize.y = m_rcPosition.bottom - m_rcPosition.top;
ptBoundsSize.x = m_rcBounds.right - m_rcBounds.left;
ptBoundsSize.y = m_rcBounds.bottom - m_rcBounds.top;
// Check the bounds
// Wrap?
if (m_baBoundsAction == BA_WRAP)
{
if ((ptNewPosition.x + ptSpriteSize.x) < m_rcBounds.left)
ptNewPosition.x = m_rcBounds.right;
else if (ptNewPosition.x > m_rcBounds.right)
ptNewPosition.x = m_rcBounds.left - ptSpriteSize.x;
if ((ptNewPosition.y + ptSpriteSize.y) < m_rcBounds.top)
ptNewPosition.y = m_rcBounds.bottom;
else if (ptNewPosition.y > m_rcBounds.bottom)
ptNewPosition.y = m_rcBounds.top - ptSpriteSize.y;
}
// Bounce?
else if (m_baBoundsAction == BA_BOUNCE)
{
BOOL bBounce = FALSE;
POINT ptNewVelocity = m_ptVelocity;
if (ptNewPosition.x < m_rcBounds.left)
{
bBounce = TRUE;
ptNewPosition.x = m_rcBounds.left;
ptNewVelocity.x = -ptNewVelocity.x;
}
else if ((ptNewPosition.x + ptSpriteSize.x) > m_rcBounds.right)
{
bBounce = TRUE;
ptNewPosition.x = m_rcBounds.right - ptSpriteSize.x;
ptNewVelocity.x = -ptNewVelocity.x;
}
if (ptNewPosition.y < m_rcBounds.top)
{
bBounce = TRUE;
ptNewPosition.y = m_rcBounds.top;
ptNewVelocity.y = -ptNewVelocity.y;
}
else if ((ptNewPosition.y + ptSpriteSize.y) > m_rcBounds.bottom)
{
bBounce = TRUE;
ptNewPosition.y = m_rcBounds.bottom - ptSpriteSize.y;
ptNewVelocity.y = -ptNewVelocity.y;
}
if (bBounce)
SetVelocity(ptNewVelocity);
}
// v0.1.1 (collision detection)
// Die?
else if (m_baBoundsAction == BA_DIE)
{
if ((ptNewPosition.x + ptSpriteSize.x) < m_rcBounds.left || ptNewPosition.x > m_rcBounds.right
|| (ptNewPosition.y + ptSpriteSize.y) < m_rcBounds.top || ptNewPosition.y > m_rcBounds.bottom)
return SA_KILL;
}
// v0.1.1 ----------------------
// Stop (default)
else
{
if (ptNewPosition.x < m_rcBounds.left || ptNewPosition.x > (m_rcBounds.right - ptSpriteSize.x))
{
ptNewPosition.x = max(m_rcBounds.left, min(ptNewPosition.x, m_rcBounds.right - ptSpriteSize.x));
SetVelocity(0, 0);
}
if (ptNewPosition.y < m_rcBounds.top || ptNewPosition.y > (m_rcBounds.bottom - ptSpriteSize.y))
{
ptNewPosition.y = max(m_rcBounds.top, min(ptNewPosition.y, m_rcBounds.bottom - ptSpriteSize.y));
SetVelocity(0, 0);
}
}