坦克大战游戏程序课程设计

坦克大战游戏程序课程设计
坦克大战游戏程序课程设计

《程序设计应用基础》课程设计计划书

坦克大战游戏

1引言

学习了C语言程序设计之后,我们粗略的掌握了程序设计的基本思路和要求,为了更加熟练的掌握这门计算机语言,我们选择编译一个经典小游戏——坦克大战。通过课程设计提高我们的动手能力,把理论知识运用到实践当中。在课程设计中,C语言的语法和逻辑严谨,对于初学者而言,有时忘记一个逗号或者分号整个程序便运行不了,经过了反复的调试,修改,最终形成可执行的程序。在这个过程中,通过不断的练习,我们对C语言的掌握程度有明显的提高,同时,也锻炼了我们的头脑,使我们的思维更加科学严谨。

2设计方案

2.1设计思路

坦克大战游戏,一共两关。不同的关卡,游戏地图、敌方坦克出现的种类不一样。敌方坦克地图上最多存在4辆,击杀后会出现新坦克直至补足4个,当击杀坦克一定数值则敌方新坦克不会再增加。击杀完所有坦克则胜利过关。己方坦克也有复活次数,用完则失败。另地图正下方有己方老家,若被敌方坦克攻破则游戏失败。

3程序设计与实施

3.1程序的主要模块

整个程序分为里表两大部分。

里部分由41*41的int地图数组组成,每个元素代表了该以该数组元素行列下标为地图坐标y,x那个单元的情况,不同的地图障碍物在该数组有不同的值,坦克在地图上占3*3个单元,在地图数组内相应坐标的3*3个元素内也对应特殊的值。由地图数组值可以读出该坦克信息。

表部分则是根据里部分的地图数组通过gotoxy和printf函数在命令行界面打印出相应字符以构成游戏界面的。

程序中的每个函数操作都是通过里部分(地图数组)判定,然后对里部分(地图数组)操作,再由里部改变外部,由gotoxy和printf函数将可视化界面呈现给玩家。也就是游戏主体函数内里表部分是一起操作的,不分开。

对于函数分类,程序又可分为三大类。一类游戏辅助函数。一个子弹系统,一个坦克系统。子弹和坦克分别都是独立运作的系统,有少量信息交换。

3.2 主函数及其流程图

主函数包括打印地图,实现游戏内置调节游戏速度的功能,判断坦克类型,判断敌我坦克是否存活,判断游戏胜负。

3

3.3其余各个功能函数

子弹系统

子弹在地图数组内没有值,但每颗子弹记录了子弹坐标(对应地图数组的坐标),子弹发射者等信息,由子弹坐标对应地图数组坐标中的数组值判定子弹碰撞障碍物或判定击中坦克等,再产生不同的响应。

子弹结构体为长度20的数组,一个元素代表一颗子弹。坦克部分发射子弹函数执行,则按顺序激活一颗子弹(改变子弹的一个标记),若激活的子弹为子弹数组[19]。则下一个激活[0],并改变给子弹的其他值。子弹击中物体后既被灭活(改变标记)。

子弹移动函数只执行被激活的所有子弹,执行子弹移动,碰撞判断与碰撞事件等。也就是说,子弹一被建立就是自己“飞”了,相当于将子弹交给了移动函数执行。两个部分有类似面向对象的概念。

坦克系统:

我方坦克样式:被子弹击中则死亡,颜色天蓝色,速度为子弹速度的1/2

敌方坦克分三种:

普通坦克:被子弹击中则死亡,颜色随机产生, 速度为子弹速度的1/3

血量较高的坦克:初始为绿色,被子弹击中一次变黄,其次变红,再次被击中则坦克死亡。速度为子弹速度1/3

速度较快的坦克:被子弹击中则死亡,颜色随机,速度为子弹速度的1/2

每次坦克移动先抹去地图数组中3*3个元素的值并抹去显示的坦克图案,再由传入的移动方向在下一个3*3方格内重新给地图数组赋值并在界面打印图案。坦克碰撞由读取坦克前方1*3的地图数组值完成。

AI部分:

AI坦克移动:

一定几率执行方向重置(转向或不变),后原地停止一定时间。(大部分时间还是会直线移动),遇到障碍一定几率选择出有通路的方向,一定几率方向重置(乱转),乱转后原地停止一定时间。之所以设置方向重置是因为地图原因,AI需要偶尔往一个方向发射子弹打碎砖块以开辟新通路,也为玩家的预判增加不确定性,增加游戏难度。让AI坦克停止为了凑足子弹冷却时间,让AI坦克向此方向发射子弹。

AI子弹发射:

一般情况下CD(冷却时间)超过一定数值则一定几率发射子弹(若随机判断为不执行,则下一次循环依然再执行随机判断,此时CD一直不变),一旦发射,CD重新计时。若敌方坦克通过它的坦克方向正好能击中我的坦克且CD达到一定值(比一般情况下的值要小),则立即发射子弹。由于地图原因,敌方99%的可能都会从最下一行的通道发射子弹攻破老家。所以当敌方坦克处于最下一行并且坦克方向朝向老家,也如上CD达到一定值后直接发射子弹。AI发射稍强化了AI以调节游戏平衡。

地图部分:地图边界为子弹击中则子弹消失的方块。地图内的障碍物分四种,两种不同颜色的▓(砖块),子弹击中则消除与子弹移动方向垂直线上的三个方块(若子弹为纵向则消除子弹击中处、子弹击中处相邻左右共三个方块),若左/右方块不为▓(为其他障碍或没有障碍)则不处理。

实现游戏内置调节游戏速度的功能:如死循环中固定每次循环Sleep(5); 于是添加判断interval[0]++%speed==0,为真则执行真正循环体。当speed为1则每次循环都会执行

5

所有真正循环体中的操作,相当于每次循环间隔5ms。speed为3则3次循环执行一次,相当于每次循环间隔15ms,达到游戏速度的微调目的。

而体现出子弹和坦克间的速度差也是同理。子弹中添加计数器,每次执行上述真正循环体时自增,当计数器为某数的倍数则执行子弹移动。坦克移动函数也有计数器每次自增,当计数器为某数的倍数则执行坦克移动。

而该程序由于子弹已经为最小单位的时间,即每次循环都执行,于是没必要设置计数器。而坦克的interval++%2==0判断则是上面描述的实现,于是子弹速度为该坦克速度的两倍。既每次循环都会执行一次子弹移动,而需要两次循环才会执行一次坦克移动,就体现了速度差,也省去了多线程。

4设计结果与分析

游戏分里外两个部分组成,里部分(用户不可见) 通过里部分执行判断,地图数组更改,和各种值的改变。更改完里部分再根据相应变化更改表部分。(用户可视部分)表部分的打印通过gotoxy去到相应坐标再printf打印出字符,通过文本函数改变文字字体颜色与文字背景颜色与字符组合实现图形界面。

7

程序通过计数器+循环判断的思想,类似单核cpu的多线程实现(单线程在不同程序/函数间来回执行)省去了多线程。(具体过程在“3.3其余各个功能函数”中有描述)

另AI实现与加强依赖于rand随机函数的运用,进一步强化AI,增加游戏乐趣

功能方面,游戏参考于80年代任天堂红白机(FC/FamilyComputer)上的游戏坦克大战(Battle City),包括地图,游戏模式等等(当时的游戏直接烧在电路板上)。所以游戏平衡方面已经有了很好的参考,无需再花大量时间测试平衡性。

但诸如地图中的树林元素,随机道具等没有实现。但较之原版,该游戏由C语言编写PC运行,由字符界面实现游戏画面。原版一辆坦克的子弹未消失之前不能发射第二颗。导致子弹打击远处CD长,近处CD短。该游戏每个子弹都有相同CD,子弹未消失只要CD达到即可发射第二颗,第三颗…增加了真实性,相较于原版是个改进。且考虑到PC性能不一内置了游戏速度调整。玩家可根据PC性能调整至合适的速度。

5源程序

#include

#include

#include

//里规格:长39*2=78 (真坐标)(假坐标宽为39) 高39

//外规格:长41*2=82 (真坐标)(假坐标宽为41) 高41 #define UP 1

#define DOWN 2

#define LEFT 3

#define RIGHT 4

#define MAX_LEVEL 8

#define BULLET_NUM 20

#define MAX_LIFE 4

//程序中未写入函数参数表中且未说明的变量只有map二维数组,level_info数组和level

/*

此程序中涉及的x,y类的坐标值,分为以下两种:

假坐标:这里的坐标指的是以一个■长度为单位的坐标,而不是真正的coord坐标(用于map数组的坐标)

真坐标:头文件自带的坐标结构coord中的坐标(也可以说是控制台里的真正坐标值)

区别:纵坐标y两值一致,假横坐标x值与真正coord横坐标(真坐标)关系是x * 2 = coord 横坐标

coord横坐标既指GoTo函数中的x参数,因为本程序游戏界面以一个■长度为基本单位,

可以说涉及的coord横坐标全是偶数。既假坐标要变真坐标(变真坐标才能发挥真正作用),横坐标须乘以2

*/

typedef struct //这里的出现次序指的是一个AI_tank变量中的次序,游戏共有四个AI_tank变量

{ //∵设定每个AI_tank每种特殊坦克只出现一次∴fast_tank & firm_tank 最多出现次数不超过1

int fast_tank_order; //fast_tank出现的次序(在第fast_tank_order次复活出现,从第0次开始),且每个AI_tank只出现一次

int firm_tank_order; //firm_tank出现的次序,同上

} LevInfo; //关卡信息(准确说是该关出现的坦克信息)

LevInfo level_info [MAX_LEVEL] = {{-1,-1},{3,-1},{-1,3},{2,3},{2,3},{2,3},{2,3},{2,3}}; //初始化,-1代表没有该类型坦克

typedef struct //子弹结构体

{

int x,y; //子弹坐标,假坐标

int direction; //子弹方向变量

bool exist; //子弹存在与否的变量,1为存在,0不存在

bool initial; //子弹是否处于建立初状态的值,1为处于建立初状态,0为处于非建立初状态

bool my; //区分AI子弹与玩家子弹的标记,0为AI子弹,1为玩家(我的)子弹} Bullet;

Bullet bullet [BULLET_NUM]; //考虑到地图上不太可能同时存在20颗子弹,所以数组元素设置20个

typedef struct //坦克结构体

{

int x,y; //坦克中心坐标

int direction; //坦克方向

int color; //颜色参方向数,1到6分别代表不同颜色,具体在PrintTank函数定义有说明

int model; //坦克图案模型,值为1,2,3,分别代表不同的坦克图案,0为我的坦克图案,AI不能使用

int stop; //只能是AI坦克使用的参数,非0代表坦克停止走动,0为可以走动int revive; //坦克复活次数

int num; //AI坦克编号(固定值,为常量,初始化函数中定下)0~3

int CD; //发射子弹冷却计时

bool my; //是否敌方坦克参数,我的坦克此参数为1,为常量

9

bool alive; //存活为1,不存活为0

} Tank;

Tank AI_tank[4] , my_tank; //my_tank为我的坦克,Ai_tank 代表AI坦克

//∵所有的函数都有可能对全局变量map进行读写(改变),

//∴函数中不另说明是否会对全局变量map读写

//基本操作与游戏辅助函数

void GoToxy(int x,int y); //光标移动

void HideCursor(); //隐藏光标

void keyboard (); //接受键盘输入

void Initialize(); //初始化(含有对多个数据的读写)

void Stop(); //暂停

void Getmap(); //地图数据存放与获取

void Frame (); //打印游戏主体框架

void PrintMap(); //打印地图(地图即地图障碍物)(含对level的读取)

void SideScreen (); //副屏幕打印

void GameCheak(); //检测游戏输赢

void GameOver( bool home ); //游戏结束

void ClearMainScreen(); //主屏幕清屏函数∵system("cls")后打印框架有一定几率造成框架上移一行的错误∴单独编写清屏函数

void ColorChoose(int color); //颜色选择函数

void NextLevel(); //下一关(含有对level全局变量的读写)

//子弹部分

void BuildAIBullet(Tank *tank); //AI坦克发射子弹(含有对my_tank的读取,只读取了my_tank坐标)

void BuildBullet (Tank tank); //子弹发射(建立)(人机共用)(含全局变量bullet的修改)我的坦克发射子弹直接调用该函数,AI通过AIshoot间接调用

void BulletFly (Bullet bullet[BULLET_NUM]); //子弹移动和打击(人机共用),

void BulletHit (Bullet* bullet); //子弹碰撞(人机共用)(含Tank全局变量的修改),只通过BulletFly调用,子弹间的碰撞不在本函数,子弹间碰撞已在BulletShoot中检测并处理

void PrintBullet (int x,int y,int T); //打印子弹(人机共用)

void ClearBullet (int x,int y,int T); //清除子弹(人机共用)

int BulletCheak (int x,int y); //判断子弹前方情况(人机共用)

//坦克部分

void BuildAITank (int* position, Tank* AI_tank); //建立AI坦克

void BuildMyTank (Tank* my_tank); //建立我的坦克

void MoveAITank (Tank* AI_tank); //AI坦克移动

void MoveMyTank (int turn); //我的坦克移动,只通过keyboard函数调用,即键盘控制

void ClearTank (int x,int y); //清除坦克(人机共用)

void PrintTank (Tank tank); //打印坦克(人机共用)

bool TankCheak (Tank tank,int direction); //检测坦克dirtection方向的障碍物,返值1阻碍,0 畅通

int AIPositionCheak (int position); //检测AI坦克建立位置是否有障碍物AIPositionCheak

//DWORD WINAPI InputX(LPVOID lpParameter); //声明线程函数,用于检查X键输入并设置X键的输入冷却时间

//注意map数组应是纵坐标在前,横坐标在后,既map[y][x],(∵数组行长度在前,列长度在后)

//map里的值: 个位数的值为地图方块部分,百位数的值为坦克,子弹在map上没有值(子弹仅仅是一个假坐标)

//map里的值: 0为可通过陆地,1为红砖,2黄砖,5为水,100~103为敌方坦克,200为我的坦克,

//全局变量

int map[41][41]; //地图二维数组

int key_x; // X键是否被“读入”的变量,也是子弹是否可以发射的变,

int bul_num; //子弹编号

int position; //位置计数,对应AI坦克生成位置,-1为左位置,0为中间,1为右,2为我的坦克位置

int speed=7; //游戏速度,调整用

int level=1; //游戏关卡数

int score=0; //游戏分数

int remain_enemy; //剩余敌人(未出现的敌人)

char* tank_figure[4][3][4]=

{

{

{"◢┃◣", "◢━◣", "◢┳◣", "◢┳◣"},

{"┣●┫", "┣●┫", "━●┃", "┃●━"},

{"◥━◤", "◥┃◤", "◥┻◤", "◥┻◤"}

},

{

{"┏┃┓", "┏┳┓", "┏┳┓", "┏┳┓"},

{"┣●┫", "┣●┫", "━●┫", "┣●━"},

{"┗┻┛", "┗┃┛", "┗┻┛", "┗┻┛"}

},

{

{"┏┃┓", "◢━◣", "┏┳◣", "◢┳┓"},

{"┣●┫", "┣●┫", "━●┃", "┃●━"},

{"◥━◤", "┗┃┛", "┗┻◤", "◥┻┛"}

},

11

{

{"╔┃╗", "╔╦╗", "╔╦╗", "╔╦╗"},

{"╠█╣", "╠█╣", "━█╣", "╠█━"},

{"╚╩╝", "╚┃╝", "╚╩╝", "╚╩╝"}

}

};

int main () //主函数

{

int i;

unsigned int interval[12]={1,1,1,1,1,1,1,1,1,1,1,1} ; //间隔计数器数组,用于控制速度srand(time(NULL)); //设置随机数种子(若不设置种子而调用rand会使每次运行的随机数序列一致)随机数序列指:如首次调用rand得到1,第二次得2,第三次3,则此次随机数序列为1,2,3

HideCursor(); //隐藏光标

system("mode con cols=112 lines=42"); //控制窗口大小

Frame (); //打印游戏主体框架

Initialize(); //初始化,全局变量level初值便是1

// HANDLE h1 , h2 ; //定义句柄变量

for(;;)

{

if(interval[0]++%speed==0) //速度调整用,假设interval[0]为a, 语句意为a % 2==0,a=a+1;

{

GameCheak(); //游戏胜负检测

BulletFly ( bullet );

for(i=0 ; i<=3 ; i++) //AI坦克移动循环

{

if(AI_tank[i].model==2 && interval[i+1]++%2==0) //四个坦克中的快速坦克单独使用计数器1,2,3,4

MoveAITank( & AI_tank[i]);

if(AI_tank[i].model!=2 && interval[i+5]++%3==0) //四个坦克中的慢速坦克单独使用计数器5,6,7,8

MoveAITank( & AI_tank[i]);

}

for(i=0;i<=3;i++) //建立AI坦克部分if(AI_tank[i].alive==0 && AI_tank[i].revive<4 && interval[9]++%90==0) //一个敌方坦克每局只有4条命

{ //如果坦克不存活。计时,每次建立有间隔1750 ms

BuildAITank( &position, & AI_tank[i] ); //建立AI坦克(复活)

break; //每次循环只建立

一个坦克

}

for(i=0;i<=3;i++)

if(AI_tank[i].alive)

BuildAIBullet(&AI_tank[i]); //AIshoot自带int自增计数CD,不使用main中的CD interval

if(my_tank.alive && interval[10]++%2==0 )

keyboard ();

if(my_tank.alive==0 && interval[11]++%30==0 && my_tank.revive < MAX_LIFE)

BuildMyTank( &my_tank );

}

Sleep(5);

}

return 0;

}

/*//这里的多线程暂时不用//x键用于子弹发射,x键的冷却时间不能和上下左右一同设置,那样就太快了

DWORD WINAPI InputX(LPVOID lpParameter) //如果不用多线程运行,那么在x键冷却时间内程序会因Sleep将会挂起,暂停运行

{ //因为只有一个变量改变,而且变量改变先后顺序是显而易见的,所以不必设置缓冲区

for(;;)

{

if(GetAsyncKeyState( 88 )& 0x8000) //88为x键键值,当摁下x并且x键处于可输入状态

{

key_x=1; // X键是否允许被“读入”的变量,也是子弹是否可以发射的变量

Sleep(600); // 子线程Sleep中,x就不能被"读入",主线程每操作完一次子弹发射,key_x会归零

}

Sleep(10);

}

return 0;

}*/

void keyboard ()

{ // kbhit() getch() 用法可用但是不好用

/*

函数功能:该函数判断在此函数被调用时,某个键是处于UP状态还是处于DOWN状态,及

13

前次调用GetAsyncKeyState函数后,

是否按过此键.如果返回值的最高位被置位,那么该键处于DOWN状态;如果最低位被置位,那么在前一次调用此函数后,此键被按过,

否则表示该键没被按过.

这里GetAsyncKeyState比kbhit() + getch() 好用,操作更顺畅. GetAsyncKeyState的返回值表示两个内容,

一个是最高位bit的值,代表这个键是否被按下。一个是最低位bit的值,代表上次调用GetAsyncKeyState后,这个键是否被按下。

&为与操作,&0x8000就是判断这个返回值的高位字节。如果high-order bit是1,则是按下状态,否则是弹起状态,为0

*/

int count=0;

if (GetAsyncKeyState(VK_UP)& 0x8000)

MoveMyTank( UP );

else if (GetAsyncKeyState(VK_DOWN)& 0x8000)

MoveMyTank( DOWN );

else if (GetAsyncKeyState(VK_LEFT)& 0x8000)

MoveMyTank( LEFT );

else if (GetAsyncKeyState(VK_RIGHT)& 0x8000)

MoveMyTank( RIGHT );

else if (GetAsyncKeyState( 0x1B )& 0x8000) // Esc键

exit(0); //退出程序函数

else if (GetAsyncKeyState( 0x20 )& 0x8000) //空格

Stop();

else if (count++%7==0) //这里添加计数器是为了防止按键粘连不能达到微调效果

{

if (speed>1 && GetAsyncKeyState( 0x6B )& 0x8000) // +键

{

speed--;

GoToxy(102,11); //在副屏幕打印出当前速度

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTE NSITY|FOREGROUND_BLUE|FOREGROUND_RED);

printf("%d ",21-speed); //副屏幕显示的速度为1~10

}

else if (speed<20 && GetAsyncKeyState( 0x6D )& 0x8000) // - 键

{

speed++;

GoToxy(102,11); //在副屏幕打印出当前速度

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTE NSITY|FOREGROUND_BLUE|FOREGROUND_RED);

printf("%d ",21-speed); //副屏幕显示的速度为1~10

}

}

if(my_tank.CD==7)

{

if(GetAsyncKeyState( 88 )& 0x8000)

{

BuildBullet(my_tank);

my_tank.CD=0;

}

}

else

my_tank.CD++;

}

void BuildAIBullet(Tank *tank) //AI子弹发射(建立)含有对my_tank的读取

{

if(tank->CD==15)

{

if(!(rand()%11)) //冷却结束后在随后的每个游戏周期中有10分之一的可能发射子弹

{

BuildBullet(*tank);

tank->CD=0;

}

}

else

tank->CD++;

if(tank->CD >= 14) //AI强化部分,在冷却到达一定范围即可使用

{

if(tank->y==38 ) //如果坦克在底部(这个最优先)

{

if(tank->x < 20) //在老家左边

{

if(tank->direction==RIGHT) //坦克方向朝左

{

BuildBullet(*tank); //发射子弹

tank->CD=0;

}

}

else //在老家右边

if(tank->direction==LEFT) //坦克方向朝右

{

15

BuildBullet(*tank); //发射子弹

tank->CD=0;

}

}

else if(tank->x==my_tank.x+1 || tank->x==my_tank.x || tank->x==my_tank.x-1) //AI 坦克在纵向上"炮口"对准我的坦克

{

if(tank->direction==DOWN && my_tank.y > tank->y || tank->direction==UP && my_tank.y < tank->y)

{ //若是AI朝下并且我的坦克在AI坦克下方(数值大的在下面)或者AI朝上我的坦克在AI上方

int big=my_tank.y , smal=tank->y , i;

if(my_tank.y < tank->y)

{

big=tank->y;

smal=my_tank.y;

}

for(i=smal+2;i<=big-2;i++) //判断AI炮口的直线上两坦克间有无障碍

if(map[i][tank->x]!=0 || map[i][tank->x]!=5) //若有障碍

break;

if(i==big-1) //若i走到big-1说明无障碍

{

BuildBullet(*tank); //则发射子弹

tank->CD=0;

}

}

}

else if(tank->y==my_tank.y+1 || tank->y==my_tank.y || tank->y==my_tank.y-1) //AI坦克在横向上"炮口"对准我的坦克

{

if(tank->direction==RIGHT && my_tank.x > tank->x || tank->direction==LEFT && my_tank.x < tank->x)

{ //若是AI朝右并且我的坦克在AI坦克右方(数值大的在下面)或者AI朝左我的坦克在AI左方

int big=my_tank.y , smal=tank->y , i;

if(my_tank.x < tank->x)

{

big=tank->x;

smal=my_tank.x;

}

for(i=smal+2;i<=big-2;i++) //判断AI炮口的直线上两坦克间有无障碍

if(map[tank->y][i]!=0 || map[tank->y][i]!=5) //若有障碍

break;

if(i==big-1) //若i走到big-1说明无障碍

{

BuildBullet(*tank); //则发射子弹

tank->CD=0;

}

}

}

}

}

void BuildBullet(Tank tank) //子弹发射(建立),传入结构体Tank,这里包含改变了全局变量结构体bullet

{ //∵实现方式为顺序循环建立子弹,每次调用改变的bullet 数组元素都不同

switch(tank.direction) //∴为了方便,不将bullet放入参数,bullet作为全局变量使用

{

case UP :

bullet [bul_num].x = tank.x;

bullet [bul_num].y = tank.y-2;

bullet [bul_num].direction=1;

break;

case DOWN :

bullet [bul_num].x = tank.x;

bullet [bul_num].y = tank.y+2;

bullet [bul_num].direction=2;

break;

case LEFT :

bullet [bul_num].x = tank.x-2;

bullet [bul_num].y = tank.y;

bullet [bul_num].direction=3;

break;

case RIGHT :

bullet [bul_num].x = tank.x+2;

bullet [bul_num].y = tank.y;

bullet [bul_num].direction=4;

break;

}

bullet [bul_num].exist = 1; //子弹被建立,此值为1则此子弹存在

bullet [bul_num].initial = 1; //子弹处于初建立状态

bullet [bul_num].my=tank.my; //如果是我的坦克发射的子弹bullet.my=1,否则为0 bul_num++;

if(bul_num==BULLET_NUM) //如果子弹编号增长到20号,那么重头开始编号bul_num=0; //考虑到地图上不可能同时存在20颗子弹,所以数

17

组元素设置20个

}

void BulletFly(Bullet bullet[BULLET_NUM]) //子弹移动和打击

{ //含有全局变量Bullet的改变for(int i =0; i

{

if(bullet [i].exist) //如果子弹存在

{

if(bullet [i].initial==0) //如果子弹不是初建立的

{

if(map[bullet[i].y] [bullet[i].x]==0 || map[bullet[i].y] [bullet[i].x]==5) //如果子弹坐标当前位置无障碍

ClearBullet( bullet[i].x , bullet[i].y , BulletCheak(bullet[i].x , bullet[i].y )); //抹除子弹图形

switch(bullet [i].direction) //然后子弹坐标变化(子弹变到下一个坐标)

{

case UP :(bullet [i].y)--;break;

case DOWN :(bullet [i].y)++;break;

case LEFT :(bullet [i].x)--;break;

case RIGHT :(bullet [i].x)++;break;

}

}

int collide = BulletCheak ( bullet [i].x , bullet [i].y ); //判断子弹当前位置情况,判断子弹是否碰撞,是否位于水面上。

if( collide ) //如果检测到当前子弹坐标无障碍(无碰撞)(包括在地面上与在水面上)

PrintBullet( bullet[i].x , bullet[i].y , collide); //则打印子弹,若有碰撞则不打印

else

BulletHit( & bullet [i] ); //若有碰撞则执行子弹碰撞函数

if(bullet [i].initial) //若子弹初建立,则把初建立标记去除

bullet [i].initial = 0;

for(int j=0; j< BULLET_NUM ; j++) //子弹间的碰撞判断,若是我方子弹和敌方子弹碰撞则都删除,若为两敌方子弹则无视

if(bullet [j].exist && j!=i && (bullet[i].my || bullet[j].my) && bullet[i].x==bullet[j].x && bullet[i].y==bullet[j].y)

{ //同样的两颗我方子弹不可能产生碰撞

bullet [j].exist=0;

bullet [i].exist=0;

ClearBullet( bullet[j].x , bullet[j].y , BulletCheak(bullet[j].x ,

bullet[j].y )); //抹除j子弹图形,子弹i图形已被抹除

break;

}

}

}

}

void BulletHit(Bullet* bullet) //含有Tank全局变量的修改,子弹间的碰撞不在本函数,子弹间碰撞已在BulletShoot中检测并处理

{ //∵每次打中的坦克都不一样,不可能把所有坦克放在参数表中

int x=bullet->x; //∴这里的Tank使用全局变量

int y=bullet->y; //这里传入的值是子弹坐标,这两个值不需要改变

int i;

if(map[y][x]==1 || map[y][x]==2) //子弹碰到砖块

{

if(bullet->direction==UP || bullet->direction==DOWN) //如果子弹是纵向的for(i = -1 ; i<=1 ; i++)

if(map[y][x+i]==1 || map[y][x+i]==2) //如果子弹打中砖块两旁为砖块,则删除砖,若不是(一旁为坦克或其他地形)则忽略

{

map[y][x+i]=0; //砖块碎

GoToxy(2*x+2*i,y);

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED); //背景黑色

printf(" ");

}

if(bullet->direction==LEFT || bullet->direction==RIGHT) //若子弹是横向的(与子弹纵向实现同理)

for(i = -1 ; i<=1 ; i++)

if(map[y+i][x]==1 || map[y+i][x]==2)

{

map[y+i][x]=0;

GoToxy(2*x,y+i);

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED); //背景黑色

printf(" ");

}

bullet->exist=0; //这颗子弹已经不存在了

}

else if(map[y][x]==4 || map[y][x]==6 ) //子弹碰到边框或者不可摧毁方块

19

bullet->exist=0;

else if(bullet->my && map[y][x]>=100 && map[y][x]<104 ) //若我的子弹碰到了敌方坦克

{

int num = map[y][x]%100; //map[y][x]%100 等同于tank.num ,可通过map值读取该坦克信息

if(AI_tank[num].model==3 && AI_tank[num].color==2) //若为firm tank,且color==2。该坦克为绿色,表明没有受到伤害

AI_tank[num].color=3; //则变成黄色,color=3为黄色

else if (AI_tank[num].model==3 && AI_tank[num].color==3)

AI_tank[num].color=4; //4为红色else //其他类型的坦克或者firm tank为红色的情况

{

AI_tank[num].alive=0;

ClearTank(AI_tank[num].x , AI_tank[num].y); //清除该坦克

}

bullet->exist=0;

score+=100;

GoToxy(102,5); //在副屏幕上打印出分数

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTE NSITY|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);

printf("%d ",score);

}

else if(map[y][x]==200 && bullet->my==0 ) //若敌方子弹击中我的坦克

{

my_tank.alive=0;

ClearTank(my_tank.x , my_tank.y);

bullet->exist=0;

my_tank.revive++; //我的坦克复活次数+1(∵我的坦克复活次数与生命值有关∴放在这里自减)

score-=100; //分数减少

GoToxy(102,5); //在副屏幕上打印出分数

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTE NSITY|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);

printf("%d ",score);

GoToxy(102,7); //在副屏幕打印出我的剩余生命值

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTE NSITY|FOREGROUND_GREEN);

printf("%d ", MAX_LIFE-my_tank.revive);

}

// else if(bullet->my==0 && map[y][x]>=100 && map[y][x]<104) //敌方子弹击中敌方坦克,可以设置两种子弹运行方式,这种暂时不用

// bullet->exist=0;

else if(map[y][x]==9) //子弹碰到家(无论是谁的子弹)

{

bullet->exist=0;

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_BLU E|FOREGROUND_RED|FOREGROUND_GREEN);

GoToxy(38,37); printf(" ");

GoToxy(38,38); printf("◢◣");

GoToxy(38,39); printf("███");

GameOver(1); //游戏结束,传入1代表老家被毁

}

}

int BulletCheak (int x,int y) //判断子弹当前位置情况,判断子弹是否碰撞,是否位于水面上。{ //有障碍返回0,无障碍且子弹在地面返回1,子弹在水面上返回2

if(map[y][x]==0)

return 1;

else if(map[y][x]==5)

return 2;

else

return 0;

}

void PrintBullet (int x,int y,int T) //当前坐标BulletCheak 的值做参量T

{

if(T==1) // T==1 表示子弹当前坐标在陆地上

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED| FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY);

else if(T==2) // T==2 表示子弹当前坐标在水面上

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED| FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY|BACKGROU ND_BLUE);

GoToxy(2*x,y);

printf("☉");

}

21

贪吃蛇游戏课程设计实验报告全解

辽宁科技大学课程设计说明书 设计题目:基于C#的贪吃蛇游戏 学院、系:装备制造学院 专业班级:计算机科学与技术 学生姓名:叶佳佳 指导教师:丁宁 成绩: 2015年12月12日

目录 一、概述 (1) 1、用C#实现该设计的方法 (1) 2、贪吃蛇游戏说明 (1) 二、实验目的及设计要求 (1) 1、实验目的 (1) 2、实验要求 (2) 三、课程设计具体实现 (2) 1、概要设计 (2) 1.1、设计思想 (2) 1.2、主模块实现 (2) 1.3、主函数流程图 (4) 2、详细设计 (5) 2.1、设计思想 (5) 2.2、具体模块实现: (5) 四、调试过程及运行结果 (10) 1、调试过程 (10) 2、实验结果 (11) 五、实验心得 (12) 六、参考资料 (13) 七、附录:源代码 (13)

一、概述 1、用C#实现该设计的方法 首先应该了解设计要求,然后按照功能设计出实际模块,每个模块都要完成特定的功能,要实现模块间的高内聚,低耦合。设计模块是一个相当重要的环节,模块的数量不宜太多,也不宜太少,要是每个模块都能比较简单的转换成流程图。模块设计完成后,就该给每个模块绘制流程图。流程图要尽可能的简单且容易理解,多使用中文,补一些过长的代码,增加理解难度。此外,流程图应容易转换成代码。 根据流程图编写好代码后在WindowsXP操作系统,https://www.360docs.net/doc/359682330.html,2008开发环境下进行运行测试,检查错误,最终设计出可行的程序。 2、贪吃蛇游戏说明 游戏操作要尽可能的简单,界面要尽可能的美观。 编写程序实现贪吃蛇游戏,贪吃蛇游戏是一个深受人们喜欢的游戏:一条蛇在密闭的围墙内,在围墙内随机出现一个食物,通过键盘上的四个光标键控制蛇向上下左右四个方向移动,蛇头撞到食物,则表示食物被吃掉,这时蛇的身体长一节,同时计10分;接着又出现食物,等待被蛇吃掉,如果蛇在移动过程中,撞到墙壁、障碍物或身体交叉(蛇头撞到自己的身体),则游戏结束。游戏结束时输出相应得分。 具体要求有以下几点: (1)对系统进行功能模块分析、控制模块分析正确,符合课题要求,实现相应功能;可以加以其他功能或修饰,使程序更加完善、合理; (2)系统设计要实用,采用模块化程序设计方法,编程简练、可用,功能全面; (3)说明书、流程图要清楚; 二、实验目的及设计要求 1、实验目的 .NET课程设计是教学实践环节中一项重要内容,进行此课程设计旨在掌握基础知识的基础上,进一步加深对VC#.NET技术的理解和掌握; 提高和加强学生的计算机应用及软件开发能力,使学生具备初级程序员的基本素质; 培养学生独立分析问题、解决问题、查阅资料以及自学能力,以适应信息管理行业日新 1

《贪吃蛇游戏课程设计》报告资料整理

贪吃蛇游戏程序设计 一、课程设计任务 贪吃蛇小游戏程序设计 二、设计要求 通过游戏程序设计,提高编程兴趣与编程思路,巩固C语言中所学的知识,合理的运用资料,实现理论与实际相结合。 (1).收集资料,分析课题,分解问题,形成总体设计思路; (2).对于设计中用到的关键函数,要学会通过查资料,弄懂其用法,要联系问题进行具体介绍; (3).上机调试,查错,逐步分析不能正常运行的原因,确保所设计的程序正确,并且能正常运行; (4).完成课程设计报告,并进行答辩 三、需求分析 3.1、程序功能 贪吃蛇游戏是一个经典小游戏,一条蛇在封闭围墙里,围墙里随机出现一个食物,通过按键盘四个光标键控制蛇向上下左右四个方向移动,蛇头撞倒食物,则食物被吃掉,蛇身体长一节,同时记10分,接着又出现食物,等待蛇来吃,如果蛇在移动中撞到墙或身体交叉蛇头撞倒自己身体游戏结束。

3.2、设计思想 程序关键在于表示蛇的图形及蛇的移动。用一个小矩形快表示蛇的一节身体,身体每长一节,增加一个矩形块,蛇头用俩节表示。移动时必须从蛇头开始,所以蛇不能向相反的方向移动,如果不按任意键,蛇自行在当前方向上前移,但按下有效方向键后,蛇头朝着该方向移动,一步移动一节身体,所以按下有效方向键后,先确定蛇头的位置,而后蛇的身体随蛇头移动,图形的实现是从蛇头新位置开始画出蛇,这时,由于未清屏的原因,原来的蛇的位置和新蛇的位置差一个单位,所以看起来蛇多一节身体,所以将蛇的最后一节用背景色覆盖。食物的出现与消失也是画矩形块和覆盖矩形块。为了便于理解,定义两个结构体:食物与蛇。

3.3、流程图

四、设计的具体实现 (1)函数定义 函数定义是对各个基础函数的定义,并且设置需要运用的信息,便于调用 #define N 200 #define M 200 #include"graphics.h" #include #include #include #include #include #include #include #define LEFT 97//A #define RIGHT 100//D #define DOWN 115//S #define UP 119//W #define Esc 0x011b int i,key; int score=0; int gamespeed=250;//游戏速度可根据实际情况自行调整 struct Food { int x;//食物的横坐标 int y;//食物的纵坐标 int yes;//判断是否要出现食物的变量 }food;//食物的结构体 struct Snake { int x[M]; int y[M]; int node;//蛇的节数 int direction;//蛇的移动方向 int life;//蛇的生命,0表示活着,1表示死亡 }snake; void Init();//图形驱动

坦克大战 实验报告

本科实验报告 课程名称:Java语言程序设计 实验项目:TankWar 实验地点:致远楼B403 专业班级:软件工程1219 学号:2012005496 学生姓名:柴丁方 指导教师:任少斌 2014年 1 月7 日

import java.awt.*; import java.awt.event.*; public class TankWarClient extends Frame { //构造游戏开始的界面 public void KaiShiJieMian() { this.setLocation(400,200); //游戏窗口的左上点在屏幕的位置 this.setSize(800, 600);//游戏窗口的尺寸 //使按窗口的“X”时,可以关闭程序

较上一次实验添加的代码段为: public void paint (Graphics g) { Color c = g.getColor();//color类是 java。awt 中的,因此可以直接 color c g.setColor(Color.green);// 类 java.awt.Graphics 中的方法,将此图形上下文的当前颜色设置为指定颜色。 g.fillOval(50, 50, 30, 30);//int x, int y,int width,int height,分别为坐标与椭圆的长宽 g.setColor(c); }

变更2: 较上一次实验添加的代码段为: 1.更改如下代码段中的“常量值”为“x”“y”,使所填充的椭圆位置可以随值改变,为静态的图形动起来打下了基础。 static int x=50,y=50;

项目坦克大战设计报告

《JA V A程序开发课程设计》项目设计 项目名称:TankWar 软件 专业:软件工程班级:13软工1班姓名:毛晨光学号:24 一、需求分析: 基本功能: 1.玩家控制的坦克能够四处移动并且打击敌方坦克; 2.敌方坦克能够随机四处移动并且打击玩家控制的坦克; 3.玩家控制的坦克拥有血量,而敌方坦克没有; 4.坦克受到攻击时血条会缩短; 5.敌方坦克被消灭完之后,提示游戏胜利; 6.用户方坦克被消灭后提示游戏结束; 特色功能: 1.坦克具有图片,不单单只是个圈圈。 2.增加了血包功能,地图上会随机出现一个血包,我方坦克开过会增加 血量。 二、系统设计: 类:实现游戏界面地图的初始化。 类:绘制和重绘功能。 :监听用户的键盘输入。 类:实现坦克的初始化,绘制,移动,发射等功能。 :实现敌方坦克的初始化,绘制,移动,发射等功能。 类:实现炮弹的初始化,绘制,移动,攻击功能。 类:实现爆炸的初始化。绘制功能,爆炸效果由绘制半径从小到大再到小的圆实现。 类:包含枚举。 类:用于实现血包的功能。 三、功能实现。 一.绘制地图功能: public class TankMap extends Frame{ tart(); }

制坦克功能:public class Tank { 方坦克的绘制方法 public class EnemyTank extends Tank{ 弹绘制方法public class Shell { ntersects())){

ntersects())){ "hittanks"); (false); =false; Explor ex=new Explor(x-3,y-3,; return true; } } return true; } }

Java课程设计小游戏

《高级语言程序设计》课程设计报告 1、程序设计说明书 【设计题目】 雷霆行动游戏程序 【问题描述】 雷霆行动是一款供大家休闲娱乐的小游戏,游戏通过鼠标控制我方飞机hero的移动,达到躲闪敌机的目的;利用鼠标键发射子弹和导弹,达到击毁敌机的目的,摧毁敌机有积分。此游戏为闯关积分类小游戏。 【软件功能】 1.按鼠标左键,游戏开始。 2.利用鼠标移动控制hero自由移动,闪躲敌方子弹。 3.利用鼠标左键发射子弹,实现打中敌方飞机的功能;利用鼠标右键释放导弹,实现摧毁大量敌 机的功能,击中一个敌方飞机积一分。 4.hero碰到对方子弹会消耗生命,消耗生命的多少,依据子弹的不同而不同。 5.一关之后会进入下一关。 6.游戏右上角红色的进度条表示hero的生命,当红色全部消失之后,游戏结束,显示死亡。 7.游戏结束后,可重新开始,同1。 【算法思想】 1.创建游戏主界面,确定窗口的坐标。 2.设计游戏开始界面显示信息及信息坐标。 3.设置游戏进行中的信息,hero的移动、释放子弹和导弹,达到击毁敌机的目的。 4.处理游戏进行中的子弹、大爆、爆炸、敌机消失和存在的条件。 5.设置进入下一关的条件。 6.设计游戏结束界面显示信息及信息坐标。 7.处理游戏重新开始满足的条件。 8.装载图像。 9.对游戏进行调试和改进,使这个游戏更加完善。 【类的设计】 本程序共有七个类: 1.MainPanel 属性:BBv为子弹数组,EEv为敌机数组,BOMBv为爆炸数组,EBv为敌机子弹数组,DBv 为大爆数组,E-num为敌机数量,E-max敌机最大数,E-vel为敌机速度,E-mov为敌机 横移几率,E-hit为敌机开火几率,Sum为击毁敌机数量,hero-hp为hero生命,back至 db-2均为图片,tracker为媒体跟踪器,y为背景滚动变量,seq为hero的动画变量,isfire 为hero开火,isblast为是否发爆,blastnum为大爆的数量,blastc为控制大爆,f、ff、s、 ss均为游戏界面上显示的信息; 方法:MainPanel(Game)构造方法,paint(Graphics)建立游戏开始界面如显示的文字,run()控制对象移动,BBmove(int,int)子弹的移动方法,DBmove(int,int)大爆的移动方法, mouseDragged(MouseEvent) 鼠标的拖拽用来保证hero不出界,mouseMoved(MouseEvent) 鼠标的移动用来控制hero移动,mousePressed(MouseEvent) 鼠标按键在组件上按下时调 用,重新开始游戏,mouseClicked(MouseEvent)鼠标按键在组件上单击(按下并释放) 时调用,释放子弹,mouseReleased(MouseEvent)鼠标按钮在组件上释放时调用, mouseEntered(MouseEvent)鼠标进入组件上调用,mouseExited(MouseEvent)鼠标离开组 件时调用;

游戏24点课程设计报告

游戏24点课程设计报告 一.题目: 分析类: 计算24点:任意输入4位数字,利用+,-,*,/四则运算使之得到结果 24。输出所有不同算法的计算表达式,可为运算优先级而使用括号。 二.问题分析: 1.全面性: 此问题要求输出结果为24的计算表达式,并且要求输出要全面,我考虑用for循环与递归实现遍历来保证输出的全面性,考虑到递归的‘一归到底',每一次完整递归都代表一种算法(详情见算法)。 2.输出的判定和四位数字的类型: 在输出的时候对最后结果等于24的判别,因为考虑到有除法,有可能中途结果可能会出现不能整除的情况与小数,所以输出的四个数都设为float型,且输出判定的时候用近似判定法,而不直接写让最后结果等于24(详情见算法)。 3.重复性: 如果用循环与递归保证了输出24的表达式的全面性,但不可避免的会出现重复,才开始我想在遍历与递归时,加一些限定条件来消除重复但是这样做不但会出错,还不能保证它的输出全面性。于是我想在输出的时候加限定条件,使重复的只输出一遍。 但是对于输入的那4位数字中如果有重复的话,程序结果还是会出现重复的,此问题尚未解决.(详情见算法)。 4.括号问题的处理: 对于括号问题,我规定对每一步的计算表达式,除了*之外,+,-,\都加上括号,即让程序按自己规定的方向执行,输出的括号只是让人能看懂,其实在运算时不起作用(详情见算法)。 5.输出: 输出方面我以为用了遍历所以在每一层遍历都把运算表达式存到一个较大的数组中,在输出的时候如果满足输出条件(在遍历时纪录每次递归的第一次运算的结果,第一次运算的运算符,第二次运算的结果,第二次运算的运算符和第三次运算的运算符),就直接把那个数组里的内容输出,遍历会直接去寻找表达式里的表达式(详情见算法)。 三.算法描述(源代码里有更详尽解释): 1.主要方法: 遍历与递归。 2.主要思路: 把输入的四个数放在一个数组n[4]中,然后任取其中任意两个(不能取同一个--既不能出现自己和自己运算的情况),然后用一个for和一个switch语句来实现这两个数的加减乘除运算,然后把运算的结果放到另一个数组b[4]中并记录此运算的表达式(放到一个大一点的数组tm[4][25]中),同时把其他两个没用到的数也放到该数组中,然后重复以上过程(用遍历实现),最后先判定是不是最后一层运算,是的话在判定最后结果是不是等于24,等于24的话就把那个纪录运算式的数组输出。然后考虑到不能出现重复的(例如:1*2*3*4和2*4*3*1等等)我在遍历的同时记录了第一次运算的结果,第一次运算的运算符,第二次运算的结果,第二次运算的运算符和第三次运算的运算符,对输出的时候做限定(例如:对运算符全*的只输出一遍等等)。在有一次输出后我还定义了另外两个数组用来分别保存上一次输出的第一次运算的结果,第一次运算的运算符,第二次运算的结果,第二次运算的运算符和第三次运算的运算符,来解决重复输出的问题,不过此种做法有可能导致输出的时候不全。(此问题尚未解决)即还不能同时保证全面性与不重复性。 3.主要函数与数组:

funcode C++课程设计坦克大战

课程设计一坦克大战 一、游戏介绍 相信大部分同学都玩过或看过“坦克大战”这款经典游戏。现在,就由我们自己动手来开发它。只要大家具备了C++语言和面向对象的基础知识,然后按照实验指南的指导一步一步进行下去,相信我们每个同学都能把这款经典游戏做出来。 二、实验目标 综合运用C++及其面向对象的知识开发一款小游戏。 三、实验内容 在一个战场上,玩家控制坦克,消灭敌方坦克,并防止敌方坦克摧毁我方基地。游戏的具体要求如下: 1、游戏有一个初始页面,如下图。 2、按下任意键开始游戏,玩家控制坦克在战场上穿梭,碰到墙时,不能通过。 3、敌方坦克自由移动,每隔2秒改变一个方向,每隔3秒发射一发子弹。 4、敌方坦克每隔5秒出现一辆,从屏幕上方的左、中、右三个位置依次出现。 5、当玩家被消灭或者我方基地被摧毁或者游戏时间大于30秒的时候,游戏结束。 游戏开始前 进入游戏

四、游戏的整体框架 五、实验指南 实验准备 打开FunCode,创建一个新的C++项目。注意:项目名称必须为英文和数字,且不能有空格。 点击“项目”→“导入地图模板”,从对话框中选取名称为TankWar的模板导入。导入成功后,界面如下: 实验一游戏开始 【实验内容】 1、设置游戏标题 2、按空格键,提示图片消失,游戏进入开始状态. 【实验运行结果】 游戏开始前 按下空格键后 【实验思路】

按下空格键是键盘按下事件,可在CSystem::OnKeyDown函数中编写响应代码。为了保证程序结构的清晰、一致,更好的办法是在CGameMain类中添加一个相应的键盘按下事件处理函数,然后在CSystem::OnMouseClick函数中进行调用。 g_GameMain是CGameMain类的对象,它是全局变量,在程序运行时最先被创建。【实验指导】 1、C++程序的执行入口是主函数。FunCode的主函数名称叫WinMain,写在Main.cpp 文件中。CSystem::SetWindowTitle是设置程序运行窗口标题的函数,修改如下:CSystem::SetWindowTitle("坦克大战"); 2、参考CSystem::OnKeyDown函数,为CGameMain类创建一个OnKeyDown函数。 CGameMain类的头文件是LessonX.h文件,实现代码写在LessonX.cpp文件中。因此,先在LessonX.h文件对函数进行声明。函数的返回值和参数列表都与 CSystem::OnKeyDown函数保持一致。访问权限应该是public。代码如下: voidOnKeyDown(constintiKey,constboolbAltPress,constboolbShiftPress,cons tboolbCtrlPress); 3、接着,在Lesson.cpp文件中对该函数进行定义: voidCGameMain::OnKeyDown(constintiKey,constboolbAltPress,constboolbShif tPress,constboolbCtrlPress) { }

三子棋小游戏课程设计

三子棋小游戏课程设计 计算机学院计算机科学与技术专业《程序设计综合课程设计》报告 (2011/2012学年第一学期) 学生姓名: 学生班级: 学生学号: 指导教师: 2012年01月04日 三 子 棋 小 游 戏 目录 第一章程序设计的目的和要求 1 1.1课程设计的目的 ......1 1.2课程设计的要求 1 第二章课程设计任务内容 3 2.1课程设计题目 3 2.2课程设计介绍 3 第三章详细设计说明 ..4 3.1 流程逻 辑............................................................ .4 3.2 限制条 件 (5)

3.3 运行结 果 (5) 3.4 实验过 程 (8) 第四章实验总结及特色 11 4.1调试结果及截图 11 第五章课程设计心得及体会 13 附录? 参考文献 15 附录? 程序代码 16 第一章课程设计目的和要求 目的 通过此次课程设计,进一步加深对C++语言和运用的了解,将理论知识运用于开发的实践,并在实践中逐步掌握软件工具的使用。 巩固已经学习过的C++理论知识;进一步学习程序设计、程序调试的能力。 进一步学习面向对象编程的知识和程序调试的能力; 增强Visual C++编程环境的应用能力 掌握并且熟练应用《C++程序设计》中所学知识,并学会运用。 掌握函数功能的划分方法,并运用此方法解决问题。学会程序测试方案的制定,并且实现程序的测试。 通过此次实践,积累经验,提高分析和解决问题的能力。 第二节要求 课程设计需要从整体来考虑,在大的方向下来考虑小的模块,在继续分工。作到最小化,可执行化。

《c语言课程设计报告--小游戏“石头剪子布”》

《C语言课程设计》报告题目:石头剪子布 班级: 学号: 姓名: 指导教师: 成绩:

目录: 一、选题背景...................................................................................................................... - 2 - 二、设计思路...................................................................................................................... - 2 - 三、主要问题的解决方法及关键技术.............................................................................. - 3 - 四、程序流程图.................................................................................................................. - 3 - 五、源程序清单.................................................................................................................. - 6 - 六、程序运行结果.............................................................................................................. - 8 - 七、设计总结...................................................................................................................... - 9 - 八、教师评语.................................................................................................................... - 10 - 一、选题背景 通过一个学期的C语言课程的学习,《C语言程序设计》课程已结束,根据学校课程学习的安排,要进行一周的C语言实习,自己动手编写游戏和系统。根据老师布置的设计任务书,按照学委的安排,根据个人的能力及意愿,我选择了设计一格小游戏:石头剪子布。 实验准备:做游戏前,首先,自己详细看了《C语言程序设计》(教科书),理解了相关函数的用法和作用;另外,上网查询了很多相关资料,还有找了很多相关的游戏设计的代码,都详细的看了一遍,加深了对C语言以及相关内容进一步理解。根据实际情况设计出一款比较理想的小游戏。 设计题目的要求: ①游戏要设置开始,结束操作控制 ②游戏要有时间提示即相关结果的提示语 ③游戏要能自动判断输赢,并显示最终比赛结果 二、设计思路 系统功能模块图: 输入:计算机随机输入选择,用户输入选择,并将数据储存。 计算:根据计算机和用户的选择,计算大小,并判断输赢,计算用户的胜负率,并储存。 输出:根据用户的输入,将用户的游戏结果显示在屏幕上。

C++课程设计报告---21点纸牌游戏程序

#include #include #include #include #include #include class Game { public: Game() { win=0,lose=0,draw=0,playerturns=0,cputurns=0,money=100,bet=0; player=0,cpu=0; char answer1[]="123456"; strcpy(answer,answer1); char answer2[]="654321"; strcpy(daan,answer2); }; void rules();//显示规则 void BET(); //下注 void deal();//交易 void run(Game &);//进行异常处理 void hit1();//拿下一牌 void hit2();//确保庄家不会爆庄并且点数大于16 void print();//打印出最后结果 void results();//最后的胜利结果 void check();//检查是否爆庄 Game operator=(Game &d);//运算符重载 void replay(char &ans);//是否进行新一轮的游戏 void clean();//清屏 void wait(int); void pause(); int GetInt(int,int); int random(long,long); private: int playerturns,cputurns,money; int win,lose,draw,bet; float player,cpu; char answer[7]; char daan[7]; }; //--------------------------------------------------------------------------------------- void Game::wait(int milli) {

计算机图形学课程设计——扫雷游戏程序设计

计算机图形学课程设计——扫雷游戏程序设计

《计算机图形学》课程设计报告 VC++扫雷游戏的程序设计 专业班级: 小组成员:

指导老师: 日期:2012年12月24日 1、需求分析 本课程设计实现类似于Windows XP操作系统自带的扫雷游戏。该设计以V isual C++ 6.0为开发环境, Windows 7/XP为程序运行平台。在程序设计中,把整个雷区看成一个二维数组,把雷方块定义为具有所在雷区二维数组的行和列、当前状态、方块属性、历史状态的结构体,采用了MFC机制解决问题的方法。整个游戏程序包括了布雷、扫雷过程和结果三个阶段,在处理鼠标响应事件中伴随着GDI绘图。程序通过调试运行,实现简单的设计目标,满足扫雷游戏初学者的需要。 通过本课程设计,以便更好的巩固计算机图形学相关知识,掌握课程设计基本的方法和技巧,同时增加同学之间的团队合作精神以及培养分析问题、解决问题的能力。 2.总体设计 2.1 功能概述 扫雷游戏的游戏界面如图1所示。在这个界面中,由众多面积均等的小方块所组成的区域称之为雷区,雷区的大小由用户设置的游戏等级决定。

图1 游戏开始时,系统会在雷区中随机布下若干个地雷。安放地雷的小方块称之为雷方块,其他的称之为非雷方块。部署完毕后,系统会在其他非雷方块中填充一些数字。某一个具体数字表示与其紧邻的8个方块 中有多少雷方块。玩家可以根据这些信息去判断是否可以鼠标点击方块, 并把认为是地雷的方块打上标识。当玩家将所有地雷找出后,其余的非雷方块区域都已打开,此时游戏结束。在游戏过程中,一旦错误地打开了雷方块则立即失败,游戏结束。 游戏规则总结: ●开始:按左键开始游戏,按按钮或菜单重新开始。 ●左键:按下时,是雷则结束,非雷则显示数字。 ●数字:代表此数字周围一圈八格中雷的个数。 ●右键:奇次按下表示雷,偶数按下表示对上次的否定。 ●结束:左键按到雷结束,找出全部雷结束。 在游戏开始后,雷区上方有两个计数器。右边的计数器显示用户扫

动画与游戏设计-课程设计报告

《动画与游戏开发》 课程报告 学号:111102020103 姓名:张慧 专业班级:11级计科本01班 日期:2013-12-9

电子信息工程学院 目录 一、课程内容及应用领域 1.1基于DirectX的粒子系统 (3) 1.1.1 粒子系统简介 (3) 1.1.2广告板技术 (3) 1.1.3粒子系统的基本原理 (3) 1.2粒子系统的应用领域 (3) 二、课程内容的难点、疑点 2.1课程要点 (4) 2.2课程难点 (4) 2.3课程疑点 (4) 三、实例开发 3.1实例题目及说明 (4) 3.2关键技术 (5) 3.2.1系统完成的四部曲 (5) 3.2.2星光粒子结构构成技术 (5) 3.2.3 MyPaint()绘图函数 (5) 3.3开发过程 (9) 3.3.1案例所需背景图 (10) 3.3.2程序部分代码 (10) 3.3.3运行结果截图 (15)

3.4总结..........................................................17四、谈谈自己对课程内容的掌握程度

一、课程内容及应用领域 1.课程内容:基于DirectX的粒子系统 相关内容简介: (1)粒子系统简介 粒子系统是三维图形编程领域中用于实现特殊效果的一种非常重要的技术.该技术是由Reeves于1983年首次提出来的.通过粒子系统可以使用非常简单的粒子来构造复杂的物体,它为模拟动态的不规则物体,提供了强有力的技术手段。一般情况下,粒子的几何特征十分简单,可以用一个像素或一个小的多边形来表示.如果给出了粒子中心点的坐标和粒子大小,不难计算出绘制粒子所需要的四个顶点的位置坐标. (2)广告板技术 由于通常使用平面图形而不是立体图形表示一个粒子,所以需要使用的粒子四边形始终面向观察者.这就要使用广告板技术.广告板技术的原理是,在渲染一个多边形时,首先根据观察方向构造一个旋转矩阵,利用该矩阵旋转多边形使其面向观察者,如果观察方向不断变化,就要不断旋转多边形. (3)粒子系统的基本原理 粒子通常都是一个带有纹理的四边形。我们通过这个使用了纹理映射的四边形,可以认为粒子实际上是一个很小的网格模型,只不过是纹理赋予了它特殊的外表罢了。绘制粒子就如果绘制多边形一样简单,因为一个粒子说白了就是一个可改变大小并映射了纹理的四边形罢了。 粒子系统由大量的粒子构成,粒子是一种微小的物体,每个粒子都具有一定的属性,如位置、大小以及纹理,可能还需要颜色、透明度、运动速度、加速度、生命期等属性。我们可以把粒子想象成颗粒状的物体,如雪花,雨滴,沙尘,烟雾等特殊的事物。又比如游戏中的

unity3d游戏课程设计报告

游戏程序设计课程报告 课程: Unity3D课程设计题目:探索迷宫 班级: 学号: 姓名:

日期:2014.12 一、摘要 1 UNITY游戏是一种新型的IT引擎。我们研究主要内容是UNITY游戏设计方法。指以游戏客户端软件为信息交互窗口的旨在实现娱乐、休闲、交流和取得虚拟成就的具有可持续性的个体性单人游戏。 本报告主要讲述了这个小游戏的设计思路及初步使用Unity3D软件 的感受和总结。设计过程中,首先建立自己想要的模型,然后在此基础上进行需求迭代,详细设计时不断地修正和完善,经过测试阶段反复调试和验证,最终形成达到设计要求的小游戏。 基于UNITY基础,构建了一个益智游戏风格的游戏,并有主角与关卡、游戏逻辑、游戏环境界面等设计,使得玩家可以在场景中进行寻找神龛的冒险游戏。 本游戏的控制很简单,及用键盘的W ASD及SPACE五个控制人物的上下左右跳跃五个方向,用户根据自己的战略方式选择寻找油桶点亮煤油灯然后寻找神龛。

二、概述 《UNITY游戏程序设计》这一课程以大作业形式进行考核,能更好地锻炼学生综合运用本课程所授知识的能力。大作业主要内容为设计完成面向某一主题内容的游戏演示程序。 自选游戏主题,并根据所选定的主题内容设计一个典型的游戏场景及玩家逻辑,其中包含主角与关卡,游戏逻辑,游戏环境界面与交2 互过程等的设计;开发完成与设计相符的游戏Demo。 要求使用Unity3D游戏开发软件实现上述游戏Demo。 三、具体要求 1、每人单独完成,特殊可由多人合作完成。 2、游戏主题自拟。 3、根据所设游戏主题、场景及玩家逻辑,实现完成相应的游戏Demo,并撰写设计开发报告。 四、设计主题 基于视频教程“平衡球”的基础,构建了一个益智游戏风格的游戏,并有主角与关卡(一关)、游戏逻辑(触碰油桶、神龛)、游戏环境界面(通道)等设计,使得玩家可以在场景轨道中进行吃油桶、神龛的冒险游戏。 五、设计思路 本游戏以几个环环相扣的通道作为人物运动的轨迹,在通道上分

猜数字游戏课程设计报告

XXXX学校 《C程序设计》 课程设计报告 设计题目:猜数字游戏 附录完整源代码 专业: 班级: 学生: 学号: 指导教师: 起止时间: xxx.x.x -xxx.x.x xxxx-xxxx年 xx 学期

目录 1 、程序设计描述 1.1 程序设计目的: 1.2 程序设计要求: 1.3、猜数字游戏的简介: 2 、程序设计内容: 2.1、游戏主要框架图: 2.2、开始游戏框架: 2.3、最佳排行框架: 2.4、游戏操作说明模块: 2.5、退出游戏系统: 2.6、游戏系统总流程图: 3、猜数字游戏源代码: 3.1、void main()函数函数功能: 3.2、void game();//双人游戏 void pgame();//单人游戏 3.4、排行榜模块函数功能: 3.5、继续游戏模块函数功能: 3.6、操作说明模块函数功能: 4、调试与测试: 4.1、调试方法 4.2、测试结果的分析与讨论 4.3、测试过程中遇到的主要问题及采取的解决措施 5、程序具体说明书: 6、程序设计心得: 7、参考文献

1 、程序设计描述 1.1 程序设计目的: 综合使用所学过的C语言程序设计知识,掌握结构化程序设计的基本思路和方法,利用所学的基本知识和技能,发挥自学能力和查找资料的能力,解决稍微复杂的结构化程序设计问题,加深对所学知识的理解与掌握,增强学生利用自己所学知识解决实际问题的能力,为以后的程序开发打下基础。 1.2 程序设计要求: 1、巩固和加强《C语言程序设计》课程的理论知识。 2、掌握C语言的基本概念、语法、语义和数据类型的使用特点。 3、掌握C语言程序设计的方法及编程技巧,能正确使用C语言编写程序。 4、进一步理解和运用结构化程设计的思想和方法;学会利用流程图。 5、掌握调试程序的基本方法及上机操作方法。 6、掌握书写程设计开发文档的能力,学会撰写课程设计总结报告。课程设计的思想和方法还可以作为做毕业论文时的参考资料。 7、通过查阅手册和文献资料,培养独立分析问题和解决问题的能力。为做毕业设计打好基础。 8、培养自己的创新能力和创新思维。可以根据指导书和相关文献上的参考算法,自己设计出相应的应用程序。 9、培养自己良好的程序设计风格。在实际编程中,为了提高编程质量,对空行、空格和注释均有要求。在课程设计书写代码时,应该严格按要求处理,以便建立良好的程序设计风格。 1.3、猜数字游戏的简介: 猜数字游戏(又称 Bulls and Cows )是一种大概于20世纪中期兴起于的益智类小游戏。一般由两个人玩,也可以由一个人和电脑玩,在纸上、在网上都可以玩。这种游戏规则简单,但可以考验人的严谨和耐心。 2 、程序设计内容: 2.1、游戏主要框架图: 该模块为玩家提供猜数字游戏的主体功能,即开始游戏、继续游戏、最佳排行、操作说明、退出游戏。给用户一个清晰明了的操作界面!流程图如下:

《面向对象的编程技术》课程设计实验报告

《面向对象的编程技术》课程设计实验报告 系计算机科学与技术 班级计114 姓名石险峰 学号119074122 指导教师胡增涛 计算机学院 2012年12月

一.应用程序的名称 设计:“坦克大战” (1)参考(《PC游戏编程(窥门篇)》谭文洪著)中的“坦克大战”(TankWar工程),并对其进行完善、扩充,程序要能看出专业水平和商业化产品的效果。 (2)要求:修改案例中“子弹可以穿透石头墙”的错误;增加上帝模式(无敌);修改一种敌军坦克,使之威力更大(要求坦克画面采用学生自己的头像)(需要重新编译资源包;之所以“改”而不是“增”,是因为同学们无法修改地图编辑器,另一个办法是在程序运行后动态加入);回答“坦克大战”指导书.doc(或pdf)和TankWar剖析.doc(或pdf)中带有蓝色《….?》标记的问题。 二.应用程序的设计目的 面向对象的编程技术》课程设计是一门独立开设的实验课程,旨在进一步强化学生对类、封装、继承、多态等面向对象基本概念的理解和OOP(面向对象编程)实际动手能力,并进一步拓展到OOD(面向对象设计)原则、技巧和初步的OOA(面向对象分析)方法。 在中国,电子游戏曾一度被大家斥为“电子海洛因”。然而电子游戏在青年学生中大受欢迎却又是一个不争的事实。正如水能载舟,亦能覆舟一样,任何事物都有其两面性。与其千方百计地封堵,还不如让同学们从技术的角度来研究它,这样既可以掌握复杂系统的设计技巧,也可以破除对电子游戏的神秘感。我相信,一个人如果自己能制作游戏,如果能清楚地知道那个绚丽多彩的虚拟世界背后无非就是一些类、变量、函数的话,他就不可能再沉迷于打游戏———与一堆对象、内存变量和函数较劲。同时,从技术上讲,游戏程序的开发异常复杂,能充分体现面向对象的拟人化思想和面向对象设计技巧。通过游戏程序的制作,可以帮助学生真正掌握面向对象程序设计的精髓。 三.应用程序简介 设计目的:C++电脑游戏开发:侧重利用面向对象的拟人化思想解决复杂问题和OOD技巧; 运行环境: 1.本设计采用Microsoft Visual C++6.0编译,并能够在WIN98,WIN2000下运行 2.游戏基于Windows Game Engine(WGE游戏引擎,添翼虎科技)(没提供源程序,不过不用担心,你可以把它看成是利用DirectX快速处理图片、声音、键鼠的类库) ,该引擎需要DirectX7.0 SDK支持(仅有Runtime运行库不够,必须包含开发语言需要的Header&Libs 头文件和库文件) 功能介绍: ○1修改案例中“子弹可以穿透石头墙”而且增加了敌军坦克子弹不能穿过 箱子:无论是敌军坦克还是玩家坦克的子弹都不能穿过石头,敌军坦克子弹不能透过箱子,一旦它们相碰撞子弹会自动销毁。 ○2增加上帝模式(无敌):玩家1通过按F1键变为上帝模式,再按一次,还原,一旦玩家进入上帝模式,敌军坦克的子弹对玩家坦克没任何损伤。 ○3修改火坦克的性能,使之威力更大,并且将该敌军坦克改为其他图像,通过更改火坦克的一些属性,使火坦克的子弹射程、威力,坦克的移动速

大学课程设计报告小小打字游戏设计-课程设计报告

2016-2017学年第一学期 《Windows程序设计》 课程设计报告 题目:小小打字游戏设计 专业: 班级: 姓名: 指导教师: 成绩: 二0一六年十一月十五日

目录 1 设计内容及要求 (1) 1.1 设计内容 (1) 1.2 系统功能 (1) 1.3 信息存储功能 (1) 2 系统设计 (1) 2.1 数据库设计 (1) 2.1.1 GameUser表 (1) 2.1.2 GameInfo表 (2) 2.2 游戏系统设计 (2) 2.2.1 程序项目设计 (2) 2.2.2 功能模块设计 (2) 3 C#系统实现 (5) 3.1 类图 (5) 3.2 核心代码 (6) 3.3 MySqlConn类 (10) 3.4 MainForm类 (11) 3.5 菜单事件 (12) 3.6 窗体键盘事件 (13) 3.7 MyRandom类 (15) 3.8 Program类 (16) 4 总结 (17) 4.1 收获 (17) 4.2 反思 (17) 5 参考文献: (18)

1 设计内容及要求 1.1 设计内容 软件名称:小小打字游戏 需求分析:使用VS2010开发环境,用C#语言编写一个打字游戏,游戏界面随机出现下落的A到Z的26个字母,当用户按下相应的键,游戏屏幕上正在下落的字母就会被消除,游戏分数将相应增加。 1.2 系统功能 (1)、登录功能:启动软件,出现登录界面,用户输入账号密码,正确后方可进入游戏; (2)、注册功能:不存在的用户,可以注册; (3)、软件互斥:通过创建互斥变量,使打字游戏软件只能单独开启一个; (4)、游戏控制:按F1开启游戏,F2暂停游戏,F3继续游戏,F4使用游戏积分兑换生命值; (5)、游戏显示:游戏窗口随机下落颜色不定的A到Z 26个字母,并根据游戏得分实时增加字母下落的速度; (6)、游戏操作:按下键盘上的A-Z 26个字母键,游戏窗口上正在下落的对应字母被消除,并使游戏分数增加1; (7)、数据保存和清除:使用数据库保存用户的游戏数据,并可调用数据库数据显示在游戏界面上显示,管理员账号可以清除游戏数据记录; (8)、游戏界面信息显示:显示相应的游戏状态信息,暂停游戏提示,结束游戏提示以及游戏排名。 1.3 信息存储功能 需要存储的信息: (1)游戏分数、(2) 游戏等级、 (3) 用户、 (4)密码、(5)游戏开始时间、(6)游戏结束时间。 2 系统设计 2.1 数据库设计 2.1.1 GameUser表 表1 GameUser表

21点游戏课程设计

/*玩家最多可以要5张牌,但是如果牌的点数之和超过21,则自动出局,在不超过21点的情况下,玩与庄家比牌的点数大小,大者为赢家。*/ #include #include #include using name space std; class C Card { priv ate: int na Pip[5]; //定义一个数组,一共是5张牌。 int nNu mbe r; //发了多少张牌。 int nDol lar; //有多少钱 int nGa mble; //赌注 int nW in; //赢局数 int n Lose; //输局数 int nDraw; //输局数 public: C Card(); //构造函数 v oid FirstPla yTwo();//最初两张牌 int Ge tNumbe r();//返回牌张数

int Ge tPip(); //返回点数 v oid Displa yPip();//一次全部显示牌面点数。 v oid Displa yPip(int ); //除了第一张牌,一次全部显示牌面点数(针对计算机牌的显示) v oid TurnPla y();//出了一张牌 v oid Win();//赢了计算赌注 v oid Lose();//输了 v oid Draw();//平局 int se tGamb le(int );//设置赌注,赌本不够返回1 int ge tM one y();//返回钱数 v oid Displa yInfo();//打印必要的信息 int Ge tCurre ntCard();//返回当前牌点。 }; CCard::C Card() { nNu mbe r=0;//开始没有发牌 nDollar=100;//初始赌本为0 for(int i=0;i<5;i++) na Pip[i]=0; //五张牌全部为0 nGa mble=0;

相关文档
最新文档