C语言之飞机大战游戏
weixin_38554391 人气:0技术原型
1、void gotoxy(int x, int y) 函数,该函数可以使光标去到(x,y)的位置进行打印;
2、链表,用于存储状态;
3、windows.h中有非阻塞输入,_kbhit();
4、随机生成数;
5、视觉暂留;
6、碰撞检测;
7、清屏函数;
8、设置边界;
技术路线
1、设置一个边界;
2、维护一个子弹的列表;
3、维护一个敌机的列表;
4、初始化飞机的位置;
5、每隔一秒钟生成一架敌机,生成位置x坐标随机,坐标为0;
6、设置点击空格生成子弹;
7、设置while(1)循环,在其中每次进行清屏和更新;
8、每次更新遍历子弹链表,使所有子弹的位置向上移动1;
9、每次更新遍历敌机链表,使所有敌机的位置向下移动1;
10、碰撞检测,遍历子弹和敌机列表,发现碰撞则从各自的链表中移除碰撞的节点;
11、当有敌机碰撞到本机游戏结束;
12、当子弹或者敌机碰撞到边界,则从链表中移除;
13、每次检测到碰撞加一分。
实现效果
花费时间
约6小时30分钟
代码
#include <stdio.h> #include <stdlib.h> #include <conio.h> #include <time.h> #include <windows.h> #include <math.h> struct node { int x; int y; struct node* next; }; typedef struct node node_t; typedef struct node* nodeptr_t; void gotoxy(int x, int y); //光标定位函数 void print_plane(int x, int y); //打印飞机 nodeptr_t generate_bullet(nodeptr_t listnode, int x, int y); //生成子弹 void print_bullet(nodeptr_t listnode); //打印子弹 nodeptr_t update_bullet(nodeptr_t listnode); //更新子弹位置 nodeptr_t generate_target(nodeptr_t listnode, int x); //生成敌机 void print_target(nodeptr_t listnode); //打印敌机 nodeptr_t update_target(nodeptr_t listnode); //更新敌机位置 int collision_detection(nodeptr_t bulletlist, nodeptr_t targetlist); //碰撞检测 bool is_gameover(int x,int y, nodeptr_t targetlist); // 游戏结束 void clear(nodeptr_t bulletlist, nodeptr_t targetlist); int main() { int plane_x = 0, plane_y = 19; //飞机位置 char control; //输入 bool isfire = 0; //是否开火 nodeptr_t target = nullptr; //敌机链表 target = (nodeptr_t)malloc(sizeof(node_t)); target->next = nullptr; target->x = 0; target->y = 0; nodeptr_t bullet = nullptr; //子弹链表 bullet = (nodeptr_t)malloc(sizeof(node_t)); bullet->next = nullptr; bullet->x = 0; bullet->y = 0; int subtime = 0; time_t starttime; starttime = time(NULL); int grade = 0; //分数 int targetspeed = 0; int bulletspeed = 0; while(1) { system("cls"); time_t currenttime; currenttime = time(NULL); //每隔一秒生成一架敌机 if (currenttime - starttime - subtime > 0) { srand((unsigned)time(NULL)); unsigned int target_y = rand() % 14 + 3; target = generate_target(target, target_y); } subtime = currenttime - starttime; //开火则生成子弹 if (isfire) { bullet = generate_bullet(bullet, plane_x, plane_y - 1); isfire = 0; } //打印敌机 print_target(target); targetspeed++; if(targetspeed % 2 == 0) target = update_target(target); //打印子弹 print_bullet(bullet); bulletspeed++; if (bulletspeed % 2 == 0) bullet = update_bullet(bullet); //碰撞检测 grade = grade + collision_detection(bullet, target); gotoxy(0, 25); printf("SCORE: %d", grade); //打印飞机 print_plane(plane_x, plane_y); //敌机本机是否相撞 bool isgameover = is_gameover(plane_x, plane_y, target); //Sleep(100); //非阻塞键盘输入 if (isgameover) { clear(target, bullet); plane_x = 0; plane_y = 19; isfire = 0; system("cls"); gotoxy(8, 8); printf("SCORE: %d", grade); gotoxy(8, 9); printf("GAME OVER"); grade = 0; break; } if (_kbhit()) { control = _getch(); if (control == ' ') isfire = 1; else isfire = 0; if (control == 'w' && plane_y > 0) plane_y--; if (control == 's' && plane_y < 20) plane_y++; if (control == 'a' && plane_x > 0) plane_x--; if (control == 'd' && plane_x < 20) plane_x++; } } return 0; } void gotoxy(int x, int y)//光标定位函数 { COORD p;//定义结构体变量p HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);//获取当前函数句柄 p.X = x; p.Y = y;//将光标的目标移动位置传递给结构体 SetConsoleCursorPosition(handle, p);//移动光标 return; } void print_plane(int x, int y) //打印飞机 { if (x == 0) { gotoxy(x, y); printf("*"); gotoxy(x, y + 1); printf("***"); gotoxy(x, y + 2); printf(" *"); } else if (x == 1) { gotoxy(x, y); printf("*"); gotoxy(x-1, y + 1); printf("****"); gotoxy(x-1, y + 2); printf("* *"); } else if (x == 20) { gotoxy(x, y); printf("*"); gotoxy(x - 2, y + 1); printf("***"); gotoxy(x - 1, y + 2); printf("* "); } else if (x == 19) { gotoxy(x, y); printf("*"); gotoxy(x - 2, y + 1); printf("****"); gotoxy(x - 1, y + 2); printf("* *"); } else { gotoxy(x, y); printf("*"); gotoxy(x - 2, y + 1); printf("*****"); gotoxy(x - 1, y + 2); printf("* *"); } return; } nodeptr_t generate_bullet(nodeptr_t listnode, int x, int y) { nodeptr_t newbullet = nullptr; //子弹链表 newbullet = (nodeptr_t)malloc(sizeof(node_t)); newbullet->next = listnode->next; newbullet->x = x; newbullet->y = y; listnode->next = newbullet; return listnode; } void print_bullet(nodeptr_t listnode) { nodeptr_t templist = listnode; while (templist->next != nullptr) { gotoxy((templist->next->x), templist->next->y); printf("|"); templist = templist->next; } return; } nodeptr_t update_bullet(nodeptr_t listnode) { nodeptr_t templist = listnode; while (templist->next != nullptr) { if (templist->next->y > 0) (templist->next->y)--; else { nodeptr_t tempnode = templist->next; templist->next = tempnode->next; tempnode->next = nullptr; free(tempnode); } if (templist->next != nullptr) templist = templist->next; else break; } return listnode; } nodeptr_t generate_target(nodeptr_t listnode, int x) { nodeptr_t newtarget = nullptr; //子弹链表 newtarget = (nodeptr_t)malloc(sizeof(node_t)); newtarget->next = listnode->next; newtarget->x = x; newtarget->y = 0; listnode->next = newtarget; return listnode; } void print_target(nodeptr_t listnode) { nodeptr_t templist = listnode; while(templist->next != nullptr) { gotoxy(templist->next->x, templist->next->y); printf("+"); templist = templist->next; } return; } nodeptr_t update_target(nodeptr_t listnode) { nodeptr_t templist = listnode; while (templist->next != nullptr) { if (templist->next->y < 21) (templist->next->y)++; else { nodeptr_t tempnode = templist->next; templist->next = tempnode->next; tempnode->next = nullptr; free(tempnode); } if (templist->next != nullptr) templist = templist->next; else break; } return listnode; } int collision_detection(nodeptr_t bulletlist, nodeptr_t targetlist) { int grade = 0; nodeptr_t tempbulletlist = bulletlist; while(tempbulletlist->next != nullptr) { nodeptr_t temptargetlist = targetlist; while(temptargetlist->next != nullptr) { if(temptargetlist->next->x == (tempbulletlist->next->x) && temptargetlist->next->y > tempbulletlist->next->y) { nodeptr_t tempnode = temptargetlist->next; temptargetlist->next = tempnode->next; tempnode->next = nullptr; free(tempnode); tempnode = tempbulletlist->next; tempbulletlist->next = tempnode->next; tempnode->next = nullptr; free(tempnode); grade++; break; } if (temptargetlist->next != nullptr) temptargetlist = temptargetlist->next; else break; } if (tempbulletlist->next != nullptr) tempbulletlist = tempbulletlist->next; else break; } return grade; } bool is_gameover(int x, int y, nodeptr_t targetlist) { nodeptr_t temptargetlist = targetlist; while (temptargetlist->next != nullptr) { int tempsub = abs((temptargetlist->next->x) - x); if (tempsub == 0 && temptargetlist->next->y > y) { return 1; } else if(tempsub == 1 && temptargetlist->next->y > y + 1) { return 1; } else if (tempsub == 2 && temptargetlist->next->y > y + 1) { return 1; } temptargetlist = temptargetlist->next; } return 0; } void clear(nodeptr_t bulletlist, nodeptr_t targetlist) { while (bulletlist->next != nullptr) { nodeptr_t temp = bulletlist->next; bulletlist->next = temp->next; //temp->next = nullptr; free(temp); } while (targetlist->next != nullptr) { nodeptr_t temp = targetlist->next; targetlist->next = temp->next; //temp->next = nullptr; free(temp); } return; }
加载全部内容