#C++# 空战实习

问题描述

使用根据坐标输出地图的方法,编写空战小游戏,并且有以下特性:
(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;
}

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值