10 C课程设计贪吃鱼汇总Word格式文档下载.docx
《10 C课程设计贪吃鱼汇总Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《10 C课程设计贪吃鱼汇总Word格式文档下载.docx(21页珍藏版)》请在冰豆网上搜索。
4、小鱼左右运动的速度为30。
上下运动的速度为15。
5、小鱼碰到世界边界时,静止。
6、游戏开始后,通过键盘WSAD键控制小鱼移动。
7、在游戏中显示游戏的等级和玩家控制的鱼的HP。
【实验思路】
按空格键开始游戏,属于键盘按下事件,我们在dOnKeyDown函数中编写代码。
在游戏中,我们运用面向对象的知识将小鱼看成一个对象,并为这个对象添加一个类叫CMyFish。
类具有属性和方法,要控制小鱼能在各个方向上自由的游动,我们为CMyFish类添加上下左右四个方向的速度,并且我们为小鱼添加OnMove方法控制小鱼的游动状态。
【实验指导】
1、在OnKeyDown中,当按下的按键为空格键并且此时的游戏状态为0,则设置游戏的状态为1。
0表示此时游戏为等待状态,未开始。
1表示游戏进行初始化,初始化后会进入2游戏运行状态。
//按下空格键,游戏开始
if(KEY_SPACE==iKey&
&
0==GetGameState())
{
SetGameState
(1);
}
2、在游戏初始化函数GameInit中隐藏"
按空格开始游戏"
这个提示图片。
在CGameMain中添加成员变量:
CSprite*m_pBeginSprite;
在CGameMain的构造函数中进行初始化:
m_pBeginSprite=newCSprite("
kaishi"
);
在GameInit中添加一下代码:
m_pBeginSprite->
SetSpriteVisible(false);
3、通过类向导创建CMyFish类。
首先添加向左、向右、向上、向下4个方向的运动速度属性。
添加OnMove方法控制小鱼的游动,bKeyDown表示键盘时按下的,iKey表示相应的是哪个按键。
classCMyFish:
publicCSprite
{
public:
CMyFish(constchar*szName);
virtual~CMyFish();
voidOnMove(boolbKeyDown,intiKey);
private:
floatm_fVelocityLeft;
//控制的鱼的上下左右游动速度
floatm_fVelocityRight;
floatm_fVelocityUp;
floatm_fVelocityDown;
};
4、在CMyFish类的构造函数中,首先初始4个方向的速度为0,然后设置小鱼缩小到原图的1/4,最后设置和世界边界的碰撞属性为WORLD_LIMIT_STICKY,当碰到世界边界时,小鱼静止不动。
而小鱼的世界边界大小,我们设置为比屏幕的大小大2个单位。
//设置鱼的模型大小为1/4
SetSpriteScale(0.25f);
//世界边界限制
SetSpriteWorldLimit(WORLD_LIMIT_STICKY,
CSystem:
:
GetScreenLeft()-2.f,CSystem:
GetScreenTop()-2.f,
GetScreenRight()+2.f,
CSystem:
GetScreenBottom()+2.f);
5、编写CMyFish类OnMove方法代码。
首先判断当前按键是按下还是松开的,其次判断是哪个按键的消息,根据这两个判断,为4个方向的速度矢量赋值。
再次算出X后和Y轴上的速度,并设置小鱼的速度。
最后根据X轴方向的速度值设置鱼的朝向。
当速度不为0的时候,更改鱼的朝向。
voidCMyFish:
OnMove(boolbKeyDown,intiKey)
if(bKeyDown)
switch(iKey)
{
caseKEY_A:
//左
m_fVelocityLeft=30.f;
break;
caseKEY_D:
//右
m_fVelocityRight=30.f;
caseKEY_W:
//上
m_fVelocityUp=15.f;
caseKEY_S:
//下
m_fVelocityDown=15.f;
}
else
m_fVelocityLeft=0.f;
m_fVelocityRight=0.f;
m_fVelocityUp=0.f;
m_fVelocityDown=0.f;
floatfVelX=m_fVelocityRight-m_fVelocityLeft;
floatfVelY=m_fVelocityDown-m_fVelocityUp;
SetSpriteLinearVelocity(fVelX,fVelY);
//当速度不为0的时候,更改鱼的朝向
if(fVelX<
-0.0001f||fVelX>
0.0001f)
if(fVelX>
SetSpriteFlipX(false);
else
SetSpriteFlipX(true);
}
6、在CGameMain类中,首先添加一个小鱼对象的指针m_pMyFish。
其次在构造函数中将m_pMyFish赋予NULL的初始值。
再次在GameInit方法中初始化m_pMyFish。
因为我们用new方法创建了m_pMyFish对象,分配了内存,所以我们在CGameMain类的析构函数中需要调用delete方法将m_pMyFish使用的内存释放掉。
if(NULL==m_pMyFish)
//创建对象实例
m_pMyFish=newCMyFish("
kongzhiyu"
7、在OnKeyDown和OnkeyUp中响应小鱼OnMove方法,它们的区别只是第一个参数的值不同。
下面是OnKeyDown方法中的调用。
if(2==GetGameState())
m_pMyFish->
OnMove(true,iKey);
8、在CGameMain类的GameInit方法中显示当前等级和分数。
m_pLevelText和m_pHpText需要在CGameMain类中声明,并在其构造函数中定义,其类类型为CTextSprite。
//更新当前等级/HP显示
m_pLevelText->
SetTextValue
(1);
//等级设置为1
m_pHpText->
SetTextValue(0);
//分数设置为0
实验二为游戏添加各种小鱼
1、创建普通鱼CNormalFish类;
2、新添的小鱼一共有4种,从鱼类模板中随机生成;
3、间隔1到2秒生成一只小鱼;
4、小鱼以随机速度从右向左移动;
5、小鱼碰到世界边界后消失;
我们将在游戏中出现的敌方小鱼看成对象,这些对象具有共同的属性和方法,因此我们创建一个CNormalFish类。
并且给这些鱼一定的速度,让他们从产生就开始运动,游过屏幕,然后到达世界边界的另一端就被删除。
1、根据类向导创建CNormalFish类。
//普通类型的鱼,有等级属性。
我们控制的鱼如果等级大于等于此鱼,则可以吃//掉其,如果小于,则被吃掉
classCNormalFish:
publicCSprite
CNormalFish(constchar*szName);
~CNormalFish(){}
2、在CNormalFish类的构造函数中。
首先生成一个1到100的随机数,根据随机数的大小,我们选择不同的小鱼模板。
当随机数小于15时我们选择yu_muban4的小鱼做为模板,当随机数在[15,35]区间时,我们选择yu_muban3做为模板,当随机数在[35,60]区间时,我们选择yu_muban2做为模板,当随机数在[60,100]区间,我们选择yu_muban1做为模板。
intiRandom=CSystem:
RandomRange(1,100);
if(iRandom<
15)
CloneSprite("
yu_muban4"
);
elseif(iRandom<
35)
yu_muban3"
60)
yu_muban2"
{
yu_muban1"
3、接着为小鱼设置X轴坐标和一个随机的Y轴坐标。
因为小鱼从右向左游,因此X坐标在世界边界的右边一些。
而Y轴坐标的区间在世界边界的Top和Bottom值之间。
同时因为小鱼向右游,我们需要将鱼的朝向改为朝向X轴的负方向。
iRandom=CSystem:
RandomRange((int)CSystem:
GetScreenTop(),
(int)CSystem:
GetScreenBottom());
SetSpritePosition(CSystem:
GetScreenRight()+10.f,(float)iRandom);
SetSpriteFlipX(true);
4、最后我们为小鱼设置一个随机速度和世界边界的碰撞属性和范围限制。
速度在[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,
5、完成了CNormalFish类后,我们需要在CGameMain类中生成小鱼,即生成CNormalFish类的实例。
首先添加一个变量表示创建鱼的时间间隔和表示小鱼数目的变量。
floatm_fCreateNormalTime;
intm_iCreatedFishCount;
6、然后在GameRun方法中,游戏循环将m_fCreateNormalTime递减,当m_fCreateNormalTime小于0时,创建一只鱼。
并在[100,300]区间随机去个数除以100做为下一次创建小鱼的时间间隔。
charszName[128];
m_fCreateNormalTime-=fDeltaTime;
if(m_fCreateNormalTime<
=0.f)
intiNextTime=CSystem:
RandomRange(100,300);
m_fCreateNormalTime=(float)iNextTime/100.f;
sprintf(szName,"
putongyu_%d"
m_iCreatedFishCount);
m_iCreatedFishCount++;
CNormalFish*fish=newCNormalFish(szName);
实验三吃小鱼
1、玩家控制小鱼与其它小鱼碰撞,当玩家小鱼等级小于敌方小鱼时,玩家小鱼被吃掉,反之敌方小鱼被吃掉;
每吃掉一只小鱼,玩家小鱼的分数增加为敌方小鱼的HP值
2、需要根据小鱼的等级确定碰撞的不同结果,因此为小鱼添加等级的属性;
3、同时不同的等级拥有不同的分数,因此为小鱼增加分数的属性;
首先为CMyFish类增加碰撞属性;
然后为CMyFish类增加表示小鱼等级和HP的属性,增加设置等级、HP值和获得等级、HP值的方法;
同理为CNormalFish类增加碰撞属性及其小鱼等级、HP的属性和获得等级、HP值的方法。
CMyFish、CNormalFish类小鱼,是在创建时就设置好了其等级和HP值,因此我们可以在构造函数中增加两个参数,直接在创建小鱼时,就初始化好等级和HP值。
在CGameMain类的OnSpriteColSprite碰撞函数中检测碰撞,并更新游戏界面中HP的值。
在OnSpriteColSprite中,我可以知道碰撞双方的名称,但我们还需要根据名称获得具体的小鱼的对象,以便获得小鱼的等级和HP值等属性,因此我们每创建一只小鱼,就把这只小鱼增加到链表中管理起来。
这样我们就增加了一个FishList链表。
1、首先为MyFish设置碰撞属性。
MyFish产生碰撞,敌方小鱼接受碰撞。
这个在控制面板中已经设置好了,如果想自己设置么可以添加如下代码,将控制面板中碰撞属性取消,在构造函数中设置碰撞属性。
SetSpriteCollisionActive(true,false);
2、其次为敌方小鱼设置碰撞属性。
敌方小鱼接受碰撞,这个属性和1一样,也在界面中设置好了,如果想要自行设置,可以取消界面中的设置,然后在CNormalFish类的构造函数中增加如下代码。
SetSpriteCollisionActive(false,true);
3、为CMyFish和CNormalFish增加等级和HP值的属性,和设置、获得这两个属性的方法,最后改造构造函数。
intm_iHp;
intm_iLevel;
CMyFish:
CMyFish(constchar*szName,constintiHp,constintiLevel);
CNormalFish:
CNormalFish(constchar*szName);
//普通鱼的HP和level随机生成
4、在LessonX.h中定义结构体FishList,并在CGameMain类中添加一个头节点m_pFishHeader。
structFishList
CNormalFish*pPtr;
FishList*pNext;
//指向链表的下一个
FishList*pPrev;
//指向链表的上一个
5、在CGameMain类中添加AddFish方法实现将小鱼添加到链表中,参数为生成的敌方小鱼的指针。
voidCGameMain:
AddFish(CNormalFish*pSprite)
if(NULL==pSprite)
return;
FishList*pFish=newFishList;
pFish->
pPtr=pSprite;
pNext=NULL;
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;
6、同时在碰撞时,我们需要根据小鱼的名称获得小鱼的对象,因此添加GetFishFromName方法。
CNormalFish*CGameMain:
GetFishFromName(constchar*szName)
FishList*pFish=NULL;
for(pFish=m_pFishHeader;
NULL!
=pFish;
pFish=pFish->
if(strcmp(szName,pFish->
pPtr->
GetName())==0)
returnpFish->
pPtr;
returnNULL;
7、在CGameMain类的GameRun方法中,将创建的小鱼对象的指针添加到链表中。
8、玩家的小鱼根据HP值分为1-4不同的等级,初始HP的值为10,等级为1。
当HP大于20时且等级为1时,玩家升为2级;
当HP值大于100时且等级为2时,玩家升为3级;
当HP值大于1000时且等级为3时,玩家升为4级。
每升1级,鱼的大小也变大25%。
在CNormalFish类中添加碰撞处理函数:
voidOnColControlFish(CMyFish*pControlFish);
定义如下:
voidCNormalFish:
OnColControlFish(CMyFish*pControlFish)
...
在上述函数中添加以下代码:
if(pControlFish==NULL)
if(m_pMyFish->
GetLevel()>
=GetLevel())
pControlFish->
SetHp(pControlFish->
GetHp()+GetHp());
if(m_pMyFish->
GetHp()>
=1000&
m_pMyFish->
GetLevel()==3)
m_pMyFish->
SetLevel(4);
SetSpriteScale(1.0f);
//模型变大
elseif(m_pMyFish->
=100&
GetLevel()==2)
SetLevel(3);
SetSpriteScale(0.75f);
}
=20&
GetLevel()==1)
{
SetLevel
(2);
SetSpriteScale(0.5f);
pControlFish->
SetHp(0);
9、接着我们在CGameMain类中声明函数OnSpriteColSprite处理碰撞。
OnSpriteColSprite函数的第一个参数是碰撞的产生方的名称,第二个参数是碰撞接受方的名称。
由上面两个步骤,我们知道碰撞产生方是玩家控制的小鱼的名称,接受方是敌方小鱼的名称。
而碰撞方是直接被删除。
同时更新玩家控制小鱼的HP。
if(2!
=GetGameState()||NULL==m_pMyFish)
return;
elseif(strcmp(m_pMyFish->
GetName(),szSrcName)==0)
if(!
strstr(szTarName,"
putongyu"
))
return;
CNormalFish*pFish=GetFishFromName(szTarName);
if(NULL!
=pFish)
OnColControlFish(m_pMyFish);
DeleteFishFromName(szTarName);
10、DeleteFishFromName将碰撞后的小鱼从链表中删除。
DeleteFishFromName(constchar*szName)
GetName())==0)
if(NULL!
=pFish->
pFish->
pNext->
pPrev=pFish->
pPrev;
pPrev)
pPrev->
pNext=pFish->
if(pFish==m_pFishHeader)
m_pFishHeader=m_pFishHeader-