C++语言课程设计一海底世界
一、实验内容
海底有五条鱼,其中四条来回随机游动,由玩家用键盘 W A S D 控制另外一条游动。
要求如下:
1、 游戏初始界面如下图。
2、 来回游动的四条鱼,从屏幕左边游进来,均已一个随机速度水平游动。从屏幕右侧
游出去,很快又从屏幕右侧游出来,就这样来回游动。
3、 玩家用 WASD 键控制一条鱼向上、左、下、右方向游动。松开按键时,玩家的鱼就
停止游动。
4、 玩家的鱼游到屏幕边界时,不能继续往前游。
游戏初始界面
二、实验指南
实验一开始实验
【实验任务】
步骤一、打开 FunCode,创建一个的 C++语言项目;
步骤二、导入 SeaFish 模板。
【实验思路】
按实验指导完成。
【实验指导】
1、 打开 FunCode,点击“项目”菜单,选择“创建 C++工程”
注意:工程名名称要求字母开头,只能包含字母和数字,且名字中间不能有空格。
2、 点击菜单“项目”中的“导入地图模块”,如图一。跳出一个对话框,选中“SeaFish”
模板,点击“导入到工程”按钮,如图二。
图 一
图 二
3、 导入成功后的,界面如下图所示:
地图不仅包括界面设计,还包括该游戏可能要用到的其他精灵。添加到“场景”中
的精灵,都已经取好名称,并根据程序要求设置好中心点、链接点等,学生只需要
直接编程就可以。本实验指导中,精灵的命名名称与模板不相同,可将名称
按实验指导设置。
实验二让 fish 游动
【实验内容】
步骤一、设置 fish0 往特定方向移动
【实验思路】
调用 SetSpriteLinearVelocity 函数设置精灵的移动速度即可。
【实验指导】
1、 进入 LessonX.h 中添加如下的成员变量声明:
CSprite*
m_pFish;
2、 在 LessonX.cpp 中的构造函数里面添加该变量的初始化代码:
m_pFish=new CSprite("fish0");
3、 同时修改构造函数中 m_iGameState 的值为 2,这样游戏启动的时候就直接调用
GameRun 函数使余游动。
4、 在 GameRun 函数里面添加下面一行代码:
m_pFish->SetSpriteLinearVelocity(30, 30);
这样鱼就能游动了。
实验三鱼碰到边界停止游动
【实验内容】
步骤一、边界检测,鱼碰到边界速度为 0
【实验思路】
当系统检测到鱼碰撞到世界边界的时候调用 SetSpriteLinearVelocity 函数使鱼的速度为
0。
【实验指导】
1、 进入 LessonX.h 中添加如下的成员变量:
float
float
float
float
m_fScreenLeft;
m_fScreenRight
m_fScreenTop ;
m_fScreenBottom ;
// 屏幕左边界值
;
// 屏幕上边界值
// 屏幕右边界值
// 屏幕下边界值
2、 在 LessonX.cpp 中 的 构 造 函 数 里 面 添 加 以 上 变 量 的 初 始 化 代 码 , 同 时 将
m_iGameState 的值改为 1,这样游戏开始直接开始初始化操作:
m_iGameState
m_fScreenBottom
m_fScreenLeft
m_fScreenRight
m_fScreenTop
1;
0.f;
0.f;
=
=
0.f;
=
0.f;
=
=
3、 在 GameInit 获取世界边界的值,同时设置鱼的边界限制和初始速度:
// 获取屏幕的边界值
m_fScreenLeft = CSystem::GetScreenLeft();
m_fScreenRight = CSystem::GetScreenRight();
m_fScreenTop = CSystem::GetScreenTop();
m_fScreenBottom = CSystem::GetScreenBottom();
// 设置精灵世界边界
m_pFish->SetSpriteWorldLimit(WORLD_LIMIT_NULL,
m_fScreenTop, m_fScreenRight, m_fScreenBottom);
m_fScreenLeft,
m_pFish->SetSpriteLinearVelocity( 15, 0);
4、 处理世界边界碰撞,建立自定义函数 OnSpriteColWorldLimit:
1) 在 LessonX.h 中添加该函数的声明:
void
OnSpriteColWorldLimit( const char *szName, const int iColSide );
2) 在 LessonX.cpp 中添加该函数的定义代码:
void CGameMain::OnSpriteColWorldLimit( const char *szName, const int
iColSide )
{
}
3) 如果系统检测到鱼碰撞了世界边界,则调用 SetSpriteLinearVelocity 函数将鱼的
速度设置为 0,在上面的函数定义里面添加如下的代码:
if(strcmp(szName, "fish0")==0)
{
m_pFish->SetSpriteLinearVelocity(0, 0);
//dSetSpriteFlipX("fish0", true);
}
4) 最后在 Main.cpp 中的 OnSpriteColWorldLimit 的函数里添加对自定义函数的调用
代码:
g_GameMain.OnSpriteColWorldLimit(szName,iColSide);
实验四鱼碰到边界后按相反方向游动
【实验内容】
步骤一、碰撞检测
步骤二、设置鱼的速度为反方向
【实验思路】
当系统检测到鱼碰撞到世界边界的时候调用 SetSpriteLinearVelocity 函数使鱼的速度为
原来速度的相反数,如原来是 15.f,碰撞后为-15.f,原来是-15.f,碰撞后为 15.f。再调用
SetSpriteFlipX 函数是鱼的图片翻转,让鱼继续游动即可。
【实验指导】
1、 在 LessonX.cpp 中的 OnSpriteColWorldLimit 函数里面,将原来的代码注释掉。
2、 首先检测是否是鱼碰撞到了边界,在该函数里面添加如下代码:
bool bFlip;
floatfSpeedX;
if(strcmp(szName, "fish0")==0)
{
}
3、 如果鱼碰撞到的是右边的边界,则图片翻转,鱼的速度为负速度,即反方向速度,
在上面的 if 中添加如下代码:
if(iColSide == 1)
{
// 右边
bFlip = true;
fSpeedX = -15.f;
}
4、 如果碰到的是左边界,则图片不翻转,鱼的速度为正速度:
else if(iColSide == 0)
// 左边
{
}
bFlip = false;
fSpeedX = 15.f;
5、 最后调用函数,使鱼的图片改变,设置鱼的速度:
m_pFish->SetSpriteFlipX( bFlip);
m_pFish->SetSpriteLinearVelocity(fSpeedX, 0);
实验五多条鱼同时来回游动
【实验内容】
步骤一、通过鱼的模板创建多条鱼的精灵
步骤二、鱼碰撞到边界后设置鱼的速度为反方向
【实验思路】
使用 for 循环,通过鱼的模板利用 CloneSprite 函数创建鱼精灵,设置它的边界限制,给
它一个初始的速度,最后将该鱼精灵加入到 m_vFish 向量数组中保存下来。
当系统检测到鱼碰撞到世界边界的时候调用 SetSpriteLinearVelocity 函数使鱼的速度为
原来速度的相反数,如原来是 15.f,碰撞后为-15.f,原来是-15.f,碰撞后为 15.f。再调用
SetSpriteFlipX 函数是鱼的图片翻转,让鱼继续游动即可。
【实验指导】
1、 打开 FunCode,将地图中的鱼移动到地图外面如下图,并在“编辑”->“程序接口”
中修改鱼的名称为 fish_muban。
2、 进入 LessonX.h 在将 CSprite* m_pFish;注释掉,添加如下的成员变量声明:
vector m_vFish;
3、 在 LessonX.cpp 中的 GameInit 函数里面添加如下的代码:
// 生成多条鱼精灵
for(int i=0; i<4; i++)
{
szName[128];
char
float fPosX, fPosY;
float fSpeedX;
//将 szName 的值赋为“fish”加上 i,即循环因子
sprintf(szName, "fish%d", i);
CSprite* tmpSprite=new CSprite(szName);
tmpSprite->CloneSprite("fish_muban");
//创建鱼精灵
}
4、 随机生成鱼的位置,并设置它的世界边界限制。在上面的 for 循环里添加:
fPosX = CSystem::RandomRange(m_fScreenLeft+10.f, m_fScreenRight-10.f);
fPosY = CSystem::RandomRange(m_fScreenTop+10.f,m_fScreenBottom-10.f);
tmpSprite->SetSpritePosition(fPosX, fPosY);
tmpSprite->SetSpriteWorldLimit(WORLD_LIMIT_NULL, m_fScreenLeft-20.f,
m_fScreenTop, m_fScreenRight+20.f, m_fScreenBottom);
5、 最后随机生成鱼的速度,并将它放入 m_vFish 数组中保存:
fSpeedX = CSystem::RandomRange(10, 20);
tmpSprite->SetSpriteLinearVelocity(fSpeedX, 0);
m_vFish.push_back(tmpSprite);
push_back 函数是 c++中 vector 的内置操作,作用是将元素存放在数组的最后面。
6、 处理多条鱼与世界边界的碰撞的问题,需要添加一个自定义查找某条鱼的函数
FindSpriteByName
1) 在 LessonX.h 中添加该函数的声明:
CSprite*
FindSpriteByName(const char* szName);
2) 在 LessonX.cpp 中添加该函数的定义:
CSprite* CGameMain::FindSpriteByName(const char* szName)
{
}
3) 使用 for 循环遍历数组,找到与传进去的精灵名称相同的鱼并返回即可。在上
面的函数定义里面添加如下的代码:
for(int i=0;iGetName())==0)
return m_vFish[i];
7、 系统检测到鱼碰撞了世界边界,则使用 FindSpriteByName 函数找到该鱼并随机生成
速度赋给它,最后判断是碰到哪个边界再决定是否翻转鱼的图片:
1) 随机生成鱼的速度,修改 OnSpriteColWorldLimit 函数中的如下代码:
fSpeedX = 15.f;改为:fSpeedX = CSystem::RandomRange(10, 20);
SpeedX = -15.f;改为:fSpeedX = -CSystem::RandomRange(10, 20);
2) 再调用函数找到哪条鱼碰撞了世界边界判断是否翻转并设置速度。将原来的代
码:
m_pFish->SetSpriteFlipX( bFlip);
m_pFish->SetSpriteLinearVelocity(fSpeedX, 0);
改为:
CSprite* tmpSprite=FindSpriteByName(szName);
tmpSprite->SetSpriteFlipX(bFlip);
tmpSprite->SetSpriteLinearVelocity(fSpeedX, 0);
fPosY=CSystem::RandomRange(m_fScreenTop+10.f,
m_fScreenBottom-10.f);
//因为有不同的鱼,因此随机生成 Y 方向的速度后需要分配给不同的
//鱼,这样多条鱼就不会重复了
tmpSprite->SetSpritePositionY(fPosY);
实验六键盘控制鱼的游动
【实验内容】
步骤、响应系统按键消息移动鱼
【实验思路】
当键盘上的 W(表示向上方向)A(表示向左方向)S(表示向下方向)D(表示向右方
向)按键中的一个按下后,给鱼一个初始速度并按该按键代表的方向游动,当按键释放
后将鱼的速度设置为 0,使其停止。
【实验指导】
1、 在静态精灵视图中添加一个鱼精灵到地图中并按下图位置摆放。在“编辑”->“程
序接口”中设置名称为 myfish
2、 在 LessonX.h 中添加以下的成员变量声明:
CSprite* m_pMyFish;
3、 在 LessonX.cpp 中的构造函数里面添加以上变量的初始化代码:
m_pMyFish=new CSprite("myfish");
4、 处理键盘按下消息需要添加一个自定义函数 OnKeyDown:
1) 在 LessonX.h 中添加该函数的声明:
void
const int iCtrlPress );
OnKeyDown( const int iKey, const int iAltPress, const int iShiftPress,
2) 在 LessonX.cpp 中添加该函数的定义:
void CGameMain::OnKeyDown( const int iKey, const int iAltPress, const int
iShiftPress, const int iCtrlPress )
{
}
3) 判断按下的按键键值并给响应方向的速度值,在上面的函数里面添加如下代码:
floatfPosX=0.f, fPosY=0.f;
switch(iKey)
{
case KEY_W:
fPosY = -10.f; //向上的时候 Y 方向速度为负的
break;
case KEY_A:
fPosX = -15.f; //向左的时候 X 方向的速度为负值
break;
case KEY_S:
fPosY = 10.f; //向下的时候 Y 方向的速度为正值