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