05 C++课程设计迷你高尔夫.docx
《05 C++课程设计迷你高尔夫.docx》由会员分享,可在线阅读,更多相关《05 C++课程设计迷你高尔夫.docx(24页珍藏版)》请在冰豆网上搜索。
![05 C++课程设计迷你高尔夫.docx](https://file1.bdocx.com/fileroot1/2023-5/16/edfad3a2-8c5c-4f9f-b6ed-ddf6499b813f/edfad3a2-8c5c-4f9f-b6ed-ddf6499b813f1.gif)
05C++课程设计迷你高尔夫
C++语言课程设计一迷你高尔夫
一、实验内容
玩家通过按下键盘上的上下左右方向键控制球的移动,使其最终到达出口则游戏通关。
要求如下:
1、游戏分成3关,第一关、第二关、第三关界面图如下:
第一关
第二关
第三关
2、启动游戏进入第一关,胜利后进入第二关,如果第三关通关,则游戏重新回到第一关。
3、游戏玩法是通关控制键盘上的上下左右方向键控制球的运动,单击方向键,则球获得一个向该方向直线运动的速度。
如果球遇到方块,则球停止运动,如果遇到黑洞,则游戏结束,重新开始该游戏,遇到出口则通关。
4、球静止状态下会有箭头指示球可以运动的方向,运动状态下则箭头消失。
如果球运动出世界边界,则游戏结束,重新回到该游戏。
二、实验指南
实验一开始实验
【实验任务】
步骤一、打开FunCode,创建一个的C++语言项目;
步骤二、导入GolfGame场景。
【实验思路】
按实验指导完成。
【实验指导】
1、打开FunCode,点击“项目”菜单,选择“创建C++工程”
注意:
工程名名称要求字母开头,只能包含字母和数字,且名字中间不能有空格。
2、点击菜单“项目”中的“导入地图模块”,如图一。
跳出一个对话框,选中“GolfGame”模板,点击“导入到工程”按钮,如图二。
图一图二
3、导入成功后的,界面如下图所示:
地图不仅包括界面设计,还包括该游戏可能要用到的其他精灵。
添加到“场景”中的精灵,都已经取好名称,并根据程序要求设置好中心点、链接点等,学生只需要直接编程就可以。
实验二游戏关卡初始化
【实验内容】
步骤一、关卡地图初始化
步骤二、清除上一关卡数据
步骤三、根据当前关卡,选择关卡数据
【实验思路】
游戏开始的时候首先要清除上一关的游戏数据,即将上一关创建的精灵从地图中删掉。
将游戏地图分成12*12的方格界面,游戏总共分成三关,因此我们需要用三个二维数组m_iLevelData1[GRID_COUNT][GRID_COUNT]
m_iLevelData2[GRID_COUNT][GRID_COUNT]
m_iLevelData3[GRID_COUNT][GRID_COUNT]
(其中GRID_COUNT的值为12)
来存放这三关的数据即可。
二维数组中0表示该位置不创建精灵,否则根据不同的值创建不同精灵,RIGID_BLOCK(值为1)表示创建一个方块精灵,BLACK_HOLE(值为2)表示创建一个黑洞精灵,GOLF_EXIT(值为3)表示创建一个出口精灵。
每次把代表该关卡的二维数组的数据拷贝到存储当前关卡m_iGridData的二维数组中。
【实验指导】
1、进入LessonX.h的CGameMain类中,添加以下成员变量的声明:
intm_iMoveState;//控制球的移动状态:
0当前静止,可以移动,1、2、3、4:
代表上下左右4个方向移动中,按键无响应
intm_iCurLevel;//当前关卡
staticconstfloatm_fGridStartX;//第一块方块的起始坐标=-(GRID_COUNT*g_fGridSize*0.5-g_fGridSize/2)
staticconstfloatm_fGridStartY;
staticconstfloatm_fGridSize;//每块的大小,包括球、出口等都是此大小
intm_iRigidBlockCount;//本关卡创建的阻挡物方块数量
intm_iBlackHoleCount;//本关卡创建的黑洞数量
intm_iGolfExitCount;//本关卡创建的出口的数量
intm_iGridData[GRID_COUNT][GRID_COUNT];//二维数组,存储当前关卡N*N的矩阵方块信息
staticconstintm_iLevelData1[GRID_COUNT][GRID_COUNT];
staticconstintm_iLevelData2[GRID_COUNT][GRID_COUNT];
staticconstintm_iLevelData3[GRID_COUNT][GRID_COUNT];
vectorm_vRigidBlock;//阻挡物精灵向量数组
vectorm_vBlackHole;//黑洞精灵向量数组
vectorm_vGolfExit;//出口精灵向量数组
2、进入LessonX.h中在头文件声明的后面添加下面的宏定义代码:
#defineGRID_COUNT12//N*N的矩阵方块,一个N的大小
#defineMAX_LEVEL3//最大关卡数量。
如果要增加关卡,请先修改此值
#defineRIGID_BLOCK1//以下3个分别为方块阻挡物、黑洞、出口的值
#defineBLACK_HOLE2
#defineGOLF_EXIT3
3、在LessonX.h头文件#include下面添加:
#include
usingstd:
:
vector;
4、进入LessonX.cpp中添加上面的成员变量的初始化:
1)在构造函数中把m_iGameState的值由0改为1:
m_iGameState=1;
2)在构造函数中添加下面代码:
m_iCurLevel=1;
m_iMoveState=0;//控制球的移动状态:
0当前静止,可以移动,1、2、3、4:
代表上下左右4个方向移动中,按键无响应
m_iRigidBlockCount=0;//本关卡创建的阻挡物方块数量
m_iBlackHoleCount=0;//本关卡创建的黑洞数量
m_iGolfExitCount=0;
3)对于const类型的成员变量,我们需要在函数外面单独进行初始化,在文件最后面添加如下代码:
constfloatCGameMain:
:
m_fGridStartX=-27.5f;
constfloatCGameMain:
:
m_fGridStartY=-27.5f;
constfloatCGameMain:
:
m_fGridSize=5.f;
constintCGameMain:
:
m_iLevelData1[GRID_COUNT][GRID_COUNT]={
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,RIGID_BLOCK,RIGID_BLOCK,RIGID_BLOCK,RIGID_BLOCK,RIGID_BLOCK,RIGID_BLOCK,0,0,0},
{0,0,0,RIGID_BLOCK,0,0,0,0,RIGID_BLOCK,0,0,0},
{0,0,0,RIGID_BLOCK,0,0,0,0,RIGID_BLOCK,0,0,0},
{0,0,0,RIGID_BLOCK,0,0,0,0,BLACK_HOLE,0,0,0},
{0,0,0,0,0,0,0,GOLF_EXIT,RIGID_BLOCK,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0}
};
constintCGameMain:
:
m_iLevelData2[GRID_COUNT][GRID_COUNT]={
{0,RIGID_BLOCK,RIGID_BLOCK,RIGID_BLOCK,0,RIGID_BLOCK,RIGID_BLOCK,RIGID_BLOCK,RIGID_BLOCK,RIGID_BLOCK,RIGID_BLOCK,0},
{0,RIGID_BLOCK,0,0,0,0,0,0,0,0,RIGID_BLOCK,0},
{0,RIGID_BLOCK,0,0,0,0,0,0,0,0,RIGID_BLOCK,0},
{0,RIGID_BLOCK,0,0,0,0,0,0,0,0,RIGID_BLOCK,0},
{0,RIGID_BLOCK,0,0,0,0,0,0,0,0,RIGID_BLOCK,0},
{0,RIGID_BLOCK,0,0,0,0,0,0,0,0,RIGID_BLOCK,0},
{0,RIGID_BLOCK,0,0,0,RIGID_BLOCK,RIGID_BLOCK,RIGID_BLOCK,0,0,RIGID_BLOCK,0},
{0,RIGID_BLOCK,0,0,0,0,0,RIGID_BLOCK,0,0,RIGID_BLOCK,0},
{0,RIGID_BLOCK,0,0,0,0,0,0,GOLF_EXIT,RIGID_BLOCK,RIGID_BLOCK,0},
{0,RIGID_BLOCK,0,0,0,0,0,0,0,0,0,0},
{0,RIGID_BLOCK,0,0,0,0,0,0,0,0,RIGID_BLOCK,0},
{0,RIGID_BLOCK,0,RIGID_BLOCK,RIGID_BLOCK,RIGID_BLOCK,RIGID_BLOCK,RIGID_BLOCK,RIGID_BLOCK,0,RIGID_BLOCK,0}
};
constintCGameMain:
:
m_iLevelData3[GRID_COUNT][GRID_COUNT]={
{0,0,0,0,0,0,0,0,RIGID_BLOCK,RIGID_BLOCK,0,0},
{0,0,RIGID_BLOCK,RIGID_BLOCK,RIGID_BLOCK,0,0,0,0,0,0,RIGID_BLOCK},
{RIGID_BLOCK,0,0,0,0,0,0,0,0,0,0,RIGID_BLOCK},
{0,0,0,0,0,0,0,0,0,0,0,RIGID_BLOCK},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,GOLF_EXIT,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,RIGID_BLOCK,RIGID_BLOCK,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,RIGID_BLOCK,0},
{0,0,0,RIGID_BLOCK,0,0,0,0,0,0,RIGID_BLOCK,0},
{0,0,0,0,BLACK_HOLE,RIGID_BLOCK,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0}
};
二维数组中0表示该位置不创建精灵,否则根据不同的值创建不同精灵,RIGID_BLOCK(值为1)表示创建一个方块精灵,BLACK_HOLE(值为2)表示创建一个黑洞精灵,GOLF_EXIT(值为3)表示创建一个出口精灵。
4)进入GameInit函数里面,将球的运动状态初始化为静止,添加下面代码:
m_iMoveState=0;
5、游戏初始化的时候,首先我们需要将前边添加的精灵全部删除掉。
1)进入LessonX.h文件的CGameMain类中添加该函数的声明:
voidClearAllSprite();
2)在LessonX.cpp最后面添加该函数的定义:
voidCGameMain:
:
ClearAllSprite()
{
}
3)再使用3个循环,分别将上一关卡创建的3种精灵删除掉。
在上边定义的函数中添加如下代码:
intiLoop=0;
for(iLoop=0;iLoop{
m_vRigidBlock[iLoop]->DeleteSprite();
}
for(iLoop=0;iLoop{
m_vBlackHole[iLoop]->DeleteSprite();
}
for(iLoop=0;iLoop{
m_vGolfExit[iLoop]->DeleteSprite();
}
//总数置0,重新创建
m_iRigidBlockCount=0;
m_iBlackHoleCount=0;
m_iGolfExitCount=0;
其中m_vRigidBlock、m_vBlackHole、m_vGolfExit是存储三种精灵的向量数组,每一个循环都遍历一遍向量数组并调用数组中每个精灵的DeleteSprite函数即可。
m_vRigidBlock.size()、m_vBlackHole.size()、m_vGolfExit.size()表示每种精灵的总数
4)最后在GameInit()中添加调用此函数的代码:
ClearAllSprite();
5)在GameInit()中,我们对关卡进行选择初始化。
a.选择关卡我们使用了switch-case结构,程序通过判断switch中的参数进入到不同的case中去,每个case就是一种情况的实现。
代码如下:
//控制球在数组中的开始位置(出生点),该位置不能为0.根据关卡数据自行指定
intiControlStartX=0,iControlStartY=0;
//根据当前关卡,选择关卡数据
switch(m_iCurLevel)
{
case2:
{
iControlStartX=5;
iControlStartY=9;
memcpy(m_iGridData,m_iLevelData2,sizeof(int)*GRID_COUNT*GRID_COUNT);
}
break;
case3:
{
iControlStartX=3;
iControlStartY=6;
memcpy(m_iGridData,m_iLevelData3,sizeof(int)*GRID_COUNT*GRID_COUNT);
}
break;
//如果要新增关卡,在此处增加case即可
//case...
//Level1或者g_iCurLevel错误
case1:
default:
{
iControlStartX=5;
iControlStartY=6;
memcpy(m_iGridData,m_iLevelData1,sizeof(int)*GRID_COUNT*GRID_COUNT);
}
break;
};
memcpy函数作用是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。
因为二维数组在内存中的存放方式是连续的,因此我们将源地址拷贝给m_iGridData的起始地址之后,系统后自动根据m_iGridData的下标来找到正确的值。
至此,本实验结束。
实验三初始化游戏精灵
【实验内容】
步骤一、创建精灵
步骤二、初始化精灵位置
【实验思路】
遍历二维数组m_iGridData,根据数组值生成对应的精灵实例:
值为0的时候不用创建,需要创建的精灵名字前缀为(按照宏定义的1,2,3顺序):
RigidBlock,BlackHole,GolfExit。
每创建一种精灵,将其总数加1:
m_iRigidBlockCount,m_iBlackHoleCount,m_iGolfExitCount。
【实验指导】
1、进入LessonX.h,CGameMain类中添加下面成员变量的声明:
CSprite*m_pControlBall;//控制球精灵
CSprite*m_pGolfArrow;//指示箭头精灵
在LessonX.cpp中CGameMain类在构造函数里面添加上面成员变量的初始化:
m_pControlBall=newCSprite("ControlBall");
m_pGolfArrow=newCSprite("GolfArrow");
2、创建精灵之后需要将精灵移到特定位置,因此我们需要定义一个自定义的函数MoveSpriteToBlock来实现这个功能。
1)进入LessonX.h中添加该函数的声明:
voidMoveSpriteToBlock(CSprite*tmpSprite,constintiIndexX,constintiIndexY);
2)在LessonX.cpp最后面添加该函数的定义:
voidCGameMain:
:
MoveSpriteToBlock(CSprite*tmpSprite,constintiIndexX,constintiIndexY)
{
}
3)传入该函数的是精灵实体以及x,y坐标参数。
再通过SetSpritePosition函数设置精灵位置,在该函数里面添加如下代码:
floatfPosX=m_fGridStartX+iIndexX*m_fGridSize;
floatfPosY=m_fGridStartY+iIndexY*m_fGridSize;
tmpSprite->SetSpritePosition(fPosX,fPosY);
3、这里定义在GameInit函数中来创建控制球、方块精灵、出口精灵和黑洞精灵。
通过一个函数来实现CreateAllSprite()。
原理是通过两个for循环来,判断m_iGridData的值,如果为0,则不创建,如果为RIGID_BLOCK则创建一个方块精灵,为BLACK_HOLE则创建一个黑洞精灵,为GOLF_EXIT则创建一个出口精灵。
由于我们预先在地图中摆放了三个模板精灵,因此只需要使用CloneSprite函数即可创建新的精灵。
然后再调用MoveSpriteToBlock函数将精灵移动到指定位置。
最后每创建一个实现精灵,将它添加到相应的精灵向量数组中。
、
1)进入LessonX.h文件的CGameMain类中添加该函数的声明:
voidCreateAllSprite();
2)在LessonX.cpp最后面添加该函数的定义:
voidCGameMain:
:
CreateAllSprite()
{
}
3)在定义汗的函数中添加变量声明:
intiLoopX=0,iLoopY=0;
CSprite*tmpSprite;
char*szName=NULL;
4)实现两个for循环:
for(iLoopY=0;iLoopY{
for(intiLoopX=0;iLoopX{
}
}
5)在里面的循环添加判断代码:
如果是0,则不创建精灵,continue表示跳出本次循环,继续下一个循环。
if(0==m_iGridData[iLoopY][iLoopX])
continue;
如果是方块,则创建方块精灵:
if(RIGID_BLOCK==m_iGridData[iLoopY][iLoopX])
{
szName=CSystem:
:
MakeSpriteName("RigidBlock",m_iRigidBlockCount);
tmpSprite=newCSprite(szName);
tmpSprite->CloneSprite("RigidBlockTemplate");
MoveSpriteToBlock(tmpSprite,iLoopX,iLoopY);
m_vRigidBlock.push_back(tmpSprite);
m_iRigidBlockCount++;
}
如果是黑洞,则创建黑洞精灵:
elseif(BLACK_HOLE==m_iGridData[iLoopY][iLoopX])
{
szName=CSystem:
:
MakeSpriteName("BlackHole",m_iBlackHoleCount);
tmpSprite=newCSprite(szName);
tmpSprite->CloneSprite("BlackHoleTemplate");
MoveSpriteToBlock(tmpSprite,iLoopX,iLoopY);
m_vBlackHole.push_back(tmpSprite);
m_iBlackHoleCount++;
}
如果是出口,则创建出口精灵:
elseif(GOLF_EXIT==m_iGridData[iLoopY][iLoopX])
{
szName=CSystem:
:
MakeSpriteName("GolfExit",m_iGolfExitCount);
tmpSprite=