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);

	}
}
相关推荐
Miuney_MAX5 小时前
【单片机】之HC32F460中断向量选择
单片机·嵌入式硬件
XINVRY-FPGA8 小时前
XC3S1000-4FGG320I Xilinx AMD Spartan-3 SRAM-based FPGA
嵌入式硬件·机器学习·计算机视觉·fpga开发·硬件工程·dsp开发·fpga
猫猫的小茶馆11 小时前
【ARM】ARM的介绍
c语言·开发语言·arm开发·stm32·单片机·嵌入式硬件·物联网
猫猫的小茶馆11 小时前
【PCB工艺】数模电及射频电路基础
驱动开发·stm32·单片机·嵌入式硬件·mcu·物联网·pcb工艺
点灯小铭11 小时前
基于单片机的智能药物盒设计与实现
数据库·单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
梓德原11 小时前
【基础】详细分析带隙型稳压电路的工作原理
单片机·嵌入式硬件·物联网
国科安芯12 小时前
航天医疗领域AS32S601芯片的性能分析与适配性探讨
大数据·网络·人工智能·单片机·嵌入式硬件·fpga开发·性能优化
小李做物联网13 小时前
【物联网毕业设计】60.1基于单片机物联网嵌入式项目程序开发之图像厨房监测系统
stm32·单片机·嵌入式硬件·物联网
贝塔实验室14 小时前
新手如何使用Altium Designer创建第一张原理图(三)
arm开发·单片机·嵌入式硬件·fpga开发·射频工程·基带工程·嵌入式实时数据库
@good_good_study14 小时前
STM32 ADC多通道采样实验
stm32·单片机·嵌入式硬件