大一下要交课程设计,于是就用C语言写了一个飞机大战小游戏 ,没有用到第三方库,飞机和子弹的移动使用的光标移动函数,所以没有卡顿
其中w s a d分别表示上下左右(包括大写),空格发射子弹,游戏结束后可选择是否储存游戏数据,该程序复制后可直接使用,也可根据喜好进行修改
运行截图如下:
代码如下:
#include <stdio.h>
#include <string.h>
#include <windows.h> //包含对光标进行的操作
#include <conio.h> //包含输入函数getch()
#include <stdlib.h> //包含随机函数
#include <time.h> //获取系统当前时间
#define HIGHT 30 //操作界面高度
#define WIGHT 40 //操作界面宽度
typedef struct
{
int x;
int y;
} BULLET;
typedef struct
{
int x;
int y;
int speed;
int life;
BULLET bullet[20]; //子弹数量
int num; //子弹计数
} PLANE;
typedef struct
{
int x;
int y;
int life;
int move_step;
} ENEMY;
typedef struct
{
int num; //敌机个数
int produce_interval; //敌机产生间隔
int produce_step;
int move_interval; //控制敌机移动
} ENEMY_DATA;
//定义全局变量
int choice; //菜单页选项
int record; //决定是否记录分数
int a[30][120];
int score; //分数
int escape; //未击落的敌机数
PLANE plane;
ENEMY_DATA en_da;
ENEMY enemy[10];
void Hide() //隐藏光标
{
CONSOLE_CURSOR_INFO cursor_info = {1, 0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
void goto_xy(int x, int y) //移动光标
{
HANDLE hOut;
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos = {x, y};
SetConsoleCursorPosition(hOut, pos);
}
void create_enemy() //创建敌机
{
srand((unsigned int)time(NULL));
enemy[en_da.num].y = 1;
do
{
enemy[en_da.num].x = rand() % WIGHT;
} while (enemy[en_da.num].x == 0 || enemy[en_da.num].x == WIGHT); //防止生成的敌机位于边界
enemy[en_da.num].life = 1;
if (en_da.num == 9)
en_da.num = 0;
else
en_da.num++;
}
void initialize_data() //初始化数据
{
plane.life = 3;
plane.speed = 1;
plane.x = WIGHT / 2 - 1;
plane.y = HIGHT - 6;
for (int i = 0; i < 20; i++)
{
plane.bullet[i].x = plane.x;
plane.bullet[i].y = 0;
}
en_da.produce_step = 0;
en_da.produce_interval = 20;
en_da.num = 0;
for (int i = 0; i < 10; i++) //初始化敌机
{
enemy[i].life = 0;
enemy[i].move_step = 0;
enemy[i].y = 0;
}
en_da.move_interval = 5;
plane.num = 0;
score = 0;
escape = 0;
create_enemy();
}
void update() //更新数据
{
if (en_da.produce_step == en_da.produce_interval) //产生敌机
{
create_enemy();
en_da.produce_step = 0;
}
else
en_da.produce_step++;
for (int i = 1; i < 30; i++)
{
for (int j = 0; j < 120; j++)
a[i][j] = 0;
}
//边界
for (int i = 1; i < HIGHT; i++)
{
a[i][0] = 8;
a[i][WIGHT] = 8;
}
//飞机位置刷新
a[plane.y][plane.x] = 1;
a[plane.y + 1][plane.x - 2] = 1;
a[plane.y + 1][plane.x - 1] = 1;
a[plane.y + 1][plane.x] = 1;
a[plane.y + 1][plane.x + 1] = 1;
a[plane.y + 1][plane.x + 2] = 1;
a[plane.y + 2][plane.x - 1] = 1;
a[plane.y + 2][plane.x + 1] = 1;
//子弹位置刷新
for (int i = 0; i < 20; i++)
{
a[plane.bullet[i].y][plane.bullet[i].x] = 2;
if (plane.bullet[i].y > 0) //子弹移动
plane.bullet[i].y--;
}
//敌机位置刷新
for (int i = 0; i <= 10; i++)
{
if (enemy[i].y < HIGHT && enemy[i].life == 1)
{
if (enemy[i].move_step == en_da.move_interval)
{
enemy[i].y++;
enemy[i].move_step = 0;
}
else
enemy[i].move_step++;
}
}
//碰到飞机或是敌机越界后飞机减血
for (int i = 0; i <= 10; i++)
{
if (enemy[i].y == HIGHT) //越界
{
escape++;
enemy[i].y = 0;
}
//碰到飞机
if ((enemy[i].y == plane.y && enemy[i].x == plane.x) ||
(enemy[i].y == plane.y + 1 && enemy[i].x == plane.x - 2) ||
(enemy[i].y == plane.y + 1 && enemy[i].x == plane.x - 1) ||
(enemy[i].y == plane.y + 1 && enemy[i].x == plane.x + 1) ||
(enemy[i].y == plane.y + 1 && enemy[i].x == plane.x + 2))
{
plane.life--;
enemy[i].life = 0;
enemy[i].y = 0;
}
}
//击毁敌机后加分
for (int i = 0; i < 20; i++)
{
for (int j = 0; j <= 10; j++)
{
if ((enemy[j].y == plane.bullet[i].y && enemy[j].x == plane.bullet[i].x) && enemy[j].life == 1)
{
score++;
enemy[j].life = 0;
enemy[j].y = 0;
plane.bullet[i].y = 0; //子弹消失
}
}
}
//敌机位置刷新
for (int i = 0; i < 10; i++)
a[enemy[i].y][enemy[i].x] = -1;
}
void Print() //打印界面
{
for (int i = 0; i < 16; i++)
printf("-");
printf("飞机大战");
for (int i = 0; i < 16; i++)
printf("-");
printf("\n");
for (int i = 1; i < HIGHT - 1; i++)
{
for (int j = 0; j < 120; j++)
{
if (a[i][j] == -1)
printf("+");
else if (a[i][j] == 1)
printf("*");
else if (a[i][j] == 2)
printf("|");
else if (a[i][j] == 0)
printf(" ");
else if (a[i][j] == 8)
printf("#");
}
}
printf("score:%d life:%d escape:%d", score, plane.life, escape);
}
void move() //控制飞机移动
{
char key;
if (kbhit())
{
key = getch();
if (key == 'w' || key == 'W')
{
if (plane.y > 1) //控制飞机不超过上界
plane.y -= plane.speed;
}
if (key == 'a' || key == 'A')
{
if (plane.x > 1) //控制飞机不超过左界
plane.x -= plane.speed;
}
if (key == 's' || key == 'S')
{
if (plane.y < HIGHT - 4) //控制飞机不超过下界
plane.y += plane.speed;
}
if (key == 'd' || key == 'D')
{
if (plane.x < WIGHT - 1) //控制飞机不超过右界
plane.x += plane.speed;
}
if (key == ' ')
{
plane.bullet[plane.num].x = plane.x;
plane.bullet[plane.num].y = plane.y - 1;
plane.num++;
if (plane.num == 20)
plane.num = 0;
}
}
}
void view_history()
{
FILE *history;
history = fopen("biubiubiu_score.txt", "r");
if (history == NULL)
printf("文件不存在,请先创建!\n");
else
{
char ch;
ch = getc(history);
while (ch != EOF)
{
putchar(ch);
ch = getc(history);
}
printf("\n");
}
fclose(history);
}
void record_history()
{
FILE *history;
history = fopen("biubiubiu_score.txt", "a");
if (history == NULL)
printf("打开文件失败!\n");
else
{
char date[30];
//获取系统当前时间
time_t t;
struct tm *now;
t = time(NULL);
now = localtime(&t);
strcpy(date, asctime(now));
int len = strlen(date);
date[len - 1] = '\0'; //去除时间结尾的换行符
fputs(date, history);
fputs(" ", history);
fprintf(history, "score:%d", score);
fputs(" ", history);
fprintf(history, "escape:%d\n", escape);
}
fclose(history);
}
void menu()
{
printf(" 主菜单\n");
printf("0、退出游戏\n");
printf("1、开始游戏\n");
printf("2、查看历史分数\n");
scanf("%d", &choice);
switch (choice)
{
case 0:
exit(0); //退出程序
break;
case 1:
system("cls");
return;
break;
case 2:
system("cls");
view_history();
system("pause");
system("cls");
menu(); //递归调用
break;
default:
printf("输入错误,请重新输入!\n");
system("pause");
system("cls");
menu(); //递归调用
break;
}
}
void end()
{
system("cls");
printf("GAME OVER!\n");
printf("你的得分是:%d\n", score);
printf("是否记录分数?\n");
printf("1、yes\n");
printf("2、no\n");
scanf("%d", &record);
switch (record)
{
case 1:
record_history();
printf("记录成功!");
system("pause");
break;
case 2:
printf("未记录!");
system("pause");
return;
break;
default:
printf("输入错误,请重新输入!\n");
system("pause");
system("cls");
end(); //递归调用
break;
}
}
int main()
{
system("color 9f");
while (1)
{
menu();
Hide();
initialize_data();
while (1)
{
update();
if (plane.life <= 0)
break; //生命值为零退出游戏
Print();
goto_xy(0, 0);
move();
}
end();
system("cls");
}
return 0;
}