问题描述
使用根据坐标输出地图的方法,编写空战小游戏,并且有以下特性:
(1)拥有主菜单;
(2)多关卡,无上限,每关卡得分满100即进入下一关卡;
(3)一架我机,拥有血量,使用方向键移动,空格发射子弹,X键发射霰弹(有次数限制);
(4)同屏五架敌机,各自可自主移动(移动速度随关卡增大而增快),随机发射子弹;
(5)敌我机碰撞,敌机坠毁,我机扣血;
(6)打满五架敌机即随机刷新补给箱;
(7)补给箱可被敌我机拾取,我机拾取时产生随机增益(补充霰弹发射次数1次或回血1点);
问题分析
题目中关键问题及思路为:
(1)将游戏过程拆分为初始化与游戏循环两个阶段;
(2)初始化阶段构建函数void init(int ex[],int ey[]),对我机坐标mx,my,敌机坐标ex[],ey[]进行赋值;
(3)游戏循环阶段分为重画地图,无键盘操作和键盘操作三个步骤;
(4)重画地图步骤构建函数void ReDraw(),清屏后根据要求、按坐标输出整个地图;
(5)无键盘操作阶段构建函数void ShowWithoutInput(int ex[],int ey[]),进行游戏结束,游戏过关,产生补给箱,补给箱拾取,敌我机碰撞的判断,及敌机的自主移动与随机发射子弹;
(6)键盘操作阶段构建函数void ShowWithInput(int ex[],int ey[]),根据用户输入,进行我机发射子弹,发射霰弹;
流程图
大致流程图为:
代码
#include <iostream>
#include <cstdlib>
#include <conio.h>
#include <windows.h>
#include <ctime>
using namespace std;
#define Height 15
#define Width 25
#define MyBlood 5
#define gShotNum 3
#define eNumSameScreen 5
int canvas[Height][Width]={0};// 游戏画布
int mx,my;// 我机位置
int sx,sy;// 补给箱位置
int score=0;// 得分
int blood=MyBlood;// 我机初始血量
int shot=gShotNum;// 霰弹发射次数
int supNum=0;// 同屏补给包数量
int GameLevel=1;// 关卡
int EnemySpeed=50;// 敌机移动速度
int speed=0;
void gotoxy(int x,int y)// 光标移动到(x,y)位置,x是横坐标,y是纵坐标
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(handle,pos);
}
void hidden()// 隐藏光标
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cci;
GetConsoleCursorInfo(hOut,&cci);
cci.bVisible=0;// 赋1为显示,赋0为隐藏
SetConsoleCursorInfo(hOut,&cci);
}
void MainManu()// 主菜单
{
void PlayGame();
void QuitGame();
char i;
system("cls");
puts("1.Play Gmae");
puts("2.Quit Game");
cin>>i;
while(i!='1' && i!='2')
{
puts("Please enter again:");
cin>>i;
}
if(i=='1') PlayGame();
else if(i=='2') QuitGame();
}
void QuitGame()// 退出游戏
{
void MainManu();
char i;
puts("Make sure that you want to quit (Y/N)");
cin>>i;
while(i!='Y' && i!='y' && i!='N' && i!='n')
{
puts("Please enter again:");
cin>>i;
}
if(i=='Y' || i=='y') exit(0);
else if(i=='N' || i=='n') MainManu();
}
void PlayGame()// 进行游戏
{
void hidden();
void init(int ex[],int ey[]);
void ReDraw();
void ShowWithoutInput(int ex[],int ey[]);
void ShowWithInput(int ex[],int ey[]);
int ex[eNumSameScreen],ey[eNumSameScreen];
hidden();
init(ex,ey);
while(1)
{
ReDraw();
ShowWithoutInput(ex,ey);
ShowWithInput(ex,ey);
}
}
void init(int ex[],int ey[])// 初始化
{
int i;
srand(time(NULL));
mx=(Width-1)/2;
my=Height-1;
canvas[my][mx];
for(i=0;i<=eNumSameScreen-1;i++)
{
ex[i]=rand()%Width;
ey[i]=rand()%2;
canvas[ey[i]][ex[i]];
}
}
void ReDraw()// 输出游戏画布
{
void gotoxy(int x,int y);
int i,j;
system("cls");
gotoxy(0,0);
for(i=0;i<=Height-1;i++)
{
for(j=0;j<=Width-1;j++)
{
if(canvas[i][j]==0)
cout<<' ';
else if(canvas[i][j]==1)
cout<<'*';
else if(canvas[i][j]==2)
{cout<<'|';canvas[i][j]=0;}
else if(canvas[i][j]==3)
cout<<'#';
else if(canvas[i][j]==4)
cout<<'$';
}
cout<<endl;
}
gotoxy(Width+10,5);
cout<<"Score:"<<score;
gotoxy(Width+10,6);
cout<<"Blood:"<<blood;
gotoxy(Width+10,7);
cout<<"Shot:"<<shot;
gotoxy(Width+10,8);
cout<<"EnemySpeed:"<<EnemySpeed;
gotoxy(Width+10,9);
cout<<"GameLevel:"<<GameLevel;
}
void ShowWithoutInput(int ex[],int ey[])
{
void ReDraw();
int i,j,p;
srand(time(NULL));
GameLevel=1+score/100;
if(blood<=0)
{
system("cls");
gotoxy(Width/2,Height/2-1);
cout<<"Game Over"<<endl;
cout<<"Your have reached stage:"<<GameLevel;
gotoxy(Width+10,5);
cout<<"Score:"<<score;
gotoxy(Width+10,6);
cout<<"Blood:"<<blood;
gotoxy(Width+10,7);
cout<<"Shot:"<<shot;
Sleep(1000);
exit(0);
}
if(score!=0 && score%100==0)
{
system("cls");
gotoxy(Width/2,Height/2);
cout<<"Next Mission";
Sleep(25);
ReDraw();
}
if(score!=0 && score%50==0 && supNum<1)
{
supNum++;
sx=rand()%Width;
sy=rand()%Height;
canvas[sy][sx]=4;
}
if(canvas[sy][sx]==1 && supNum>0)
{
supNum--;
canvas[sy][sx]=0;
p=rand()%2;
if(p==0) shot++;
else if(p==1) blood++;
}
if(canvas[sy][sx]==2 && supNum>0)
supNum--;
EnemySpeed=50-5*GameLevel;
if(EnemySpeed>=10)
EnemySpeed=10;
if(speed==EnemySpeed)
{
speed=0;
for(i=0;i<=eNumSameScreen-1;i++)
{
canvas[ey[i]][ex[i]]=0;
ex[i]+=rand()%3-1;
ey[i]++;
if(ex[i]<0) ex[i]=0;
else if(ex[i]>Width-1) ex[i]=Width-1;
canvas[ey[i]][ex[i]]=3;
if(ey[i]>Height-1)
{
blood--;
score-=10;
ex[i]=rand()%Width;
ey[i]=rand()%2;
canvas[ey[i]][ex[i]]=3;
}
p=rand()%10;
if(p==1)
{
for(j=ey[i]+1;j<=Height-1;j++)
canvas[j][ex[i]]=2;
if(supNum>0)
canvas[sy][sx]=4;
}
if(ex[i]==mx)
blood--;
}
}
else speed++;
for(i=0;i<=eNumSameScreen-1;i++)
{
if(ex[i]==mx && ey[i]==my)
{
blood--;
score+=10;
ex[i]=rand()%Width;
ey[i]=rand()%2;
}
}
}
void ShowWithInput(int ex[],int ey[])
{
char input;
int i,j;
if(kbhit())
{
input=getch();
if(input==75 && mx>0)
{canvas[my][mx]=0;mx--;canvas[my][mx]=1;}
else if(input==77 && mx<Width-1)
{canvas[my][mx]=0;mx++;canvas[my][mx]=1;}
else if(input==72 && my>0)
{canvas[my][mx]=0;my--;canvas[my][mx]=1;}
else if(input==80 && my<Height-1)
{canvas[my][mx]=0;my++;canvas[my][mx]=1;}
else if(input==' ')
{
for(i=my-1;i>=0;i--)
canvas[i][mx]=2;
if(supNum>0)
canvas[sy][sx]=4;
for(i=0;i<=eNumSameScreen-1;i++)
{
if(mx==ex[i])
{
score+=10;
ex[i]=rand()%Width;
ey[i]=rand()%2;
canvas[ey[i]][ex[i]]=3;
}
}
}
else if((shot>0) && (input=='X' || input=='x'))
{
shot--;
for(j=mx-1;j<=mx+1;j++)
{
for(i=my-1;i>=0;i--)
canvas[i][j]=2;
if(supNum>0)
canvas[sy][sx]=4;
for(i=0;i<=eNumSameScreen-1;i++)
{
if(j==ex[i])
{
score+=10;
ex[i]=rand()%Width;
ey[i]=rand()%2;
canvas[ey[i]][ex[i]]=3;
}
}
}
}
}
}
int main()
{
void MainManu();
MainManu();
return 0;
}