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

news/2024/6/3 17:45:39 标签: 单片机, stm32, 嵌入式硬件

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

	}
}





http://www.niftyadmin.cn/n/5392731.html

相关文章

openssl3.2 - crypto-mdebug被弃用后, 内存泄漏检查的替代方法

文章目录 openssl3.2 - crypto-mdebug被弃用后, 内存泄漏检查的替代方法概述笔记查看特性列表openssl3.2编译脚本 - 加入enable-crypto-mdebug看看有没有替代内存诊断的方法?main.cppmy_openSSL_lib.hmy_openSSL_lib.c备注备注END openssl3.2 - crypto-mdebug被弃用后, 内存泄…

【JVM】线上一次fullGC排查思路

fullGC问题背景 监控告警发现&#xff0c;今天开始我们线上应用频繁出现fullGC&#xff0c;并且每次出现后磁盘都会被占满 查看监控 查看监控发现FULLGC的机器均为同一个机房的集器&#xff0c;并且该机房有线上error报错&#xff0c;数据库监控对应的时间点也有异常&#x…

自然语言处理Gensim入门:建模与模型保存

文章目录 自然语言处理Gensim入门&#xff1a;建模与模型保存关于gensim基础知识1. 模块导入2. 内部变量定义3. 主函数入口 (if __name__ __main__:)4. 加载语料库映射5. 加载和预处理语料库6. 根据方法参数选择模型训练方式7. 保存模型和变换后的语料8.代码 自然语言处理Gens…

15.openEuler SSH管理及安全

openEuler OECA认证辅导,标红的文字为学习重点和考点。 如果需要做实验,建议安装麒麟信安、银河麒麟、统信等具有图形化的操作系统,其安装与openeuler基本一致。 1.SSH服务搭建 安装SSH服务总共需要至少三个套件,包括: openssh、openssh-server、openssh-clients open…

1904_ARM Cortex M系列芯片特性小结

1904_ARM Cortex M系列芯片特性小结 全部学习汇总&#xff1a; g_arm_cores: ARM内核的学习笔记 (gitee.com) ARM Cortex M系列的MCU用过好几款了&#xff0c;也涉及到了不同的内核。不过&#xff0c;关于这些内核的基本的特性还是有些不了解。从ARM的官方网站上找来了一个对比…

SpringAMQP消息队列

安装RabbitMQ 在linux上安装RabbitMQ,并运行 docker run \-e RABBITMQ_DEFAULT_USERzywzy \-e RABBITMQ_DEFAULT_PASS123321 \--name mq \--hostname mq1 \-p 15672:15672 \-p 5672:5672 \-d \rabbitmq:3-managementhttp://ip:15672 访问控制台, 用户名zywzy,密码123321 引入…

springboot项目打成含crud操作的sdk集成到springboot启动引擎项目

一 sdk配置操作 1.1 结构 sdk项目目录中只有基础的service类以及mybatis操作数据库的相关文件&#xff0c;service类中包含查询数据库的方法。 说明&#xff1a; 1.2 sdk的pom打包配置 作为公共项目打成jar供其他项目引用&#xff0c;注意被引入的项目不能使用默认的maven…

Node.js-文件读取输入

Node.js-文件读取输入 fs模块&#xff08;操作文件的模块&#xff09; 读取 fs.readFile(path[, options], callback)&#xff1b;[]里面 是可选参数&#xff0c;表示以什么样的编码 格式读取path是路径callback表示读取完成后的回调函数 例子 fs.readFile (‘./files/11.txt…