📄 gameobject.cpp
字号:
/*****************************************************************************
*
* GameObject.cpp
*
* Electrical Engineering Faculty - Software Lab
* Spring semester 1998
*
* Tanks game
*
* Module description: Implements the GameObject hierarchy :
* GameObject (abstract)
* / \
* MovingObject ExplodingObject
* All game objects (tanks, shells, etc.) are derived from
* one or more (multiple inheritance) of these classes.
*
*
* Authors: Eran Yariv - 28484475
* Moshe Zur - 24070856
*
*
* Date: 23/09/98
*
******************************************************************************/
#include <stdafx.h>
#include <math.h>
#include <GameObject.h>
#include <GameConsts.h>
#include <Tanks.h>
CGameObject::CGameObject () :
m_ListPosition (NULL),
m_UpdateRect (m_Pos, m_Size),
m_GlobalImageManager (TANKS_APP->m_gImageManager),
m_GlobalObjsList (TANKS_APP->m_gGameManager.ExposeObjects())
{}
/*------------------------------------------------------------------------------
Function: GetMapPosition
Purpose: Returns the objects current position on game board (map).
The object can be entirely seen (fully in map), partialy seen
(some portion of the object is out of map), and unseen.
Input: pos - the suggested position of the object on the map.
Output: Status of the object visiblity given the suggested position.
Remarks:
------------------------------------------------------------------------------*/
WORD CGameObject::GetMapPosition (CPoint &pos)
{
WORD wRes = 0;
CRect ObjRect (pos, m_Size),
TmpRect,
MapRect (0, 0, MAP_WIDTH-1, MAP_HEIGHT-1);
CBitMask *myBitMask = m_GlobalImageManager.ExposeBitMask(GetImage());
if (NULL != myBitMask)
{
// There's a better rectangle for the object
CRect &ActualRect = myBitMask->GetActualRect();
int x1 = pos.x + ActualRect.left,
y1 = pos.y + ActualRect.top;
ObjRect.SetRect (x1, y1, x1 + ActualRect.Width(), y1 + ActualRect.Height());
}
if (ObjRect.left >= 0 && ObjRect.right < MAP_WIDTH)
wRes |= X_FULL_IN_MAP; // Map fully contains the object in the X axis
else if (TmpRect.IntersectRect (ObjRect, MapRect) != 0)
wRes |= X_PARTIAL_IN_MAP; // Map partailly contains the object in the X axis
else
wRes |= X_NOT_IN_MAP; // Map doesn't contains the object in the X axis
if (ObjRect.top >= 0 && ObjRect.bottom < MAP_HEIGHT)
wRes |= Y_FULL_IN_MAP; // Map fully contains the object in the Y axis
else if (TmpRect.IntersectRect (ObjRect, MapRect) != 0)
wRes |= Y_PARTIAL_IN_MAP; // Map partailly contains the object in the Y axis
else
wRes |= Y_NOT_IN_MAP; // Map doesn't contains the object in the Y axis
return wRes;
}
/*------------------------------------------------------------------------------
Function: CollidesWith
Purpose: Check if our object collides with the given object.
Input: pOtherObj - the pointer to the object to be checked against.
Output: TRUE if objects collide.
Remarks: Some objects contains bitmasks for more accurate collision detection
(by pixel resolution), but more time consuming. For objects w/o
bitmasks the object rectangles are checked for intersection.
------------------------------------------------------------------------------*/
BOOL CGameObject::CollidesWith (CGameObject *pOtherObj)
{
CRect IntersecRect = pOtherObj->CGameObject::GetUpdateRectangle();
IntersecRect &= CGameObject::GetUpdateRectangle();
if (IntersecRect.IsRectEmpty())
{ // no further calculations needed - rects don't intersect:
return FALSE;
}
// check if bit masks of objects collides: (check is ignored if both bit masks are null)
CBitMask *myBitMask = m_GlobalImageManager.ExposeBitMask(GetImage());
CBitMask *otherBitMask = m_GlobalImageManager.ExposeBitMask(pOtherObj->GetImage());
if (! myBitMask && ! otherBitMask) {
return TRUE;
}
return BitMaskCollides (IntersecRect,
m_Pos,
pOtherObj->GetPos(),
myBitMask,
otherBitMask);
}
/*------------------------------------------------------------------------------
Function: CollidesWith
Purpose: Check if our object collides with the given object.
Input: pOtherObj - the pointer to the object to be checked against.
MyRect - a specified rectangle on the game board object to be
checked against.
Output: TRUE if objects collide.
Remarks: This method is called from game board only.
Thus we know there is no bit mask for the other object and that
UpdateRect is no good for us.
------------------------------------------------------------------------------*/
BOOL CGameObject::CollidesWith (CGameObject* pOtherObj, CRect& MyRect)
{
CRect IntersecRect = pOtherObj->CGameObject::GetUpdateRectangle();
IntersecRect &= MyRect;
if (IntersecRect.IsRectEmpty())
{ // no further calculations needed - rects don't intersect:
return FALSE;
}
// check if there is a bit mask:
if (m_GlobalImageManager.ExposeBitMask(pOtherObj->GetImage())) {
return BitMaskCollides (IntersecRect,
MyRect.TopLeft(),
pOtherObj->GetPos(),
NULL,
m_GlobalImageManager.ExposeBitMask(pOtherObj->GetImage()));
}
return TRUE;
}
/*------------------------------------------------------------------------------
Function: BitMaskCollides
Purpose: Test if the given bitmasks collides inside the given rectangle.
Input: IntersectRect - The intersection rectangle of the objects that
overlaps.
myPos - The position of one object on the map
otherPos - the position of the other object on the map
myBitMask - the bitmask of one object (may be null)
otherBitMask - the bitmask of the other object (may be null)
Output: TRUE if the two bitmasks collides inside the region of the
intersection rectangle.
Remarks: At least on of the bitmask must exist (otherwise this code wasn't
inuse).
------------------------------------------------------------------------------*/
BOOL
CGameObject::BitMaskCollides (CRect& IntersectRect, CPoint& myPos, CPoint& otherPos,
CBitMask* myBitMask, CBitMask* otherBitMask)
{
CPoint myOffset = IntersectRect.TopLeft() - myPos;
CPoint otherOffset = IntersectRect.TopLeft() - otherPos;
ASSERT(myBitMask || otherBitMask); // at this stage at least one bit mask exists
if (myBitMask && otherBitMask)
{ // both object have bitmasks:
for (int i = 0; i < IntersectRect.Width(); i++) {
for (int j = 0; j < IntersectRect.Height(); j++) {
if (myBitMask->GetMaskAt(i + myOffset.x, j + myOffset.y) &&
otherBitMask->GetMaskAt(i + otherOffset.x, j + otherOffset.y))
return TRUE;
}
}
return FALSE;
}
// Only one object contains a bit mask, so we assume the missing bitmask is
// all ones:
CBitMask *BitMask;
CPoint Offset;
if (myBitMask) {
BitMask = myBitMask;
Offset = myOffset;
} else {
BitMask = otherBitMask;
Offset = otherOffset;
}
for (int i = Offset.x; i < Offset.x + IntersectRect.Width(); i++) {
for (int j = Offset.y; j < Offset.y + IntersectRect.Height(); j++) {
if (BitMask->GetMaskAt(i, j))
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -