【实验思路】
和一般的小鱼一样,创建一个CSpecialFish类,并且将创建出的对象加入到小鱼链表中。 改造链表的节点,使链表能够容纳第二中小鱼。 【实验指导】
1、 为了将此类型的鱼添加到链表中,需要对结构体做以下修改。
struct FishList { CSprite *pPtr;
};
FishList FishList
*pNext; // 指向链表的下一个 *pPrev; // 指向链表的上一个
2、 修改链表中增加小鱼的操作AddFish。 // 添加一个精灵到链表中
void CGameMain::AddFish( CSprite *pSprite,int iType ) { if( NULL == pSprite ) return; FishList *pFish = new FishList; // pFish->pPtr = pSprite; pFish->pNext = NULL; pFish->pPrev = NULL; // 插入链表中 if( NULL == m_pFishHeader ) m_pFishHeader = pFish; else { FishList *pTemp = m_pFishHeader; while( NULL != pTemp->pNext ) pTemp = pTemp->pNext; pFish->pPrev = pTemp; pTemp->pNext = pFish; } }
3、 通过类向导创建CSpecialFish类,其继承与CSprite类。添加生命值属性,获得和设
置生命值方法。 int m_iHp; int GetHp();
void SetHp( const int iHp );
4、在其构造函数中将其作为模板鱼6的复制,并将其大小改变。 CloneSprite( \
12
上海锐格软件有限公司
SetSpriteScale(0.5f);
5、 接着为小鱼设置X轴坐标和一个随机的Y轴坐标。因为小鱼从右向左游,因此X 坐标在世界边界的右边一些。而Y轴坐标的区间在世界边界的Top和Bottom 值 之间。同时因为小鱼向右游,我们需要将鱼的朝向改为朝向X轴的负方向。 int iRandom=CSystem::RandomRange((int)CSystem::GetScreenTop(),
(int)CSystem::GetScreenBottom());
SetSpritePosition(CSystem::GetScreenRight() + 10.f, (float)iRandom ); SetSpriteFlipX( true ); 6、 最后我们为小鱼设置一个随机速度和世界边界的碰撞属性和范围限制。速度在 [10,25]区间。当小鱼碰到世界边界时小鱼消失,因此设置为WORLD_LIMIT_KILL, 而范围,我们需设置的比屏幕边界大一些,让小鱼完全游出屏幕时才消失。 iRandom = CSystem::RandomRange( 10, 25 );
SetSpriteLinearVelocityX( -(float)iRandom ); SetSpriteWorldLimit(WORLD_LIMIT_NULL, CSystem::GetScreenLeft() - 10.f,
CSystem::GetScreenTop(),CSystem::GetScreenRight()+20.f,
CSystem::GetScreenBottom()); 7、初始化其HP的值: m_iHp= 15;
8、添加处理这种类型的鱼的碰撞功能函数OnColControlFish ,其声明如下: void OnColControlFish(CMyFish *pControlFish); 函数定义以及处理如下: void CSpecialFish::OnColControlFish(CMyFish *pControlFish) { int HP; if (NULL == pControlFish) { return ; } else { pControlFish->SetHp( pControlFish->GetHp() - GetHp() ); HP = pControlFish->GetHp();
if( HP <= 0 ) { pControlFish->SetHp(0); pControlFish->SetLevel(1); pControlFish->SetSpriteScale(0.25f); }else if (HP <= 20) { pControlFish->SetLevel(1); pControlFish->SetSpriteScale(0.25f); }else if (HP <= 100) {
13
}
pControlFish->SetLevel(2); pControlFish->SetSpriteScale(0.5f); }else if (HP <= 10000) { }
pControlFish->SetLevel(3);
pControlFish->SetSpriteScale(0.75f); }
9、在GameRun,生成特殊的鱼,并将它添加到链表中去。
char szNameSpecial[128]; 在 if( m_fCreateNormalTime <= 0.f )中添加以下: sprintf( szNameSpecial, \ CSpecialFish *specialfish = new CSpecialFish(szNameSpecial); AddFish(specialfish);
10、在CGameMain类的OnSpriteColSprite方法中完善碰撞检测,将代码添加到 if( strcmp( m_pMyFish->GetName(), szSrcName ) == 0 )判断里面。 // 找到该鱼的对象实例,调用碰撞处理函数 if(strstr( szTarName, \ ) { CNormalFish* pFish=(CNormalFish*)( GetFishFromName( szTarName )->pPtr); if( NULL != pFish ) { pFish->OnColControlFish( m_pMyFish ); } } else if ( strstr(szTarName, \ { }
CSpecialFish* pFish=(CSpecialFish*)(GetFishFromName( szTarName )->pPtr); if( NULL != pFish ) {
pFish->OnColControlFish( m_pMyFish ); } } // 碰撞之后,不管谁吃谁,都将游戏里的鱼删除掉 DeleteFishFromName( szTarName );
实验五 *为小鱼增加父类
【实验内容】
为CNormalFish、CSpecialFish、CMyFish增加父类CGameSprite。
14
上海锐格软件有限公司
【实验思路】 由于CNormalFish、CSpecialFish和CMyFish有许多共同属性和方法,因此把他们的共性提取出来,使用这些共性为他们创建一个父类CGameSprite。增加父类是为了方便以后再有这方面的类需要创建的时候,就可以直接继承于CGameSprite这个类 【实验指导】
1、 通过类向导添加CGameSprite类,其继续于CSprite类。在类定义前,通过类声明,
声明CMyFish类。 class CMyFish;
class CGameSprite : public CSprite {
public:
// 结合该变量的应用,考虑为什么要用静态成员变量?普通成员变量和静态成员变量的生命周期有什么不同? static int m_iCreatedFishCount; public:
CGameSprite( const char *szName ) : CSprite( szName ) {} ~CGameSprite() { } // Get
// 获取精灵生命值 int GetLevel() { return m_iLevel; }
// 获取精灵级别 int GetHp() { return m_iHp; } // Set void SetLevel( const int iLevel ) { m_iLevel = iLevel; } void SetHp( const int iHp ) { m_iHp = iHp; }
// 当游动的鱼碰撞到玩家控制的鱼的时候调用到。 // pControlFish即为玩家控制的鱼的指针 // 思考:这里为什么使用虚函数 virtual void OnColControlFish( CMyFish *pMyFish ) { } virtual void OnMove(bool bKeyDown,int iKey){} protected:
int m_iHp; // Health Point 生命值 int m_iLevel; // 等级(玩家控制的那条鱼可以升级降级,其它的鱼是初始 // 的时候就给了固定的等级值) };
2、 修改CNormalFish、CSpecialFish、CMyFish三个类的相关代码,使其继承于
CGameSprite类,并且将一部分私有成员变量去除,并将没有virtual前缀的相同的成员函数删除;
3、 修改FishList的结构,将CSprite * pPtr改为以下:
CGameSprite *pPtr;
4、 修改CGameMain类GetFishFromName方法代码。
CGameSprite* CGameMain::GetFishFromName( const char *szName ) {
15
}
FishList *pFish = NULL;
for( pFish = m_pFishHeader; NULL != pFish; pFish = pFish->pNext ) { if( strcmp( szName, pFish->pPtr->GetName() ) == 0 ) return pFish->pPtr; }
return NULL;
5、 修改AddFish的参数。将CSprite * pSprite 改成CGameSprite * pSprite; 6、 修改CGameMain类OnSpriteColSprite方法。 将上一个实验中的 CNormalFish *pFish = (CNormalFish *)(GetFishFromName( szTarName )->pPtr); CSpecialFish *pSpecialFish =(CSpecialFish *)(GetFishFromName( szTarName )->pPtr); 改成: CNormalFish *pFish = (CNormalFish *)(GetFishFromName( szTarName )); CSpecialFish *pSpecialFish =(CSpecialFish *)(GetFishFromName( szTarName )); 7、 至此,游戏就结束了,你可以开始玩自己做的游戏了。
16
相关推荐: