{
((CEnemyFighter *)pSprite)->LoopTick(fDeltaTime); }}
17、在GameEnd中添加代码,清空所有精灵,显示空格开始。
m_pBeginSprite->SetSpriteVisible(true); m_SpriteList.DeleteAllSprite(true); m_pMyFighter->SetSpriteVisible(false); delete m_pMyFighter; m_pMyFighter = NULL;
实验五 添加碰撞检测
【实验内容】
1、创建一个精灵父类CGameSprite;
2、将战机类和子弹类改为继承于CGameSprite类;
3、为游戏中的精灵添加HP属性,并为子弹添加破坏力的属性。 4、CGameSprite类添加检测碰撞的虚函数,并在各子类中实现; 5、当玩家战机的HP值小于0是游戏结束。
【实验思路】
检测碰撞时,我们先获取碰撞的双方,然后再将其各自做碰撞检测。并且产生碰撞特效,是游戏看起来更加逼真。用虚函数的方式实现多态。
【实验指导】
1、分析我方战机类、敌方战机类、子弹类的共同特性,我们提取它们的这些共性,创
建它们的父类CGameSprite类,使得我方战机、敌方战机和子弹类都继承于CGameSprite类。仿照上边方法创建CGameSprite类:
class CGameSprite : public CSprite { private: public:
CGameSprite( const char *szName ); virtual ~CGameSprite() { };
};
注意修改构造函数。
2、为CGameSprite类添加生命值、碰上敌方,给敌方造成的伤害值和击毁本Sprite将
获得的积分值以及精灵类型。并为这四个个属性添加Set和Get方法
int m_iHp; int m_iDamage; int m_iScore; int m_iType;
3、添加IsDead方法。当m_iHp小于等于0时,精灵为死亡状态。
boolIsDead(){ return ( GetHp() <= 0 ); }
4、添加IsMyBullet,方法判断子弹是谁发射的。
// 子弹类专用函数.判断子弹是哪方发射的
16
上海锐格软件有限公司 virtual boolIsMyBullet() { return false; } 5、添加IsMyFighter,判断是否为我方战机。
virtual boolIsMyFighter(){ return false; }
6、添加虚函数OnColOtherSprite,处理精灵之间的碰撞。
virtual voidOnColOtherSprite( CGameSprite *pOther );
7、将CBullet、CMyFighter和CEnemyFighter三个类的父类改为CGameSprite。 注意需要修改各自的构造函数并包含头文件: #include\8、修改CSpriteList类中的函数参数以及返回值,将原先所有的CSprite * 更改为
CGameSprite *;并将结构体中的CSprite * pSprite; 改为CGameSprite * pSprite; 9、在CMyFight中添加函数:
bool IsMyFighter(){ return true; }
在CGameMain的GameInit函数中添加代码初始化数据,在GameInit函数最后添加代码:
m_pControlSprite->SetHp( 500 ); m_pControlSprite->SetScore( 0 );
m_pControlSprite->SetCanFire( true );
10、在CGameMain中添加通过索引值或者名字获取精灵的两个函数,:
CGameSprite *CGameMain::GetSprite( const int iIndex ) {
return m_SpriteList.GetSprite(iIndex); }
CGameSprite *CGameMain::GetSprite( const char *szName ) {
return m_SpriteList.GetSprite(szName); } 11、为CBullet添加OnColOtherSprite方法,并实现此方法。
void CBullet::OnColOtherSprite( CGameSprite *pOther )
{
if( NULL == pOther ) return; if(IsMyBullet () ) {
if( pOther->IsMyFighter () ) return;
SetHp( GetHp() - pOther->GetDamage() ); } else {
if( pOther->IsMyFighter () || pOther->IsMyBullet () ) {
SetHp( GetHp() - pOther->GetDamage() ); }
17
} }
注意因为用到全局对象g_GameMain,所以需要声明头文件,第10步同: #include\
12、在CGameMain中添加函数,获取控制的精灵对象。
在LessonX.h中声明: CMyFight * GetMyFight(); 在LessonX.cpp中添加定义:
CMyFight * CGameMain::GetMyFight() {
if (NULL != m_pMyFighter) {
return m_pMyFighter; } }
13、为CMyFightr添加OnColOtherSprite方法,并实现此方法。
void CMyFight::OnColOtherSprite( CGameSprite *pOther ) {
if( NULL == pOther ) return;
if( pOther-> IsMyBullet () ) return;
SetHp( GetHp() - pOther->GetDamage() ); if( GetHp() <= 200 ) {
SetSpriteColorGreen( 0 ); SetSpriteColorBlue( 0 ); }
else if( GetHp() <= 500 ) {
SetSpriteColorGreen( 128 ); SetSpriteColorBlue( 128 ); } else {
SetSpriteColorGreen( 255 ); SetSpriteColorBlue( 255 ); }
//更新积分显示
g_GameMain.GetMyFight()->SetScore( g_GameMain.GetMyFighter()->GetScore() +
pOther->GetScore() );
}
14、为CEnemyFighter添加OnColOtherSprite方法,并实现此方法。
18
上海锐格软件有限公司 void CEnemyFighter::OnColOtherSprite( CGameSprite *pOther ) {
if( NULL == pOther ) return;
if( pOther-> IsMyFighter () || pOther-> IsMyBullet () ) {
SetHp( GetHp() - pOther->GetDamage() ); if (IsDead()) {
g_GameMain.GetMyFight()->SetScore(g_GameMain.GetMyFight()->GetScore() GetScore());
} } }
+
15、在CGameMain类中添加函数,通过名字判断是否是我方坦克:
bool CGameMain::IsMyFighter( const char *szName ) {
return (strcmp( m_ pMyFighter ->GetName(), szName ) == 0); }
16、的OnSpriteColSprite方法中添加碰撞检测。
voidCGameMain::OnSpriteColSprite( const char *szSrcName, const char *szTarName ) {
if( 2 != GetGameState() ) return;
CGameSprite*pSrcSprite =IsMyFighter
GetSprite( szSrcName );
CGameSprite *pTarSprite=IsMyFighter
GetSprite( szTarName );
if( NULL == pSrcSprite || NULL == pTarSprite ) return;
pSrcSprite->OnColOtherSprite( pTarSprite ); pTarSprite->OnColOtherSprite( pSrcSprite );
if( !pSrcSprite-> IsMyFighter () ) {
if( pSrcSprite->IsDead() )
g_GameMain.DeleteSprite( pSrcSprite, true ); }
if( !pTarSprite-> IsMyFighter () ) {
if( pTarSprite->IsDead() )
19
(szSrcName (szTarName
) )
? ?
m_pMyFighter m_pMyFighter
::