C++ 游戏飞机大战, 字符型的

cpp 复制代码
//#define _CRT_SECURE_NO_WARNINGS 1  用于禁止不安全函数的警告
#include<iostream>
#include<stdlib.h>
#include<string>
#include<conio.h>
#include<Windows.h>
#include<time.h>
#include <graphics.h>
using namespace std;
char ch;
#define Count 5//敌机数量
#define Col 40//列
#define Row 40//行
//玩家飞机坐标,声明:左上角坐标为(0,0)
int PlayerPlane_y = Row - 2;//39,墙上面最后一行
int PlayerPlane_x = Col / 2;//20,列中央
//子弹坐标
int Bullet_y;
int Bullet_x;
//敌机坐标
int Enemy_y[Count] = { 0 };
int Enemy_x[Count] = { 0 };
//敌机的移动速度
int EnemySleep = 250;
int sleep = 0;//当二者相等时敌机才发生移动,sleep可认为缓冲,该设置用于控制速度与难度梯度
//分数
int score = 0;
//技能充能
int skill1 = 20;
int skill2 = 5;
//容错度
int error = 0;//抵达五时失败
//获取系统时间
char* time()//返回指针
{
	time_t rawtime;//原始时间
	struct tm* curtime;//指向结构体的变量
	time(&rawtime); // 获取系统时间并存储
	curtime = localtime(&rawtime); //转换为本地时间
	char* now = asctime(curtime);//更改为指针类型
	return now;
}
//弄一个结构体保存当前位置的各项数据,但是不保存已使用的子弹,以此来实现简单存档
typedef struct history
{
	int PlayerPlane_y;
	int PlayerPlane_x;
	int Enemy_y[Count];
	int Enemy_x[Count];
	int EnemySleep;
	int sleep;
	int score;
	int skill1;
	int skill2;
	int error;
	char* curtime;
	int flag = 0;//初始化标记
}history, * apple;
void contain(apple& L, int PlayerPlane_y, int PlayerPlane_x, int EnemySleep, int sleep, int score, int skill1, int skill2, int error, int flag, char* curtime)
{
	L = new history;//赋予空间
	L->PlayerPlane_y = PlayerPlane_y;
	L->PlayerPlane_x = PlayerPlane_x;
	L->EnemySleep = EnemySleep;
	L->sleep = sleep;
	L->score = score;
	L->skill1 = skill1;
	L->skill2 = skill2;
	L->error = error;
	L->flag = flag;
	L->curtime = curtime;
}
void game();//有关进入游戏后的各项函数
void menu()
{
	printf("                                           --------------飞机大作战--------------\n");
	printf("                                          |                                       |\n");
	printf("                                          |             3.查看历史记录            |\n");
	printf("                                          |             2.选择存档开始            |\n");
	printf("                                          |             1.开始游戏                |\n");
	printf("                                          |             0.退出游戏                |\n");
	printf("                                          |             W/A/S/D移动               |\n");
	printf("                                          |           空格射击 E/R技能            |\n");
	printf("                                          |                                       |\n");
	printf("                                          |w温馨提示,游戏过程中可以按下\"Esc\"退出游戏 |\n");
	printf("                                          ----------------------------------------------\n");
}

int main()
{
	system("color b");
	int input = 0;
	menu();
	printf("请选择:");
	scanf("%d", &input);
	switch (input)
	{
	case 1:
		game();//大部分函数均包括在内
		break;
	case 0:
		printf("退出游戏\n");
		break;
	default:
		printf("输入有误,请重新输入:\n");
		break;
	}
	return 0;
}
//隐藏光标
void HideCursor()
{
	CONSOLE_CURSOR_INFO cursor_info = { 1,0 };  //第二个值为0,表示隐藏光标
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

// 光标移到(X, Y)位置
void gotoxy(int x, int y)
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos;
	pos.X = x;
	pos.Y = y;
	SetConsoleCursorPosition(handle, pos);
}

void DisPlay(int arr[Col][Row])//绘制画面
{
	gotoxy(0, 0);
	for (int i = 0; i < Col; i++)
	{
		for (int j = 0; j < Row; j++)
		{
			if (arr[i][j] == 0)//路
			{
				printf("  ");
			}
			if (arr[i][j] == 1)//基地区域
			{
				printf("█");
			}
			if (arr[i][j] == 2)//己方
			{
				printf("++");
			}
			if (arr[i][j] == 3)//敌机
			{
				printf("%%+");
			}
			if (arr[i][j] == 4)//子弹
			{
				printf("/\\");
			}
		}
		printf("\n");
	}
	//各项数值
	char* curtime = time();
	printf("得分:%d ", score);
	printf("EnemySleep=%d ", EnemySleep);
	printf("skill1(20)=%d ", skill1);
	printf("skill2(5)=%d ", skill2);
	printf("时间:%s", curtime);
	Sleep(20);//刷新频率
}

void InSet(int arr[Col][Row])
{
	srand(time(NULL));//设置随机数种子
	//路--0
	//墙--1
	for (int i = 0; i < Col; i++)//赋值定义
	{
		arr[i][0] = 1;
		arr[i][Row - 1] = 1;
	}
	for (int i = 0; i < Row; i++)
	{
		arr[0][i] = 1;
		arr[Col - 1][i] = 1;
	}
	//玩家飞机--2
	arr[PlayerPlane_y][PlayerPlane_x] = 2;//一开始在中央
	//敌机--3
	for (int i = 0; i < Count; i++)//随机出现敌机
	{
		Enemy_y[i] = rand() % 3 + 1;//确保敌机不出现在墙区域,并且不会太接近下方基地
		Enemy_x[i] = rand() % (Row - 2) + 1;//确保不会出现在墙中
		arr[Enemy_y[i]][Enemy_x[i]] = 3;//敌机位置
	}
	//子弹--4
}
void PlayerPlay(int arr[Col][Row])
{

	if ((ch == 'w' || ch== 72) && arr[PlayerPlane_y - 1][PlayerPlane_x] == 0)//上飞,且路通
	{
		arr[PlayerPlane_y][PlayerPlane_x] = 0;//清除
		PlayerPlane_y--;//数值小则上
		arr[PlayerPlane_y][PlayerPlane_x] = 2;//飞机位置
	}
	if ((ch == 'a' || ch== 75) && arr[PlayerPlane_y][PlayerPlane_x - 1] == 0)//下述同理
	{
		arr[PlayerPlane_y][PlayerPlane_x] = 0;
		PlayerPlane_x--;
		arr[PlayerPlane_y][PlayerPlane_x] = 2;
	}
	if ((ch == 's' || ch == 80) && arr[PlayerPlane_y + 1][PlayerPlane_x] == 0)
	{
		arr[PlayerPlane_y][PlayerPlane_x] = 0;
		PlayerPlane_y++;
		arr[PlayerPlane_y][PlayerPlane_x] = 2;
	}
	if ((ch == 'd' || ch == 77) && arr[PlayerPlane_y][PlayerPlane_x + 1] == 0)
	{
		arr[PlayerPlane_y][PlayerPlane_x] = 0;
		PlayerPlane_x++;
		arr[PlayerPlane_y][PlayerPlane_x] = 2;
	}
	if (ch == ' ')//空格射击
	{
		Bullet_y = PlayerPlane_y - 1;
		Bullet_x = PlayerPlane_x;
		arr[Bullet_y][Bullet_x] = 4;//子弹位置
	}
	if (ch == 'r')//技能
	{
		if (skill1 == 20)//充能结束
		{
			for (int i = 1; i < Row - 1; i++)//火力覆盖
			{
				skill1 = 0;//归零
				Bullet_y = PlayerPlane_y - 1;//上飞,完成后一行子弹上飞到顶
				Bullet_x = i;//布满横行
				arr[Bullet_y][Bullet_x] = 4;//位置
			}
		}
	}
	if (ch == 'e')//技能
	{
		int left = PlayerPlane_x - 3;//左线
		int right = PlayerPlane_x + 3;//右线
		if (skill2 == 5)//充能
		{
			for (int i = left; i < right; i++)//火力覆盖
			{
				if (i > 0 && i < Row - 1)//可见r技能火力充足
				{
					skill2 = 0;//归零
					Bullet_y = PlayerPlane_y - 1;//上飞,几颗子弹到顶
					Bullet_x = i;
					arr[Bullet_y][Bullet_x] = 4;
				}
			}
		}
	}

}
void BulletEnemy(int arr[Col][Row])//关于子弹与敌机的处理,包括能量与加速的处理
{

	for (int i = 0; i < Col; i++)
	{
		for (int j = 0; j < Row; j++)
		{
			if (arr[i][j] == 4)//有子弹
			{
				for (int k = 0; k < Count; k++)//检查各个敌机
				{
					//子弹击中敌机的处理
					if (i == Enemy_y[k] && j == Enemy_x[k])
					{
						if (skill1 < 20)
						{
							skill1++;
						}
						if (skill2 < 5)
						{
							skill2++;
						}
						score += 100;//分数
						arr[Enemy_y[k]][Enemy_x[k]] = 0;//清除
						Enemy_y[k] = rand() % 3 + 1;
						Enemy_x[k] = rand() % (Row - 2) + 1;
						arr[Enemy_y[k]][Enemy_x[k]] = 3;//重构
						//每500分敌机加速
						if (score % 500 == 0 && EnemySleep > 4)
						{
							EnemySleep -= 2;
						}
					}
				}

				//子弹的移动
				if (arr[i][j] == 4)
				{
					arr[i][j] = 0;
					if (i > 1)
					{
						arr[i - 1][j] = 4;
					}
				}
			}
		}

		//敌机的移动,sleep初始0
		if (sleep < EnemySleep)
		{
			sleep++;
		}
		else if (sleep > EnemySleep)
		{
			sleep = 0;
		}

		for (int i = 0; i < Count; i++)//遍历敌机
		{
			if (PlayerPlane_y == Enemy_y[i] && PlayerPlane_x == Enemy_x[i] || score < 0)
			{
				printf("  /\\_/\\  \n");//敌机击中玩家飞机的处理
				printf(" ( o.o ) \n");
				printf("  > ^ < \n");
				printf("游戏失败!\n");
				printf("\a");//发出失败警告
				system("pause");//等待
				exit(0);
			}
			//敌机到达最底面的处理
			if (Enemy_y[i] >= Col - 2)//提前处理,不破坏墙面,当然不提前处理也没问题,可以设1
			{
				score -= 100;
				arr[Enemy_y[i]][Enemy_x[i]] = 0;
				Enemy_y[i] = rand() % 3 + 1;
				Enemy_x[i] = rand() % (Row - 2) + 1;
				arr[Enemy_y[i]][Enemy_x[i]] = 3;
			}
			//敌机下移的处理
			if (sleep == EnemySleep)
			{
				for (int j = 0; j < Count; j++)
				{
					arr[Enemy_y[j]][Enemy_x[j]] = 0;
					sleep = 0;
					Enemy_y[j]++;
					arr[Enemy_y[j]][Enemy_x[j]] = 3;
				}
			}
		}
	}
}
void write(apple& L, FILE* fp)//传引用,避免指针的使用
{
	L->curtime = time();
	fprintf
	(fp, "%d %d %d %d %d %d %d %d %d %s ",
		L->PlayerPlane_y,
		L->PlayerPlane_x,
		L->EnemySleep,
		L->sleep,
		L->score,
		L->skill1,
		L->skill2,
		L->error,
		L->flag,
		*(L->curtime));
	for (int i = 0; i < Count; i++)
		fprintf(fp, "%d %d", L->Enemy_y[i], L->Enemy_x[i]);
}
void creathistory(apple& L)//创建存档
{

	FILE* fp;
	if ((fp = fopen("history.txt", "a+")) == NULL) { cout << "打开失败,没有存档,请建立新的存档"; system("pause"); exit(0); }
	else
	{
		write(L, fp);
	}
}
void read(apple& L)
{
	FILE* fp;
	if ((fp = fopen("history.txt", "a+")) == NULL) { cout << "打开失败,没有存档,请建立新的存档"; system("pause"); exit(0); }
	else
	{
		int PlayerPlane_y;
		int PlayerPlane_x;
		int Enemy_y[Count];
		int Enemy_x[Count];
		int EnemySleep;
		int sleep;
		int score;
		int skill1;
		int skill2;
		int error;
		char* curtime;
		int flag;
		while (fscanf
		(fp, "%d %d %d %d %d %d %d %d %d %s\n",
			&L->PlayerPlane_y,
			&L->PlayerPlane_x,
			&L->EnemySleep,
			&L->sleep,
			&L->score,
			&L->skill1,
			&L->skill2,
			&L->error,
			&L->flag,
			L->curtime))
		{
			for (int i = 0; i < Count; i++)
				fscanf(fp, "%d %d", L->Enemy_y[i], L->Enemy_x[i]);
		}
		rewind(fp);//指针归位
	}
}
void again(apple& L)
{
	int arr[Col][Row] = { 0 };
	for (int i = 0; i < Count; i++)
	{
		arr[L->Enemy_y[i]][L->Enemy_x[i]] = 3;
	}
	arr[L->PlayerPlane_y][L->PlayerPlane_x] = 2;
	for (int i = 0; i < Col; i++)//赋值定义
	{
		arr[i][0] = 1;
		arr[i][Row - 1] = 1;
	}
	for (int i = 0; i < Row; i++)
	{
		arr[0][i] = 1;
		arr[Col - 1][i] = 1;
	}
	//打印游戏界面
	DisPlay(arr);
	//玩家移动
	while (1)
	{
		//时间
		time();
		//玩家操作
		PlayerPlay(arr);
		//打印棋盘
		DisPlay(arr);
		//子弹与敌机的操作
		BulletEnemy(arr);
	}
}
void findhistory(apple& L)//查找存档
{
	for (int i = 0; i < L->flag; i++)
	{
		read(L);
		printf("请输入你选择的存档编号flag:");
		int a = getch();
		cout << a << endl;
		if (_kbhit() && i == L->flag - 1)//判断是否有键盘输入
		{
			system("cls");
			again(L);

		}
	}
}

void game()
{
	system("cls");
	//设置一个存放信息的数组
	int arr[Col][Row] = { 0 };
	apple L;
	//隐藏光标
	//HideCursor();
	//放置信息
	InSet(arr);
	//打印游戏界面
	DisPlay(arr);
	//玩家移动
	while (1)
	{
		if (_kbhit()) {
			ch = getch();
				if (ch == 27) {
					cout << "是否退出并保存存档" << endl;
						system("pause");
						if (getch() == 27)
						{
							creathistory(L);
								cout << "存档成功,继续按键将退出" << endl;
								system("pause");
								exit(0);
						}
				}
				else
				{
					time();
					//玩家操作
					PlayerPlay(arr);
				}

		}
		//打印棋盘
		DisPlay(arr);
		//子弹与敌机的操作
		BulletEnemy(arr);

	}
}
相关推荐
is081510 分钟前
简说stm32的startup.s文件和ld链接脚本
stm32
我不是加奈7 小时前
QMC5883L的驱动
c语言·驱动开发·单片机·嵌入式硬件
ICGOODFIND18 小时前
电子接口与微控制器核心知识:串口、并口、USB、UART、RS232/RS485、ESP32与STM32详解
单片机·嵌入式硬件
qq_2151383278 小时前
【Proteus仿真】【32单片机-A012】GP2D12红外测距系统设计
单片机·mongodb·proteus
合方圆~小文11 小时前
架空线路图像视频监测装置
c语言·c++·人工智能·嵌入式硬件·硬件工程·模拟退火算法
passer__jw76716 小时前
【51单片机】2. 进阶点灯大师
单片机·51单片机
Immortals_wang17 小时前
MCU Keil中支持的变量类型和定义方法
单片机·嵌入式硬件
胡Jason17 小时前
GPIO_Analog与ADC什么区别
单片机·嵌入式硬件
Fang_pi_dai_zhi17 小时前
经典的多位gpio初始化操作
单片机·嵌入式硬件
技术流浪者18 小时前
PCB设计实践(三十五)STM32与ESP32的核心应用场景及选型
嵌入式硬件·硬件工程·pcb设计