900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 飞机大战C++

飞机大战C++

时间:2021-10-20 00:23:15

相关推荐

飞机大战C++

为期两周的实训结束了,写一篇飞机大战纪念一下,因为之前对于编程可能也没有太深入系统的学习,这个实训应该标志着编程学习的由浅入深,也代表着我们学习正式开始。(所以说之前一年我们学了点什么。。。)

在拿到我们最后的要求时我其实还是有些犹豫,毕竟之前刚做过链表,写起贪吃蛇来相比飞机大战可能会比较容易,但后来又想到老师会给我们一些提示,于是我理所当然的飘了。。。。认为写出来的飞机大战应该会是这样的:

但是在提示给出来之后是这样的:

。。。。。。。。。。。

只能说菜给的太多了,喝成了这个样子

话不多说,还是脚踏实地一步一步写的好。

一、游戏要求:

按照一定的规则排列的“*”模拟玩家飞机,向下移动的“@”符号表示敌机,由下至上间断显示的“|”模拟子弹,界面下方显示飞机的生命值,的分情况等等。

每当玩家飞机撞上敌机生命值减1,程序自动生成另一架位置随机的飞机继续游戏,直到生命值为0游戏结束。

通过wasd键控制飞机移动,通过空格键发射激光子弹,要求:采用多文件结构实现。

二、实验设计

程序应该主要涉及到两个模块,分别为主模块mainfighter 和子模块fighter,子模块主要包含初始化功能函数init(),绘制游戏界面函数drawpitcure(),电脑操作子界面与敌机函数pcoperate(),玩家控制飞机函数operatefighter()。

主模块只有mainfighter这一个文件,以下为框架:

void main(){init();while(1);{drawpicture();pcoperate();operatefighter();}system("pause");}

相应的功能在具体的函数中实现。

三 函数调用思路

绘制游戏界面函数drawpicture()

外层循环变量x控制行输出,内层循环变量y控目列输出,内层循环语句不断判断当前坐标与玩家飞机、敌机、激光束子弹位置是否重叠,前坐标值(x,y)为(fighter. x, fighter. y)时向屏幕输出玩家飞机“*”,当前坐标值为(enemyenemy_ y)时向屏幕输出敌机“@”,当前坐标值为(bullet x, bullet y)时向屏幕输出激光子弹否则输出空格,从而实现了在屏幕上看到玩家飞机、敌机、激光束子弹的效果。

此时实现的游戏界面上的玩家飞机、敌机、激光子弹等是静止的,要想实现动态效需要不断改变玩家飞机、敌机、激光東子弹坐标值实现动态效果。

3)电脑操作子弹与敌机函数pcOperate0

pcOperate()函数相对简单,调用flatBaullet)函数实现激光束子弹向上漂浮效果,调用enemyfighter()实现敌机移动,被击落后随机生成敌机的视觉效果等。

eneyfighter(函数实现敌机移动、被击落后随机生成放机的视觉效果等)

4控制飞机operateFighter()

该西数主要实现玩家飞机移动、发射激光束子弹,通过按W5. 2小建控朝元家飞机上下左右移动,通过按下空格键发射激光子弹。

判断当前按键改变相应坐标值实现飞机移动、发射激光束子弹功能。当按下”键时表示向.上移动,玩家飞机纵向坐标减1横向坐标不变,即fighter X–;当按下“d”键时表不向右移动,玩家飞机横向坐标加1纵向坐标不变,即fighter y++。当按下空格键时表示发射激光束子弹,则在飞机正上方生成子弹,即将激光束子弹坐标值为(ighter_ x- 1, fighter y)。

五、编码实现

将游戏画面尺寸、玩家飞机位置、激光束子弹位置、敌机位置等定义为全局变量:

//全局变量int height,width;//游戏画面尺寸int fighter_x,fighter_y;//飞机位置int bullet_x,bullet_y;//子弹位置int enemy_x;enemy_y;//敌机位置string difficulty//难度设置显示条

init 函数要实现对上述全局变量赋值的功能,一般将玩家飞机显示在画面中间的位置,敌机显示在第一行,飞机坐标(fighter_x,fighter_y)设置为(height/2,width/2),敌机坐标为(enemy_x,enemy_y),设置为(0,rand()%(width-5)+2)。

drawpicture函数实现

通过双层函数循环控制光标移动,当坐标值(x,y)满足特定的条件时向屏幕输出玩家飞机,敌机,光束子弹。

cout << setfill('#') << setw(width + 6) << "#" << endl;for (int x = 0; x < height; x++){//外层循环for (int y = 0; y < width + 1; y++){if (y == 0)cout << "#";//设置左边界else if (y == width){//设置右边界if (x == fighter_x)cout << "#";else if (x == fighter_x + 1)cout << setfill(' ') << "#";else if (x == fighter_x + 2)cout << setfill(' ') << "#";else cout << setfill(' ') << setw(6) << "#";}else if ((x == fighter_x) && (y == fighter_y))cout << setfill(' ') << setw(6) << "* ";else if ((x == fighter_x + 1) && (y == fighter_y))cout << setfill('*') << setw(6) << " ";else if ((x == fighter_x + 2) && (y == fighter_y))cout << setfill(' ') << setw(6) << "* * ";//输出飞机else if ((x == bullet_x) && (y == bullet_y))cout << "|";//输出子弹else if (x == enemy_x && y == enemy_y)cout << "@";//输出敌机位置else cout << " ";}cout << endl;}cout << setfill('#') << setw(width + 6) << "#" << endl;cout << "难度:" << difficulty << endl;cout << "生命:" << fighter << endl;cout << "得分:" << score << endl;

operatefighter编码实现

调用floatbullet 函数处理子弹移动,调用enemyfighter函数实现生成敌机、移动等等。

bullet_x–实现子弹移动

要想设置难度层次,就要设法控制敌机向下移动的速度。因此设置静态变量speed,每执行几次,敌机就移动一次。

static int speed = 10;difficulty = "简单";if (score > 5) {speed++;difficulty = "普通";}if (score > 15) {speed++;difficulty = "困难";}if (speed < 10) {speed += 2;}else {enemy_x++;speed = 0;

最后,是击中敌机。在enemyfighter中增加判断,当子弹和敌机位置相同时就击中敌机,并增加变量score记录得分,击中敌机后+1;敌机被击中后会消失,然后在随机位置出现

if((bullet_x==enemy_x)&&(bullet_y==enemy_y))//子弹击中敌机{score++;enemy_x=-1;enemy_y=rand()%(width-5)+2;bullet_x=-2;//子弹无效

思路大致如下,但是在操作过程中,由于飞机体型较大,在击中敌机过程中无法准确被击毁,此外还存在着敌机在移动过程的瞬间子弹击中敌机无效的情况,因此更改判断条件,使得飞机任何位置碰到敌机都会被击毁;子弹能够准确的击毁敌机。

if (((bullet_x == enemy_x) && (bullet_y == enemy_y)) || ((bullet_x + 1 == enemy_x) &&(bullet_y == enemy_y)) || ((bullet_x - 1 == enemy_x) && (bullet_y == enemy_y))){score++;enemy_x = -1;//产生新的飞机enemy_y = rand() % (width - 5) + 3;//rand()函数生成随机数,但因为一般生成的随机数较大,因此做取余操作使其能在规定的宽度内生成bullet_x = -2;//子弹无效}if ((enemy_x == fighter_x) && ((enemy_y == fighter_y) ||(enemy_y == fighter_y + 1) || (enemy_y == fighter_y + 3) ||(enemy_y == fighter_y + 4)) || ((enemy_x == fighter_x) &&(enemy_y == fighter_y + 2))){fighter--;fighter_x = rand() % (height - 5) + 2;fighter_y = rand() % (width - 5) + 2;enemy_x = -1;enemy_y = rand() % width;lose();}if (enemy_x > height) {//如果敌机飞出屏幕则重新生成一架score--;enemy_x = -1;enemy_y = rand() % width;lose();}

目前屏幕的闪烁严重,还存在光标,因此需要一个函数实现清屏效果,这里直接调用了windows.库函数来实现

void zeroXy(int x, int y) {//实现函数清屏HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);COORD pos;pos.X = x;pos.Y = y;SetConsoleCursorPosition(handle, pos);}void hidecursor() {//隐藏光标CONSOLE_CURSOR_INFO consor_info = {1,0 };//第二个值为0隐藏光标SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consor_info);}

最后就是要时刻判断游戏的输赢情况,当生命值为0时或者得分小于0时则游戏失败,再定义一个函数来实现

void lose() {if (fighter < 0 || score < 0) {cout << endl;cout << "**********************你输了!*********************" << endl;system("pause");exit(0);}}

至此飞机大战全部内容就完成了,生成代码如下(包含一个头文件,一个子模块和一个主模块)

//fighter.h文件#ifndef _fighter_h#define _fighter_hvoid drawPicture();void init();void OperateFighter();void pcOperate();void floatBullet();void enemyFighter();void zeroXy(int x, int y);void hidecursor();void lose();#endif

//fighter.cpp文件#include<iostream>#include<conio.h>#include<Windows.h>#include<iomanip>#include"fighter.h"using namespace std;int height = 20;long width = 30;//定义游戏界面长和宽int fighter_x, fighter_y;int bullet_x, bullet_y;int enemy_x, enemy_y;int score;int fighter;string difficulty;void drawPicture() {//x控制行输出,y控制列输出zeroXy(0, 0);cout << setfill('#') << setw(width + 6) << "#" << endl;for (int x = 0; x < height; x++){for (int y = 0; y < width + 1; y++){if (y == 0)cout << "#";else if (y == width){if (x == fighter_x)cout << "#";else if (x == fighter_x + 1)cout << setfill(' ') << "#";else if (x == fighter_x + 2)cout << setfill(' ') << "#";else cout << setfill(' ') << setw(6) << "#";}else if ((x == fighter_x) && (y == fighter_y))cout << setfill(' ') << setw(6) << "* ";else if ((x == fighter_x + 1) && (y == fighter_y))cout << setfill('*') << setw(6) << " ";else if ((x == fighter_x + 2) && (y == fighter_y))cout << setfill(' ') << setw(6) << "* * ";else if ((x == bullet_x) && (y == bullet_y))cout << "|";else if (x == enemy_x && y == enemy_y)cout << "@";else cout << " ";}cout << endl;}cout << setfill('#') << setw(width + 6) << "#" << endl;cout << "难度:" << difficulty << endl;cout << "生命:" << fighter << endl;cout << "得分:" << score << endl;}void init() {fighter_x = height / 2;//定义飞机的位置fighter_y = width / 2;enemy_x = 0;enemy_y = fighter_y;//随机定义敌机位置bullet_x = -2;//定义子弹位置bullet_y = fighter_y;score = 0;//得分数fighter = 3;//飞机生命数hidecursor();}void OperateFighter() {char input;if (_kbhit()) {//检查是否是否有键盘输入,有返回非0,无则返回0input = _getch();//根据用户不同的输入来移动if (input == 'a') {if (fighter_y > 1)fighter_y--;//位置左移}else if (input == 'd') {if (fighter_y < width - 1)fighter_y++;//位置右移}else if (input == 'w') {if (fighter_x > 0)fighter_x--;//位置上移}else if (input == 's') {if (fighter_x < height)fighter_x++;//位置下移}if (input == ' ') {bullet_x = fighter_x - 1;bullet_y = fighter_y + 2;}}}void pcOperate() {//调用函数模拟人操作飞机战斗floatBullet();//调用floatBullet函数控制子弹移动enemyFighter();//控制敌机移动速度}void floatBullet() {//控制子弹移动if (bullet_x > -1)//判断子弹是否在屏幕内bullet_x--;//子弹上移}void enemyFighter() {//用来控制敌机向下移动的速度。每隔十次循环就移动一次敌机static int speed = 0;difficulty = "简单";if (score > 5) {speed++;difficulty = "普通";}if (score > 15) {speed++;difficulty = "困难";}if (speed < 10) {speed += 2;}else {enemy_x++;speed = 0;}//击中敌机后增加判断,并增加变量score记录游戏得分。敌机被击中后会先消失,然后重新在随机位置出现。if (((bullet_x == enemy_x) && (bullet_y == enemy_y)) || ((bullet_x + 1 == enemy_x) &&(bullet_y == enemy_y)) || ((bullet_x - 1 == enemy_x) && (bullet_y == enemy_y))){score++;enemy_x = -1;//产生新的飞机enemy_y = rand() % (width - 5) + 3;//rand()函数生成随机数,但因为一般生成的随机数较大,因此做取余操作使其能在规定的宽度内生成bullet_x = -2;//子弹无效}if ((enemy_x == fighter_x) && ((enemy_y == fighter_y) ||(enemy_y == fighter_y + 1) || (enemy_y == fighter_y + 3) ||(enemy_y == fighter_y + 4)) || ((enemy_x == fighter_x) &&(enemy_y == fighter_y + 2))){fighter--;fighter_x = rand() % (height - 5) + 2;fighter_y = rand() % (width - 5) + 2;enemy_x = -1;enemy_y = rand() % width;lose();}if (enemy_x > height) {//如果敌机飞出屏幕则重新生成一架score--;enemy_x = -1;enemy_y = rand() % width;lose();}}void zeroXy(int x, int y) {//实现函数清屏HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);COORD pos;pos.X = x;pos.Y = y;SetConsoleCursorPosition(handle, pos);}void hidecursor() {//隐藏光标CONSOLE_CURSOR_INFO consor_info = {1,0 };//第二个值为0隐藏光标SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consor_info);}void lose() {if (fighter < 0 || score < 0) {cout << endl;cout << "**********************你输了!*********************" << endl;system("pause");exit(0);}}

//mainfighter文件#include<iostream>#include<conio.h>#include<Windows.h>#include<iomanip>#include"fighter.h"using namespace std;int main() {init();while (1) {drawPicture();pcOperate();OperateFighter();}system("pause");}

运行截图如下:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。