飞机大战学习心得(Dev-C++)

本文详细介绍了一款基于C语言的飞机大战游戏开发过程,包括游戏界面设计、键盘控制、碰撞检测等功能实现,并增加了用户名、游戏难度选择等附加功能。

在c语言中,我们要用代码来做游戏就必须得去实现代码与图形界面接口的互联,也就是要通过按键的输入与输出来控制游戏的进行,所以以下几个头文件是必不可少的

 stdio函数就不用我多说了。

在这三个基础的头文件下,我们便可以开始进行游戏编写的第一步了.

具体思路:我们可以通过按键改变飞机的位置,只要用两个for循环来重复检测这架飞机的位置,一旦for循环中的所对应的点与目标重合,打印即可,一直重复这个操作就能给我们带来了飞机在移动的动画效果.

//定义变量
int hight,width;       //边界的高度和宽度
int score;            //得分
int blood;             //飞机生命值
int plane_x,plane_y;   //飞机坐标
int enemy_x,enemy_y;   //敌人飞机坐标
int bullet_x,bullet_y; //子弹坐标

先创建变量赋予目标参数

接着可以通过定义多个函数来逐步实现功能

我的第一步思路是先搭建好初始界面,这需要用到调节颜色以及调节光标位置的两个函数

//可以用两种不同的方式来设定字体颜色
//可以用system("color ...")
//也可以用SetConsoleTextAttribute函数 

//我用的是 SetConsoleTextAttribute函数
//先定义一个color函数调用 SetConsoleTextAttribute函数,这样可以随时修改颜色 
 int color(int number)
{
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), number);    //number代表的是第几号颜色 前面的GetStdHandle(STD_OUTPUT_HANDLE)是获取当前窗口权柄,简单来说就是让这个颜色加在这个页面
 return 0;
}
 

//开始界面的设定需要用到定义光标的函数
void gotoxy(int x,int y)
{
	COORD gb;  //windows.h内用于确认光标位置的函数 
  	gb.X=x;
  	gb.Y=y;    //定义光标的xy坐标 
  	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),gb);//同样的(获取权柄,定位)
} 
//接下来可以开始布局初始页面
//定义弹出初始页面的函数
 void Start()
{
char choice;
gotoxy(45,10);
color(14); 
printf("打 飞 机");
gotoxy(20,22);
color(13);
printf("输入1:开始打飞机");
gotoxy(60,22);
printf("输入2:我选择退出");
//scanf("%d",&choice);

while(!kbhit())     //如果不输入数据先进入while循环判断,不用while用if的话会跳过该函数直接执行cycle()
{                   
	choice=getch();   //接收按键内容
	if(choice=='1')   //前面的choice变量要用char定义,这里才能用'1'
	{
				system("cls"); //清屏准备进入游戏 
		//cycle();
		break;
	}
	else if(choice=='2')
	{
				exit(0);    
				break;   //直接结束游戏 
	}
	else
	{
				system("cls"); 
		gotoxy(40,10);
		printf("眼睛不用可以捐掉");
		_getch();       //输入任意键 
		system("cls");   //清屏 
		Start();         //返回初始界面 
	}
}

另外system("cls")是windows.h里的函数,作用是清空屏幕.

getch函数的作用可以参考:getch()函数的使用方法及其返回值问题_灰猫-优快云博客_getch()

具体的光标位置移动和颜色调节函数的学习可以参考以下网址:
c语言pos光标函数用法,SetConsoleCursorPosition()移动光标函数的使用方法_计算智能的博客-优快云博客在C语言中,SetConsoleTextAttribute(参数1,参数2)是设置控制台窗口字体颜色和背景颜色的函数。GetStdHandle(参数)函数用于获得句柄_baiqi123456的博客-优快云博客

 以上函数可以提供初始化页面,也就是相当于你打游戏之前的登陆页面

接下来到要写的东西就是游戏要能运行起来的关键了

  1. void chushihua() //初始化游戏数据(只在进入游戏运行一次)
  2. void Totalscore() //记录分数的函数(需要重复执行)
  3. void cycle() //寻找并打印各个物件位置的函数(需要重复执行)
  4. void Fly() //子弹以及敌人移动的函数(需要重复执行且被动执行)
  5. void Planefly //控制飞机移动并射击的函数  (需要重复执行且主动执行)

进入了游戏后的第一步我们得先初始化一下数据,先得把飞机,敌人和子弹的位置摆好,再把游戏框架设置好.

//先对飞机,敌人和子弹的位置进行初始化
void chushihua()
{
color(11);  //先调色 
hight=20;   //游戏界面高度为20 
width=50;   //游戏界面宽度为50 
score=0;    //初始分数为0 
blood=1;    //只有一条命 
plane_x=width/2;     //接下来设置飞机,敌人和子弹初始坐标 
plane_y=hight-3;
enemy_x=2+rand()%width-2;
enemy_y=0;
bullet_x=plane_x;    //注意:子弹初始的纵坐标要设置在0,这样方便后续设置 
bullet_y=0;

//下面函数用于对光标的隐藏
CONSOLE_CURSOR_INFO guangbiao = {1, 0}; 
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &guangbiao);
} 
//分数显示
void Totalscore()     //在右侧显示分数 
{
	color(13); 
	gotoxy(52,3);
	printf("操作指南");
	gotoxy(52,4);
	printf("按wasd移动,按空格打飞机") ; 
	color(15); 
	gotoxy(52,8);
	printf("你的分数是:%d",score);
		color(11); 
 }

这里下面是初始化后对光标的隐藏,可以参考:控制台界面控制(八):光标设置_bnb45的专栏-优快云博客

框架搭好以后我们接下来就要开始写用于定位并打印飞机,敌人和子弹的函数了

void cycle()
{
int i,j,k;
for(i=0;i<hight;i++)  //这里是通过用两个循环 在一个矩阵里面寻找飞机子弹和敌人的位置并打印出来 
  {
	for(j=0;j<width;j++)
	{
		if(blood==0)
		{
			break;
		}
		else
		{
		if((i==hight-1)||(j==width-1)||(i==0)||(j==0)) //这里是打印矩阵边界 
		{
			printf("+");
		}
		else if((i==plane_y)&&(j==plane_x))            //打印飞机 
		{
			printf("^");
		}
		else if((i==enemy_y)&&(j==enemy_x))            //打印敌人 
		{
			printf("#");
		}
		else if((i==bullet_y)&&(j==bullet_x))          //打印子弹 
		{
			printf("|");
		}
		else
		{
			printf(" ");                         //如果都不是就打印空字符来填充游戏界面 
		}
		}
	}
	printf("\n");                                //这里的换行很重要一定要加 ,不然没法正常显示 
  }	
  printf("\n");
  		if((plane_x==enemy_x)&&(plane_y==enemy_y))  //如果飞机和敌人碰撞,血量-1 
		{
			blood--;                                //这里为了简便处理,可以将飞机碰到敌人被销毁的函数一块写了
		}                                           //这个血量我们可以通过难度调整自定义
}

当以上函数在一个死循环里面运行的时候就可以一直将飞机等的位置实惠实时显示出来,接着,我们就要赋予飞机子弹和敌人“动能”了。

这里我用的是Fly()和Planefly()分别来控制子弹与敌人的自动位移 以及 飞机的主动移动

//定义函数来控制子弹和敌人的移动 
void Fly()
{
static int speed=0;      //这里的static一定要加,不然在死循环中speed会被一直重置为0 
if(speed<30)    //先耗费一段时间让程序执行30次加法再让敌人前进,这样可以减缓前进速度 
  {
	speed++;	
  }
 if(speed==30)                        //每当speed=30的时候才移动一次
  {
 	if(enemy_y<hight)
 	{
 		enemy_y++;	
	}
	else
	{
		enemy_y=0;
  		enemy_x=rand()%(width-2)+2;   //如果飞机碰到边界,重置飞机的位置 
	}
	speed=0;   //每次前进以后都要重置speed这样才能每次都延缓 
  } 
  if(bullet_y>0)   //控制子弹飞行,如果子弹y坐标不为0则开始往前移动一位,连续执行出现飞行动画 
  	{
  		bullet_y--;
	}
  if((bullet_x==enemy_x)&&(bullet_y==enemy_y))
    {
  		score++;
  		bullet_y=0;
  		enemy_y=1;
  		enemy_x=rand()%(width-2)+2;    //这里是意思是随机重置位置,重置范围是(2,(width)-2)
                                       //如果范围不这么写敌人可能会出现在墙缝里面
	}

} 

//定义函数来控制飞机的移动和子弹的发射 
void Planefly()
{
	char shuru;
	if(kbhit()) //kbhit函数是判断是否有输入 
	{
		shuru=getch(); //将输入的值传入shuru里面 
		if((shuru=='w')&&(plane_y>1)) // 如果按下wsad则相应移动飞机的位置 
		{
			plane_y--;
		}
		if((shuru=='s')&&(plane_y<hight-2))
		{
			plane_y++;
		}
		if((shuru=='a')&&(plane_x>1))
		{
			plane_x--;
		}
		if((shuru=='d')&&(plane_x<width-2))
		{
			plane_x++;
		}
		if((shuru==' ')&&(bullet_y==0))   //如果按下空格键,发射子弹
		{
			bullet_x=plane_x;             //这里的意思是将子弹位置同步到飞机位置
			bullet_y=plane_y;             //由上述Fly函数可知,当子弹y坐标>0的时候开始发射
		}
	}
} 

这里的控制时间(speed)的方法是我参考一位大佬的代码得来的,这里的核心是利用程序执行30次加法所带来的时间差来达到一个延时效果,这样每次敌人移动一个位都要等待一段执行30次加法的时间,连贯起来就能做到减速的效果了,可以说是非常的巧妙。

另外speed变量在这条函数内一定要声明为静态局部变量,也就是加static前缀,这样才会使得每次调用Fly函数时speed值不被重置

static的用法可以参考:static变量及其作用,C语言static变量详解 (biancheng.net)及其static变量及其作用,C语言static变量详解 (biancheng.net)

写完上述代码后,程序便可以真正动起来了,可如果飞机销毁,又会怎么样呢?下面就开始写飞机销毁的gameover函数。

//设计游戏结束界面
void gameover()
{
	color(12);
	char choice2;
	system("cls");
	gotoxy(40,22);
	printf("输入1继续打飞机,输入2结束游戏");
	while(!kbhit())  //这里与上面Start函数同理
{
	choice2=getch();
	if(choice2=='1')   //如果输入1则清屏初始化以后重新进入游戏
	{
			system("cls");   
			chushihua();
			cycle();
			break;
	}
	else if(choice2=='2')
	{
			exit(0);
			break;
	}
	else
	{
		gotoxy(40,22);
		printf("皮一下很开心!");
		_getch(); //这里需要注意_getch()和getch()是一样的
		gameover();
	}
}

gameover函数提供了一个结束面板,在飞机销毁以后,可以选择1重新开始游戏,也可以选择2退出游戏

最后我们用一个main函数将所有的子函数串联在一起,最基本的飞机大战就成型了

//设置主函数来启动飞机大战
int main()
{
	system("mode con cols=100 lines=30");  //创建宽100高30的程序界面大小 
	Start();                               //执行Start函数弹出初始界面 
	chushihua();                           //初始化飞机敌人和子弹的位置 
	while(1)                               //通过死循环来重复调用函数达到播放动画的效果 
	{
		gotoxy(0,0);
		cycle();
		Totalscore();
		if(blood==0)
		{
			gameover();
		}
		Fly();                             
		Planefly();   
	}                     //按键检测也要再死循环里面吗,不然只会执行1次 
} 

飞机大战已经可以简单运行了,接下来我们为它添加一些功能

  1. 添加游戏用户名功能
  2. 选择游戏难度功能
  3. 日期功能
  4. 排行榜功能

具体思路:这里的添加用户名的功能可以选择直接用链表,同样的也可以用结构体数组来实现(用结构体更容易理解)。用结构体数组创建排行榜的话只需要用一个变量计数,然后把每个不同的数组打印出来就可以形成不同用户的列表,对列表进行排序可以用到sort函数(不过只能在c++里面用)(推荐打击去学习,非常方便),也可以用结构体排序的方法

sort函数可以参考:C++中sort函数使用方法 - 俊宝贝 - 博客园 (cnblogs.com)

首先,我们需要一个结构体数组来容纳用户的数据

//定义一个结构体来存放用户数据
struct rank 
{   
    char name[100];    //存放用户名 
    char nian,yue,ri,shi,fen,miao;//对应年月日时分秒
	//struct tm *lt;   //通过日期 
	char difficluty[100];  //难度系数 
	double time;       //通关耗时 
	int score;         //个人得分 
}f[5];

然后需要在Start函数里面增加排行榜功能,这里的排行榜我用的是Bool型变量来做开关

创建好结构体数组以后,为程序添加创建用户名功能

//用来创建游戏用户的函数 
void Name(struct rank f[],int num)   //第一个参数是rank结构体数组,第二个参数是用来确定输入的名字存到第几个结构体数组里面 
{
	gotoxy(45,10);
	printf("请输入用户名");
    gotoxy(42,13);
	gets(f[num].name);   //这里将输入的用户名传入相应的结构体的name数组里面 
	system("cls");
}

因为我定义的是函数,所以里面得有参数才能调用对应的数据

下面是选择游戏难度功能

//选择游戏难度
void Difficulty(struct rank f[],int num)   //与上同理 
{
		tt:char d;            //这里的tt:是用来标记开头,方便goto函数的使用 
		gotoxy(45,10);
		printf("请选择游戏难度");
		gotoxy(45,15);
		printf("1.eassy");
		gotoxy(45,20);
		printf("2.middle");
		gotoxy(45,25);
		printf("3.hard");
while(!kbhit()) 
{
	d=getch();	
	if(d=='1')
	{
	strcpy (f[num].difficluty, "eassy" );
	system("cls");
	break;
	}
	else if(d=='2')
	{
	strcpy (f[num].difficluty, "middle" );
	system("cls");
	break;
	}
	else if(d=='3')
	{
	strcpy (f[num].difficluty, "hard" );
	system("cls");
	break;
	}
	else
     goto tt;     //如果输入的不是123那么直接返回开头重新来过 
} 
}

做好这些功能以需要用一个排行榜来把相应的数据显示出来

//创建一个排行榜
void Rank(struct rank f[],int num)
{
	system("cls");
	for(int i=0;i<num;i++)   //这里的for是用来逐一输出每一个用户的数据 
	{   gotoxy(15,8+3*i);
		printf("%d:用户名:%s   ",i+1,f[i].name);
		printf("难度:%s   ",f[i].difficluty);
		printf("得分:%d   ",f[i].score);
		printf("通关日期:%d/%d/%d %d:%d:%d\n",f[i].nian+1900,f[i].yue+1,f[i].ri,f[i].shi, 
 f[i].fen,f[i].miao);   //这里的时间在下面主函数里面有赋值
		//Start();
	}
		getch();
		RANK=0;    //排行榜用完以后要把RANK设置为0,这样才能正常关闭 
		system("cls");
		Start();  //看完以后返回开始界面 
}

goto函数的用法可以参考:C语言goto 函数的用法_Tony.j的博客-优快云博客_goto函数

 最后就是用主函数将上述定义的子函数串联起来

修改以后的主函数如下

bool cmp(rank a,rank b)         //这个cmp是对sort排序规则的定义 
{
	return a.score>b.score;     //a.score>b.score代表排序顺序从大到小 
}

//设置主函数来启动飞机大战
int main()
{
	int num=0;
	system("mode con cols=100 lines=30");  //创建宽100高30的程序界面大小 
	loop:Start();                               //执行Start函数弹出初始界面 
	while(RANK==1)        //这里就是前面所说的用来开关排行榜的函数 
	{
	Rank(f,num);
	}
	Name(f,num);   //Start开始后紧接着是输入用户名 
	Difficulty(f,num);  //输入游戏难度 
	chushihua();                           //初始化飞机敌人和子弹的位置 
	while(1)                               //通过死循环来重复调用函数达到播放动画的效果 
	{
		gotoxy(0,0);
		cycle();
		Totalscore();
		if(blood==0)
		{   time_t t;            //这里是定义时间的函数
 			struct tm *lt;       
 			time(&t); //获取时间戳。 
 			lt=localtime(&t);//转为时间结构。
 			f[num].nian=lt->tm_year; //年 
 			f[num].yue=lt->tm_mon;        //月 
 			f[num].ri=lt->tm_mday;        //日 
 			f[num].shi=lt->tm_hour;       //时 
 			f[num].fen=lt->tm_min;        //分 
 			f[num].miao=lt->tm_sec;       //秒 
 			f[num].lt=lt;      //这里将定义的时间存进结构体数组里面
			f[num].score=score;    //这里必须得提前把分数赋值给对应用户,因为后面分数会清零 
			sort(f,f+5,cmp);       //使用sort函数对排名进行实时排序,要在分数赋值给用户以后再排序 
			gameover();
			num++;     //每次死亡后重开那么用户数量+1 
			if(num==5) //这里设置最多存放五个用户的数据
			num=0; 
			goto loop;   //跳到开头Start的位置重开 
		}
		Fly();                             
		Planefly();   
	}                     //按键检测也要再死循环里面,不然只会执行1次 
} 

获取时间日期的函数可参考:C语言获取当前的日期及时间_HPC&Geophysics攻城狮-优快云博客_c语言获取时间

需要注意的是这里的goto就是跳回开头重开游戏的意思

sort函数在结构体数组中的用法可以参考:sort() 及对结构体数组用sort()的用法_happyaaakkk的博客-优快云博客_sort对结构体数组排序


完整代码如下

#include<algorithm>  //可以不加,此头文件在下面只用于调用 sort 函数 
#include<stdio.h>
#include<iostream>   //可以不加,此头文件在下面只用于调用 sort 函数 
#include<windows.h>  //用于获取窗口的句柄与屏幕控制 
#include<conio.h>    //用于获取键盘输入的内容 
#include <time.h>    //用于控制时间 
using namespace std;         //可以不加,此语句在下面只用于调用 sort 函数 
//定义变量
int hight,width;       //边界的高度和宽度
int score;            //得分
int blood;             //飞机生命值
int plane_x,plane_y;   //飞机坐标
int enemy_x,enemy_y;   //敌人飞机坐标
int bullet_x,bullet_y; //子弹坐标
bool RANK=0;
//定义一个结构体来存放用户数据
struct rank 
{   
    char name[100];    //存放用户名 
    char nian,yue,ri,shi,fen,miao;
	char difficluty[100];  //难度系数 
	double time;       //通关耗时 
	int score;         //个人得分 
}f[5];
//可以用两种不同的方式来设定字体颜色
//可以用system("color ...")
//也可以用SetConsoleTextAttribute函数 

//我用的是 SetConsoleTextAttribute函数
//先定义一个color函数调用 SetConsoleTextAttribute函数,这样可以随时修改颜色 
 int color(int number)
{
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), number);    //number代表的是第几号颜色 
 return 0;
}
//开始界面的设定需要用到定义光标的函数
void gotoxy(int x,int y)
{
	COORD gb;  //windows.h内用于确认光标位置的函数 
  	gb.X=x;
  	gb.Y=y;    //定义光标的xy坐标 
  	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),gb);
} 
//接下来可以开始布局初始页面
//定义弹出初始页面的函数
 void Start()
{
char choice;
gotoxy(45,10);    //因为我在主函数里面定义界面宽100高30,所以光标移动到这些位置会比较合适 
color(14); 
printf("打 飞 机");
gotoxy(20,22);
color(13);
printf("输入1:开始打飞机");
gotoxy(60,22);
printf("输入2:我选择退出");
gotoxy(42,25);
printf("输入3:排行榜"); 
CONSOLE_CURSOR_INFO guangbiao = {1, 0}; 
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &guangbiao);
while(!kbhit()) 
{
	choice=getch();
	if(choice=='1')
	{
				system("cls"); //清屏准备进入游戏 
		//cycle();
		break;
	}
	else if(choice=='2')
	{
				exit(0);    
				break;   //直接结束游戏 
	}
	else if(choice=='3')
	{
				RANK=1;  //这里的RANK是排行榜的开关 ,1开0关 
                break;
	}
	else
	{
				system("cls"); 
		gotoxy(40,10);
		printf("眼睛不用可以捐掉");
		_getch();       //输入任意键 
		system("cls");   //清屏 
		Start();         //返回初始界面 
	}
}
} 
//用来创建游戏用户的函数 
void Name(struct rank f[],int num)   //第一个参数是rank结构体数组,第二个参数是用来确定输入的名字存到第几个结构体数组里面 
{
	gotoxy(45,10);
	printf("请输入用户名");
    gotoxy(42,13);
	gets(f[num].name);   //这里将输入的用户名传入相应的结构体的name数组里面 
	system("cls");
}
//选择游戏难度
void Difficulty(struct rank f[],int num)   //与上同理 
{
		tt:char d;            //这里的tt:是用来标记开头,方便goto函数的使用 
		gotoxy(45,10);
		printf("请选择游戏难度");
		gotoxy(45,15);
		printf("1.eassy");
		gotoxy(45,20);
		printf("2.middle");
		gotoxy(45,25);
		printf("3.hard");
while(!kbhit()) 
{
	d=getch();	
	if(d=='1')
	{
	strcpy (f[num].difficluty, "eassy" );
	system("cls");
	break;
	}
	else if(d=='2')
	{
	strcpy (f[num].difficluty, "middle" );
	system("cls");
	break;
	}
	else if(d=='3')
	{
	strcpy (f[num].difficluty, "hard" );
	system("cls");
	break;
	}
	else
     goto tt;     //如果输入的不是123那么直接返回开头重新来过 
} 
}
//创建一个排行榜
void Rank(struct rank f[],int num)
{
	system("cls");
	for(int i=0;i<num;i++)   //这里的for是用来逐一输出每一个用户的数据 
	{   gotoxy(15,8+3*i);
		printf("%d:用户名:%s   ",i+1,f[i].name);
		printf("难度:%s   ",f[i].difficluty);
		printf("得分:%d   ",f[i].score);
		printf("通关日期:%d/%d/%d %d:%d:%d\n",f[i].nian+1900,f[i].yue+1,f[i].ri,f[i].shi, 
 f[i].fen,f[i].miao); 
		//Start();
	}
		getch();
		RANK=0;    //排行榜用完以后要把RANK设置为0,这样才能正常关闭 
		system("cls");
		Start();  //看完以后返回开始界面 
} 
//先对飞机,敌人和子弹的位置进行初始化
void chushihua()
{
color(11);  //先调色 
hight=20;   //游戏界面高度为20 
width=50;   //游戏界面宽度为50 
score=0;    //初始分数为0 
blood=1;    //只有一条命 
plane_x=width/2;     //接下来设置飞机,敌人和子弹初始坐标 
plane_y=hight-3;
enemy_x=2+rand()%width-2;
enemy_y=0;
bullet_x=plane_x;    //注意:子弹初始的纵坐标要设置在0,这样方便后续设置 
bullet_y=0;
//下面函数用于对光标的隐藏
CONSOLE_CURSOR_INFO guangbiao = {1, 0}; 
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &guangbiao);
} 
//创建循环函数持续检测飞机,子弹和敌人的位置
void cycle()
{
int i,j,k;
for(i=0;i<hight;i++)  //用两个循环 来寻找飞机子弹和敌人的位置并打印出来 
  {
	for(j=0;j<width;j++)
	{
		if(blood==0)
		{
			break;
		}
		else
		{
		if((i==hight-1)||(j==width-1)||(i==0)||(j==0)) //这里是打印边界 
		{
			printf("+");
		}
		else if((i==plane_y)&&(j==plane_x))            //打印飞机 
		{
			printf("^");
		}
		else if((i==enemy_y)&&(j==enemy_x))            //打印敌人 
		{
			printf("#");
		}
		else if((i==bullet_y)&&(j==bullet_x))          //打印子弹 
		{
			printf("|");
		}
		else
		{
			printf(" ");                         //如果都不是就打印空字符填充游戏界面 
		}
		}
	}
	printf("\n");                                //这里的换行很重要一定要加 ,不然没法正常显示 
  }	
  printf("\n");
  		if((plane_x==enemy_x)&&(plane_y==enemy_y))  //如果飞机和敌人碰撞,血量-1 
		{
			blood--;
		}
} 
//分数显示
void Totalscore()     //再右侧显示分数 
{
	color(13); 
	gotoxy(52,3);
	printf("操作指南");
	gotoxy(52,4);
	printf("按wasd移动,按空格打飞机") ; 
	color(15); 
	gotoxy(52,8);
	printf("你的分数是:%d",score);
		color(11); 
 } 
//定义函数来控制子弹和敌人的移动 
void Fly()
{
static int speed=0;   //这里的static一定要加,不然在死循环中speed会被一直重置为0 
if(speed<30)    //先耗费一段时间让程序执行30次加法再让敌人前进,这样可以减缓前进速度 
  {
	speed++;	
  }
 if(speed==30)
  {
 	if(enemy_y<hight)
 	{
 		enemy_y++;	
	}
	else
	{
		enemy_y=0;
  		enemy_x=rand()%(width-2)+2;   //如果飞机碰到边界,重置飞机的位置 
	}
	speed=0;   //每次前进以后都要重置speed这样才能每次都延缓 
  } 
  if(bullet_y>0)   //控制子弹飞行,如果子弹y坐标不为0则开始自动飞行 
  	{
  		bullet_y--;
	}
  if((bullet_x==enemy_x)&&(bullet_y==enemy_y))
    {
  		score++;
  		bullet_y=0;
  		enemy_y=1;
  		enemy_x=rand()%(width-2)+2;    //这里是意思是随机重置位置,重置范围是(2,(width)-2) 
	}
} 
//定义函数来控制飞机的移动和子弹的发射 
void Planefly()
{
	char shuru;
	if(kbhit()) //kbhit函数是判断是否有输入 
	{
		shuru=getch(); //将输入的值传入shuru里面 
		if((shuru=='w')&&(plane_y>1)) //如果按下wsad则相应移动飞机的位置 
		{
			plane_y--;
		}
		if((shuru=='s')&&(plane_y<hight-2))
		{
			plane_y++;
		}
		if((shuru=='a')&&(plane_x>1))
		{
			plane_x--;
		}
		if((shuru=='d')&&(plane_x<width-2))
		{
			plane_x++;
		}
		if((shuru==' ')&&(bullet_y==0))
		{
			bullet_x=plane_x;
			bullet_y=plane_y;
		}
	}
} 
//设计游戏结束界面
void gameover()
{
	color(12);
	char choice2;
	system("cls");
	gotoxy(40,22);
	printf("输入1继续打飞机,输入2结束游戏");
	//scanf("%d",&choice2);
	//system("cls");
	while(!kbhit()) 
{
	choice2=getch();
	if(choice2=='1')
	{
			system("cls");
			//Start();
			//cycle();
			break;
	}
	else if(choice2=='2')
	{
			exit(0);
			break;
	}
	else
	{
		system("cls");
		gotoxy(40,22);
		printf("皮一下很开心是吧!");
		_getch();
		gameover();
	}
}
 } 
bool cmp(rank a,rank b)         //这个cmp是对sort排序规则的定义 
{
	return a.score>b.score;     //a.score>b.score代表排序顺序从大到小 
}
//设置主函数来启动飞机大战
int main()
{
	int num=0;
	system("mode con cols=100 lines=30");  //创建宽100高30的程序界面大小 
	loop:Start();                               //执行Start函数弹出初始界面 
	while(RANK==1)        //这里就是前面所说的用来开关排行榜的函数 
	{
	Rank(f,num);
	}
	Name(f,num);   //Start开始后紧接着是输入用户名 
	Difficulty(f,num);  //输入游戏难度 
	chushihua();                           //初始化飞机敌人和子弹的位置 
	while(1)                               //通过死循环来重复调用函数达到播放动画的效果 
	{
		gotoxy(0,0);
		cycle();
		Totalscore();
		if(blood==0)
		{	time_t t;            //前四行函数是用来定义时间的 
 			struct tm *lt; 
 			time(&t); //获取时间戳。 
 			lt=localtime(&t);//转为时间结构。
 			f[num].nian=lt->tm_year; //年 
 			f[num].yue=lt->tm_mon;        //月 
 			f[num].ri=lt->tm_mday;        //日 
 			f[num].shi=lt->tm_hour;       //时 
 			f[num].fen=lt->tm_min;        //分 
 			f[num].miao=lt->tm_sec;       //秒 
			f[num].score=score;    //这里必须得提前把分数赋值给对应用户,因为后面分数会清零 
			sort(f,f+5,cmp);       //使用sort函数进行实时排序,要在分数赋值给用户以后再排序 
			gameover();
			num++;     //每次死亡后重开那么用户数量+1 
			if(num==5) //这里设置最多存放五个用户的数据
			num=0; 
			goto loop;   //跳到开头Start的位置重开 
		}
		Fly();                             
		Planefly();   
	}                     //按键检测也要再死循环里面,不然只会执行1次 
} 




感谢米娜桑看到最后,祝各位新年快乐!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值