📄 gameobject.cpp
字号:
}
return FALSE;
}
/* ------------------------- Moving object ------------------------- */
/*------------------------------------------------------------------------------
Function: CalcNewPos
Purpose: Calculates the moving object current position depending on its speed,
the time passed since we last updated its position, and a flag
indicating that object must be fully inside map.
Input: dwCurTime - Current game time
bMustBeFullyInMap - flag forcing object to be fully in map
Output: Returns the distance passed (squared) or -1 if out of map.
Remarks:
------------------------------------------------------------------------------*/
int CMovingGameObject::CalcNewPos (DWORD dwCurTime, BOOL bMustBeFullyInMap)
{
if (m_uLastTick == 0) // Called for the first time
m_uLastTick = dwCurTime;
DWORD dwTimeGap = dwCurTime - m_uLastTick;
m_uLastTick = dwCurTime;
double dDistanceRatio = m_dVelocity * double (dwTimeGap) * m_cdThousandth,
dXDist = dDistanceRatio * m_dDirectionsArr[m_uDirectionIndex].dXDir,
dYDist = dDistanceRatio * m_dDirectionsArr[m_uDirectionIndex].dYDir;
PrecisePosType NewPrecPos;
NewPrecPos.dXPos = m_PrecPos.dXPos + dXDist;
NewPrecPos.dYPos = m_PrecPos.dYPos + dYDist;
CPoint NewIntPos (int (NewPrecPos.dXPos+0.5), int (NewPrecPos.dYPos+0.5));
if (bMustBeFullyInMap)
{ // Check if object is fully in map
if (GetMapPosition(NewIntPos) != (X_FULL_IN_MAP | Y_FULL_IN_MAP))
{ // Out of map situation
return -1;
}
}
else
{ // check if object is partially in map
WORD fl = GetMapPosition(NewIntPos);
if ((X_NOT_IN_MAP & fl) || (Y_NOT_IN_MAP & fl))
{ // Out of map situation
return -1;
}
}
// Now we know the move is legal:
m_PrevPrecPos = m_PrecPos;
m_PrecPos = NewPrecPos;
m_Pos = NewIntPos;
return int((dXDist * dXDist) + (dYDist * dYDist));
}
/*------------------------------------------------------------------------------
Function: CalcPosAtTime
Purpose: Calculates the moving object new position depending on its speed,
the time passed its previous position and the prev. pos. and a
flag indicating that object must be fully inside map.
Input: StartPos - the previous position
dwTimeGap - the time period the object was moving since the
previous position.
ResPos - the new position [OUT]
bMustBeFullyInMap - flag forcing object to be fully in map
Output: Returns TRUE if new position is contained in map.
Remarks:
------------------------------------------------------------------------------*/
BOOL
CMovingGameObject::CalcPosAtTime (CPoint &StartPos,
DWORD dwTimeGap,
CPoint &ResPos,
BOOL bMustBeFullyInMap)
{
double dDistanceRatio = m_dVelocity * double (dwTimeGap) * m_cdThousandth,
dXDist = dDistanceRatio * m_dDirectionsArr[m_uDirectionIndex].dXDir,
dYDist = dDistanceRatio * m_dDirectionsArr[m_uDirectionIndex].dYDir;
ResPos.x = int (double(StartPos.x) + dXDist + 0.5);
ResPos.y = int (double(StartPos.y) + dYDist + 0.5);
if (bMustBeFullyInMap)
{ // Check if object is fully in map
if (GetMapPosition(ResPos) != (X_FULL_IN_MAP | Y_FULL_IN_MAP))
{ // Out of map situation
return FALSE;
}
}
else
{ // check if object is partially in map
WORD fl = GetMapPosition(ResPos);
if ((X_NOT_IN_MAP & fl) || (Y_NOT_IN_MAP & fl))
{ // Out of map situation
return FALSE;
}
}
return TRUE;
}
void
CMovingGameObject::SetNewPos (int x, int y)
{
m_PrevPrecPos = m_PrecPos;
SetPos (x, y);
m_PrecPos.dXPos = x;
m_PrecPos.dYPos = y;
}
const double CMovingGameObject::m_cdThousandth = double(0.001);
const DirectionType CMovingGameObject::m_dDirectionsArr[MAX_DIRECTIONS] = {
{ -1.0 , 0.0 }, // 0
{ -0.9659258262891, 0.2588190451025 }, // 15
{ -0.8660254037844, 0.5 }, // 30
{ -0.7071067811865, 0.7071067811865 }, // 45
{ -0.5 , 0.8660254037844 }, // 60
{ -0.2588190451025, 0.9659258262891 }, // 75
{ 0.0 , 1.0 }, // 90
{ 0.2588190451025, 0.9659258262891 }, // 105
{ 0.5 , 0.8660254037844 }, // 120
{ 0.7071067811865, 0.7071067811865 }, // 135
{ 0.8660254037844, 0.5 }, // 150
{ 0.9659258262891, 0.2588190451025 }, // 165
{ 1.0 , 0.0 }, // 180
{ 0.9659258262891,-0.2588190451025 }, // 195
{ 0.8660254037844,-0.5 }, // 210
{ 0.7071067811865,-0.7071067811865 }, // 225
{ 0.5 ,-0.8660254037844 }, // 240
{ 0.2588190451025,-0.9659258262891 }, // 255
{ 0.0 ,-1.0 }, // 270
{ -0.2588190451025,-0.9659258262891 }, // 285
{ -0.5 ,-0.8660254037844 }, // 300
{ -0.7071067811865,-0.7071067811865 }, // 315
{ -0.8660254037844,-0.5 }, // 330
{ -0.9659258262891,-0.2588190451025 } // 345
};
/* ------------------------- Exploding object ------------------------- */
CExplodingGameObject::CExplodingGameObject
(UINT uXPos, UINT uYPos, UINT uXSize, UINT uYSize,
UINT uMaxIntensity,
CImageManager::ImageType uExplosionImageIndex,
BOOL InitiallyExploding) :
m_uMaxIntensity (uMaxIntensity),
m_bIsExploding (InitiallyExploding)
{
m_himgExplode = m_GlobalImageManager.GetImage (uExplosionImageIndex);
m_pCurImage = &m_himgExplode; // override this in your ctor
SetPos (uXPos, uYPos);
SetSize (uXSize, uYSize);
ASSERT (uMaxIntensity > 0);
for (int i=0; i<MAX_TANKS; i++)
m_bNotifiedTanks[i]=FALSE; // No tank was notified about an explosion
}
/*------------------------------------------------------------------------------
Function: CalcRelativeExplosionIntensity
Purpose: Calculates the explosion intensity depending on the distance between
our object and the given object, and the min and max radiuses of the
explosition's impact.
Input: pOtherObject - pointer to the object we are exploding
MinRadius - the minimal explosion impact radius: below this radius
the impact is maximal
MaxRadius - the maximal explostion imapct radius: above this radius
there is no impact
Output: The explosion intensity
Remarks: If the distance between the objects is in the range {min, max}, the
intensity is calculated relative to the distance.
------------------------------------------------------------------------------*/
UINT
CExplodingGameObject::CalcRelativeExplosionIntensity (CGameObject *pOtherObject,
UINT MinRadius, UINT MaxRadius)
{
CPoint OtherPos = pOtherObject->GetPos ();
CSize OtherSize = pOtherObject->GetDimensions();
int iXDist = (m_Pos.x + m_Size.cx / 2) - (OtherPos.x + (OtherSize.cx) / 2),
iYDist = (m_Pos.y + m_Size.cy / 2) - (OtherPos.y + (OtherSize.cy) / 2),
iDist = int (sqrt (double(iXDist * iXDist) + double(iYDist * iYDist)) + 0.5);
ASSERT (MaxRadius > MinRadius);
if (iDist <= int(MinRadius))
// We're below minimum radius - return full blast power
return m_uMaxIntensity;
if (iDist >= int(MaxRadius))
// We're behind max radius - no impact
return 0;
// Otherwise , we're between min and max radiuses. Return relative impact
return UINT (double (MaxRadius - iDist) * double (m_uMaxIntensity) /
double (MaxRadius - MinRadius));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -