這是一個簡單的箱子碰撞測試。這顯然很簡單,等到你做多邊形碰撞測試!
//! (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);
}
}
如果你打算提到Chipmunk,你可能還會提到Box2D,但我認爲要麼是他想要做的事情過度。 – mpen 2009-08-31 02:05:41