课程设计坦克大战样本.docx

上传人:b****8 文档编号:10158624 上传时间:2023-02-08 格式:DOCX 页数:47 大小:527KB
下载 相关 举报
课程设计坦克大战样本.docx_第1页
第1页 / 共47页
课程设计坦克大战样本.docx_第2页
第2页 / 共47页
课程设计坦克大战样本.docx_第3页
第3页 / 共47页
课程设计坦克大战样本.docx_第4页
第4页 / 共47页
课程设计坦克大战样本.docx_第5页
第5页 / 共47页
点击查看更多>>
下载资源
资源描述

课程设计坦克大战样本.docx

《课程设计坦克大战样本.docx》由会员分享,可在线阅读,更多相关《课程设计坦克大战样本.docx(47页珍藏版)》请在冰豆网上搜索。

课程设计坦克大战样本.docx

课程设计坦克大战样本

课程设计一坦克大战

一、游戏简介

相信大某些同窗都玩过或看过“坦克大战”这款典型游戏。

当前,就由咱们自己动手来开发它。

只要人们具备了C++语言和面向对象基本知识,然后按照实验指南指引一步一步进行下去,相信咱们每个同窗都能把这款典型游戏做出来。

二、实验目的

综合运用C++及其面向对象知识开发一款小游戏。

三、实验内容

在一种战场上,玩家控制坦克,消灭敌方坦克,并防止敌方坦克摧毁我方基地。

游戏详细规定如下:

1、游戏有一种初始页面,如下图。

屏幕上最内部黑色区域为玩家坦克活动区域,左上角坐标为(-26,-22),右下角坐标为(26,22)。

当坦克运动到该区域边界时,坦克不能继续迈进。

2、按下任意键开始游戏,玩家控制坦克在战场上穿梭,遇到墙时,不能通过。

3、敌方坦克自由移动,每隔2秒变化一种方向,每隔3秒发射一发子弹。

4、敌方坦克每隔5秒浮现一辆,从屏幕上方左、中、右三个位置依次浮现。

5、当玩家被消灭或者我方基地被摧毁或者游戏时间不不大于30秒时候,游戏结束。

游戏开始前

进入游戏

四、游戏整体框架

 

五、实验指南

实验准备

打开FunCode,创立一种新C++项目。

注意:

项目名称必要为英文和数字,且不能有空格。

点击“项目”→“导入地图模板”,从对话框中选用名称为TankWar模板导入。

导入成功后,界面如下:

实验一游戏开始

【实验内容】

1、设立游戏标题

2、按空格键,提示图片消失,游戏进入开始状态.

【实验运营成果】

游戏开始前

按下空格键后

【实验思路】

要解决FunCode中图片,咱们需要声明CSprite类型对象来指向相应图片,然后调用精灵类相应函数进行解决。

按下空格键是键盘按下事件,系统调用CSystem:

:

OnKeyDown函数进行响应。

该函数中调用CGameMain:

:

OnKeyDown函数。

因而咱们可以在CGameMain类OnKeyDown函数完毕相应代码。

按下键盘后,需要变化游戏状态,游戏从未开始进入开始状态。

成员变量m_iGameState用来表达游戏状态。

【实验指引】

1、C++程序执行入口是主函数。

FunCode主函数名称叫WinMain,写在Main.cpp文献中。

CSystem:

:

SetWindowTitle是设立程序运营窗口标题函数,修改如下:

CSystem:

:

SetWindowTitle("坦克大战");

2、FunCode程序运营时,当发生键盘按下事件,程序一方面调用并执行CSystem:

:

OnKeyDown函数,然后由CSystem:

:

OnKeyDown函数调用并执行CGameMain:

:

OnKeyDown函数。

因而,键盘按下事件响应代码咱们在CGameMain:

:

OnKeyDown函数中编写即可。

3、咱们要解决两个精灵如下图,它们名称分别是splash和start。

咱们需要创立两个CSprite类对象与这两个精灵绑定。

4、在CGameMain类中声明两个CSprite*类型,依照面向对象封装性原理,成员变量访问权限应当是private。

代码应当写LessonX.h文献中。

CSprite*m_pSplash;

CSprite*m_pStart;

在CGameMain类构造函数中,对上面两个指针变量进行初始化。

通过调用CSprite构造函数,将精灵和精力对象绑定在一起。

m_pSplash=newCSprite("splash");

m_pStart=newCSprite("start");

5、最后,咱们在CGameMain:

:

OnKeyDown函数中解决空格键按下事件。

if(0==GetGameState())

{

if(iKey==KEY_SPACE)

{

m_iGameState=1;

}

}

KEY_SPACE是枚举变量KeyCodes成员,表达空格键。

KeyCodes定义在CommonClass.h文献中。

该枚举变量定义了所有键盘值。

注意:

必要将m_iGameState值改为1。

当GameMainLoop函数再次执行时,依照m_iGameState值调用并执行GameInit函数,游戏进入开始状态。

进入游戏开始状态时,调用CSprite类SetSpriteVisible函数将精灵图片设立为不可见。

在GameInit函数中添加代码:

m_pSplash->SetSpriteVisible(false);

m_pStart->SetSpriteVisible(false);

6、程序执行完CGameMain:

:

GameInit函数后,执行CGameMain:

SetGameState

(2),将m_iGameState值改为2,游戏进入运营状态。

7、在CGameMain类析构函数中delete本实验创立指针对象,以释放分派内存。

CGameMain:

:

~CGameMain()

{

deletem_pSplash;

deletem_pStart;

}

8、编译并运营程序,然后按下空格键,看看运营效果。

实验二坦克运动

【实验内容】

1、创立坦克类CTankPlayer;

2、游戏开始时,将坦克放置于(0,0)坐标上;

3、通过按键WSAD控制坦克上下左右运动;

4、坦克运营到黑色区域边界时不能继续迈进。

【实验运营成果】

在区域内运动

运动到区域边界

【实验思路】

坦克也是精灵,但是它具备某些自己独特功能,例如通过键盘控制运动、开炮等。

因而咱们可以创立一种新类CTankPlayer类,并让它继承CSprite类。

通过WASD键,控制坦克做相应上左下右运动。

按下某个键,给坦克设立相应方向运动速度;松开时,将该方向速度设为0,表达停止运动。

屏幕上最内部黑色区域为玩家坦克活动区域,左上角坐标为(-26,-22),右下角坐标为(26,22)。

当坦克运动到该区域边界时,坦克不能继续迈进。

【实验指引】

1、通过类向导创立CTankPlayer类,其继承于CSprite类。

以VC++6.0为例:

第一步、点击菜单“插入”-〉“新建类”。

第二步、在“NewClass”对话框中输入类名和父类名。

第三步、点击“Change”按钮,在新对话框中修改CTankPlayer类头文献和cpp文献途径。

将头文献保存到项目文献夹\SourceCode\Header文献夹中,将cpp文献保存到项目文献夹下\SourceCode\Src文献夹中。

这里需要特别注意是创立文献途径问题,所有.h头文献应当在项目文献夹\SourceCode\Header中,所有.cpp源文献应当放在项目文献夹下\SourceCode\Src文献夹中。

这样咱们在#include时候只需要写文献名就可以了。

如果保存到其她途径下,需要写相对途径。

2、点击OK,浮现下面提示,不用管它,点击“拟定”。

3、这是由于,咱们创立类集成了CSprite类,但是却没有把这个类声明文献include进来。

因而咱们在新建类头文献中,做如下操作:

#include"CommonClass.h"

4、编译程序,发现如下提示:

打开CommonClass.h文献,找到CSprite类定义,可以发现该类没有缺省构造函数,只有一种带参数构造函数。

因而,作为它子类,构造函数也必要带参数,并且将参数传递给父类。

构造函数声明和定义修改如下:

CTankPlayer(constchar*szName);

CTankPlayer:

:

CTankPlayer(constchar*szName):

CSprite(szName)

{

}

5、为CTankPlayer类添加m_iDir,m_fSpeedX,m_fSpeedY,m_iHp四个成员变量(成员变

量。

用来表达坦克在X轴和Y轴方向上速度以及运营方向,并且在构造函数中初始化为0。

这里规定,m_iDir值为0、1、2、3,分别表达上、右、下、左。

成员函数声明和定义如何添加,访问权限是什么,可参照实验一,下文不再继续提示),分别表达运动方向、X轴、Y轴速度以及血量值。

本文档命名采用匈牙利命名法,m_表达类成员变量,i表达整型,f表达float型,sz表达字符指针,g_表达全局变量等。

同步需要在public权限下定义获取和设立这些变量Get和Set办法,可在LessonX.h文献中完毕:

//set办法

voidSetHp(inthp){m_iHp=hp;}

voidSetDir(intdir){m_iDir=dir;}

voidSetSpeedX(floatspeedX){m_fSpeedX=speedX;}

voidSetSpeedY(floatspeedY){m_fSpeedY=speedY;}

//get办法

intGetHp(){returnm_iHp;}

intGetDir(){returnm_iDir;}

floatGetSpeedX(){returnm_fSpeedX;}

floatGetSpeedY(){returnm_fSpeedY;}

6、在CTankPlayer类构造函数完毕上面四个成员变量初始化。

CTankPlayer:

:

CTankPlayer(constchar*szName):

CSprite(szName)//对构造函数进行实现

{

m_iDir=0;

m_fSpeedX=0.f;

m_fSpeedY=0.f;

m_iHp=2;

}

子类对象创立时,要先调用父类构造函数完毕父类某些构造。

如果父类没有默认构造函数,子类构造函数必要显示调用父类构造函数。

CTankPlayer构造函数调用CSprite类构造函数,并将参数szName值传递给它,从而将名称为szName精灵图片与CTankPlayer对象绑定起来。

7、为CTankPlayer类添加Init函数,该函数重要用来完毕该类初始化工作。

这里,先调用setHp办法设立血量。

然后调用父类SetSpritePosition函数将坦克精灵设立在屏幕中央(0,0)处。

接下来给坦克精灵设立时间边界大小,与世界边界碰撞模式为WORLD_LIMIT_NULL,表达精灵与世界边界碰撞响应由代码完毕,同步设立坦克碰撞模式为发送碰撞和接受碰撞。

voidCTankPlayer:

:

Init()

{

SetHp

(2);

SetSpritePosition(0.f,0.f);

SetSpriteWorldLimit(WORLD_LIMIT_NULL,-26,-22,26,22);

SetSpriteCollisionActive(1,1);//设立为可以接受和发生碰撞

SetSpriteVisible(true);

}

8、完毕CTankPlayer类有关定义后,在CGameMain类中增长一种私有成员变量m_pTankplayer,类型为CTankPlayer*。

注旨在LessonX.h添加头文献:

#include"TankPlayer.h"

9、按下空格键后,程序会调用键盘按下事件响应函数,将m_iGameState值改为1,游戏进入开始状态(见实验一)。

程序再次执行CGameMain:

:

GameMainLoop函数时,依照m_iGameState值调用并执行CGameMain:

:

GameInit函数。

因而,可以在该函数中创立我方坦克,并调用CTankPlayer:

:

Init函数来完毕该类对象初始化工作。

m_pTankPlayer=newCTankPlayer("myPlayer");//新建一种名字是myPlayer我方坦克对象

m_pTankPlayer->CloneSprite("player");//我方坦克克隆在funcode模板中存在名字为player坦克,表达新建坦克对象有当前精灵所有属性

m_pTankPlayer->Init();

10、接下来,咱们为CTankPlayer类添加OnMove函数,参数iKey、bPress分别表达按下是哪个按键和按键与否按下。

一方面声明该函数,访问权限为public:

voidOnMove(intiKey,boolbPress);

11、接着,完毕OnMove办法。

voidCTankPlayer:

:

OnMove(intiKey,boolbPress)

{

if(bPress)

{

switch(iKey)

{

caseKEY_W:

SetDir(0);

SetSpeedX(0);

SetSpeedY(-8);

break;

caseKEY_D:

SetDir

(1);

SetSpeedX(8);

SetSpeedY(0);

break;

caseKEY_S:

SetDir

(2);

SetSpeedX(0);

SetSpeedY(8);

break;

caseKEY_A:

SetDir(3);

SetSpeedX(-8);

SetSpeedY(0);

break;

}

SetSpriteRotation(float(90*GetDir()));//用方向值乘于90得到精灵旋转度数

SetSpriteLinearVelocity(GetSpeedX(),GetSpeedY());

}

else

{

if(iKey==KEY_W||iKey==KEY_D||iKey==KEY_S||iKey==KEY_A)

{

SetSpeedX(0);

SetSpeedY(0);

SetSpriteLinearVelocity(GetSpeedX(),GetSpeedY());

}

}

}

用参数bPress来判断键盘是按下还是弹起。

如果bPress为false,表达键盘弹起,且弹起键是WASD键时,设立坦克X轴和Y轴移动速度都为0。

如果bPress为true,表达键盘按下,依照按下键,为m_iDir,m_fSpeedX,m_fSpeedY赋予相应值。

SetSpriteRotation和SetSpriteLinearVelocity函数用来设立精灵角度和线性速度,详细含义参照CommonClass.h文献。

12、在CGameMain类OnKeyDown函数中,通过调用CTankPlayer类OnMove办法,依照按下键,控制坦克朝指定方向运动。

只有游戏进入开始状态,按键才有效。

注意:

OnMove参数bPress值为true。

在OnKeyDown函数中添加代码如下:

if(m_iGameState==2)

{

m_pTankPlayer->OnMove(iKey,true);

}

13、编译并运营程序。

按空格键开始,按WASD键,坦克会向规定方向运动。

但是松开按键后,坦克继续迈进,不会停止下来。

14、在CGameMain:

:

OnKeyUp函数中调用CTankPlayerOnMove办法,参数bPress值为false。

voidCGameMain:

:

OnKeyUp(constintiKey)

{

if(m_iGameState==2)

{

m_pTankPlayer->OnMove(iKey,false);

}

}

15、编译并运营程序,按下WASD键,坦克运营;松开按键,坦克停止。

接下来,咱们来实现坦克运营到黑色区域边界停止运动效果。

16、当坦克精灵遇到边界时,将精灵速度都设为0,精灵停止运动。

一方面,咱们需要给该精灵设立世界边界碰撞模式。

可以在CTankPlayer:

:

GameInit()中完毕。

17、用字符串解决函数strstr()来判断遇到世界边界精灵与否为我方坦克。

当遇到世界边界精灵名字中具有”player”时候,strstr会返回一种非空值。

因而代码如下:

voidCGameMain:

:

OnSpriteColWorldLimit(constchar*szName,constintiColSide)

{

if(strstr(szName,"myPlayer")!

=NULL)//判断遇到世界边界坦克与否为我方坦克

{

m_pTankPlayer->SetSpriteLinearVelocity(0,0);

}

}

实验三坦克开炮

【实验内容】

1、创立子弹类CBullet;

2、通过按键J控制坦克开炮;

【实验运营成果】

【实验思路】

创立子弹类,该类应具备子弹运动方向、起始位置、X轴速度、Y轴速度等属性,其中运动方向和起始位置由坦克方向和位置决定。

通过按键控制坦克发射子弹,因而在CGameMain类OnKeyDown办法中实现该需求。

此时咱们为CTankPlayer类添加发射子弹办法OnFire。

当按下J键后,坦克发射子弹,在OnFire办法中,咱们需要告诉子弹方向和初始位置。

而创立子弹咱们由CGameMain类来完毕。

这样减少了类之间耦合。

【实验指引】

1、通过类向导创立CBullet类,其继承于CSprite类,详细做法参照实验一;

2、为CBullet类添加m_iDir,m_fSpeedX,m_fSpeedY,m_iHp,m_iOwner五个成员,分别表达方向、X轴、Y轴速度、子弹血量以及发射子弹归属坦克,0表达地方坦克,1表达我方坦克,并参照实验二添加变量get和set办法。

3、为CBullet类添加构造函数和析构函数。

参照实验二,把构造函数中将所有变量进行初始化。

4、为CBullet类添加OnMove办法,参数为iDir表达子弹运动方向。

5、完毕OnMove办法。

依照方向m_iDir,一方面设立m_fSpeedX,m_fSpeedY值,然后设立依照方向设立旋转角度,最后设立子弹运动速度。

voidCBullet:

:

OnMove(intiDir)

{

SetDir(iDir);

switch(GetDir())

{

case0:

SetSpeedX(0);

SetSpeedY(-10);

break;

case1:

SetSpeedX(10);

SetSpeedY(0);

break;

case2:

SetSpeedX(0);

SetSpeedY(10);

break;

case3:

SetSpeedX(-10);

SetSpeedY(0);

break;

}

SetSpriteRotation(90*GetDir());

SetSpriteLinearVelocity(GetSpeedX(),GetSpeedY());

}

6、在CGameMain类中添加表达子弹数目成员变量m_iBulletNum(注意初始化为0)。

然后添加AddBullet办法。

办法中有iDir、fPosX、fPosY、iOwner四个参数分别表达子弹方向、子弹初始位置X轴Y轴坐标以及子弹所属坦克。

由于地图上只有一种子弹模板,因此咱们需要先复制这个模板,然后设立该精灵世界边界。

voidCGameMain:

:

AddBullet(intiDir,floatfPosX,floatfPosY,intiOwner)

{

char*szName=CSystem:

:

MakeSpriteName("bullet",m_iBulletNum);//创立坦克名字

CBullet*pBullet=newCBullet(szName);

pBullet->CloneSprite("bullet");

pBullet->SetSpriteWorldLimit(WORLD_LIMIT_NULL,-26,-22,26,22);//设立世界边界

pBullet->SetSpritePosition(fPosX,fPosY);

pBullet->SetSpriteCollisionSend(true);//设立接受碰撞

pBullet->OnMove(iDir);

m_iBulletNum++;//子弹个数加1

if(iOwner==1)

{

pBullet->SetOwner

(1);//1表达我方坦克发射子弹

}

else

{

pBullet->SetOwner(0);//0表达地方坦克发射子弹

}

}

注意:

这里用到了CBullet类型,因而需要include相应头文献。

7、为CTankPlayer类增长OnFire办法,实现发射子弹功能。

在依照坦克运动状态,得到子弹有关属性后,通过AddBullet办法在游戏中增长一发子弹。

voidCTankPlayer:

:

OnFire()

{

floatx,y;

x=GetSpritePositionX();

y=GetSpritePositionY();

switch(GetDir())

{

case0:

y=y-GetSpriteHeight()/2-1;

break;

case1:

x=x+GetSpriteWidth()/2+1;

break;

case2:

y=y+GetSpriteHeight()/2+1;

break;

case3:

x=x-GetSpriteWidth()/2-1;

break;

}

g_GameMain.AddBullet(GetDir(),x,y,1);

}

由于用到g_GameMain这个全局对象,因此需要在CTankPlayer.cpp中声明头文献:

#include”LessonX.h”

8、按J键发射子弹。

在CGameMain类OnKeyDown函数if(m_iGameState==2)下添加if(iKey==KEY_J)//判断按下键是够为J键

{

m_pTankPlayer->OnFire();

}

实验四敌方坦克

【实验内容】

1、创立CTankEnemy类;

2、创立一种敌方坦克实例,实现坦克从上方左中右三个位置随机浮现。

3、实现坦克隔2秒,随机变化一种方向。

4、实现坦克隔5秒发射一发子弹;

5、当坦克与世界边界碰撞时,变化方向;

【实验运营成果】

【实验思路】

同我方坦克同样,敌方坦克运动,也需要有运动方向、X轴Y轴速度三个基本属性。

为了实现坦克能自由运动,即坦克运动一段时间后变化方向,需增长一种变化方向时间间隔。

同步为了实现坦克自动发射子弹,需增长一种发射子弹时间间隔。

然后为敌方坦克增长移动和发射子弹办

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 企业管理

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1