- //#define _CRT_SECURE_NO_WARNINGS 1 用于禁止不安全函数的警告
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- 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);
-
- }
- }
-
-
-
-