📄 sprite.cpp
字号:
#include "StdAfx.h"
#include ".\sprite.h"
Sprite::Sprite(Bitmap* pBitmap)
{
// Initialize member variable
m_pBitmap = pBitmap;
SetRect(&m_rcPosition, 0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
m_ptVelocity.x = m_ptVelocity.y = 0;
m_iZOrder = 0;
SetRect(&m_rcBounds, 0, 0, 640, 480);
m_baBoundAction = BA_STOP;
m_bHidden = FALSE;
m_bDead = FALSE;
m_bOneCycle = FALSE;
m_iNumFrames = 1;
m_iCurFrame = m_iFrameDelay = m_iFrameTrigger = 0;
}
Sprite::Sprite(Bitmap* pBitmap, RECT& rcBounds, BOUNDSACTION baBoundsAction)
{
// Calculate a random position
int iXPos = rand() % (rcBounds.right - rcBounds.left);
int iYPos = rand() % (rcBounds.bottom - rcBounds.top);
// Initialize the member variable
m_pBitmap = pBitmap;
SetRect(&m_rcPosition, iXPos, iYPos,
iXPos + pBitmap->GetWidth(), iYPos + pBitmap->GetHeight());
m_ptVelocity.x = m_ptVelocity.y = 0;
m_iZOrder = 0;
CopyRect(&m_rcBounds, &rcBounds);
m_baBoundAction = baBoundsAction;
m_bHidden = FALSE;
m_bDead = FALSE;
m_bOneCycle = FALSE;
m_iNumFrames = 1;
m_iCurFrame = m_iFrameDelay = m_iFrameTrigger = 0;
}
Sprite::Sprite(Bitmap* pBitmap, POINT ptPosition, POINT ptVelocity,
int iZOrder, RECT& rcBounds, BOUNDSACTION ba)
{
// Initialize the member variables
m_pBitmap = pBitmap;
SetRect(&m_rcPosition, ptPosition.x, ptPosition.y,
ptPosition.x + pBitmap->GetWidth(), ptPosition.y + pBitmap->GetHeight());
m_ptVelocity = ptVelocity;
m_iZOrder = iZOrder;
CopyRect(&m_rcBounds, &rcBounds);
m_baBoundAction = ba;
m_bHidden = FALSE;
m_bDead = FALSE;
m_bOneCycle = FALSE;
m_iNumFrames = 1;
m_iCurFrame = m_iFrameDelay = m_iFrameTrigger = 0;
}
Sprite::~Sprite(void)
{
}
void Sprite::Update(void)
{
// 如果已经死了,就不用再更新了 ^_^
if (m_bDead)
return;
UpdateFrame();
// 更新位置
POINT ptNewPostion, ptSpriteSize, ptBoundsSize;
ptNewPostion.x = m_rcPosition.left + m_ptVelocity.x;
ptNewPostion.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;
// 检查边界动作
// 精灵环绕到屏幕另一边
if (m_baBoundAction == BA_WRAP)
{
if ((ptNewPostion.x + ptSpriteSize.x) < m_rcBounds.left)
ptNewPostion.x = m_rcBounds.right;
else if (ptNewPostion.x > m_rcBounds.right)
ptNewPostion.x = m_rcBounds.left - ptSpriteSize.x;
if ((ptNewPostion.y + ptSpriteSize.y) < m_rcBounds.top)
ptNewPostion.y = m_rcBounds.bottom;
else if (ptNewPostion.y > m_rcBounds.bottom)
ptNewPostion.y = m_rcBounds.top - ptSpriteSize.y;
SetPosition(ptNewPostion);
}
// 精灵在边界被弹回
else if (m_baBoundAction == BA_BOUNCE)
{
BOOL bBounce = FALSE;
POINT ptNewVelocity = m_ptVelocity;
if (ptNewPostion.x < m_rcBounds.left)
{
bBounce = TRUE;
ptNewPostion.x = m_rcBounds.left;
ptNewVelocity.x = -ptNewVelocity.x;
}
else if ((ptNewPostion.x + ptSpriteSize.x) > m_rcBounds.right)
{
bBounce = TRUE;
ptNewPostion.x = m_rcBounds.right - ptSpriteSize.x;
ptNewVelocity.x = -ptNewVelocity.x;
}
if (ptNewPostion.y < m_rcBounds.top)
{
bBounce = TRUE;
ptNewPostion.y = m_rcBounds.top;
ptNewVelocity.y = -ptNewVelocity.y;
}
else if ((ptNewPostion.y + ptSpriteSize.y) > m_rcBounds.bottom)
{
bBounce = TRUE;
ptNewPostion.y = m_rcBounds.bottom - ptSpriteSize.y;
ptNewVelocity.y = -ptNewVelocity.y;
}
if (bBounce)
SetVelocity(ptNewVelocity);
SetPosition(ptNewPostion);
}
// 精灵在边界停下
else if (m_baBoundAction == BA_STOP)
{
POINT ptNewVelocity = m_ptVelocity;
if (ptNewPostion.x < m_rcBounds.left ||
ptNewPostion.x > (m_rcBounds.right - ptSpriteSize.x))
{
ptNewPostion.x = max(m_rcBounds.left, min(ptNewPostion.x,
m_rcBounds.right - ptSpriteSize.x));
SetVelocity(0, ptNewVelocity.y);
}
if (ptNewPostion.y < m_rcBounds.top ||
ptNewPostion.y > (m_rcBounds.bottom - ptSpriteSize.y))
{
ptNewPostion.y = max(m_rcBounds.top, min(ptNewPostion.y,
m_rcBounds.bottom - ptSpriteSize.y));
SetVelocity(ptNewVelocity.x, 0);
}
SetPosition(ptNewPostion);
}
// 精灵在边界销毁,对于子弹和敌机有效
else
{
if (ptNewPostion.x < (m_rcBounds.left - ptSpriteSize.x) ||
ptNewPostion.x > (m_rcBounds.right + ptSpriteSize.x) ||
ptNewPostion.y < (m_rcBounds.top - ptSpriteSize.y) ||
ptNewPostion.y > (m_rcBounds.bottom + ptSpriteSize.y))
this->Kill();
SetPosition(ptNewPostion);
}
}
void Sprite::Draw(HDC hDC)
{
if (m_pBitmap != NULL && !m_bHidden)
{
if (m_iNumFrames == 1)
m_pBitmap->Draw(hDC, m_rcPosition.left,
m_rcPosition.top, GetWidth(), GetHeight(), 0, 0);
else
m_pBitmap->Draw(hDC, m_rcPosition.left,m_rcPosition.top,
GetWidth(), GetHeight(), m_iCurFrame * GetHeight(), 0);
}
}
void Sprite::SetPosition(int x, int y)
{
m_rcPosition.left = x;
m_rcPosition.top = y;
m_rcPosition.right = x + GetWidth();
m_rcPosition.bottom = y + GetHeight();
}
void Sprite::SetPosition(POINT ptPosition)
{
m_rcPosition.left = ptPosition.x;
m_rcPosition.top = ptPosition.y;
m_rcPosition.right = ptPosition.x + GetWidth();
m_rcPosition.bottom = ptPosition.y + GetHeight();
}
void Sprite::OffsetPosition(int x, int y)
{
m_rcPosition.left += x;
m_rcPosition.right += x;
m_rcPosition.top += y;
m_rcPosition.bottom += y;
}
void Sprite::SetVelocity(int x , int y)
{
m_ptVelocity.x = x;
m_ptVelocity.y = y;
}
void Sprite::SetVelocity(POINT ptVelocity)
{
m_ptVelocity = ptVelocity;
}
void Sprite::CalcCollisionRect()
{
int iXShrink = (m_rcPosition.left - m_rcPosition.right) / 12;
int iYShrink = (m_rcPosition.top - m_rcPosition.bottom) / 12;
CopyRect(&m_rcCollision, &m_rcPosition);
InflateRect(&m_rcCollision, iXShrink, iYShrink);
}
BOOL Sprite::TestCollision(Sprite* pTestSprite)
{
RECT& rcTest = pTestSprite->GetCollision();
return m_rcCollision.left <= rcTest.right &&
rcTest.left <= m_rcCollision.right &&
m_rcCollision.top <= rcTest.bottom &&
rcTest.top <= m_rcCollision.bottom;
}
Sprite* Sprite::AddSprite()
{
return NULL;
}
void Sprite::SetNumFrames(int iNumFrames)
{
// 设置动画帧数
m_iNumFrames = iNumFrames;
// 重新计算位置矩形, 图片比屏幕宽,出问题了
RECT rect = GetPosition();
rect.right = abs(rect.left) + abs((rect.right - rect.left) / iNumFrames);
SetPosition(rect);
}
void Sprite::SetFrameDelay(int iFrameDelay)
{
m_iFrameDelay = iFrameDelay;
}
void Sprite::UpdateFrame()
{
if ((m_iFrameDelay >= 0) && (-m_iFrameTrigger <= 0))
{
// 重置帧触发器
m_iFrameTrigger = m_iFrameDelay;
// 将帧加1
if (++m_iCurFrame >= m_iNumFrames)
{
if (m_saSpriteAction == SA_SHOW)
this->Kill();
else
m_iCurFrame = 0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -