C语言飞机大战小游戏(2万字!完整精讲解版+源代码)

  • 运行效果
  • 项目技术点
    • 1、启动欢迎界面
    • 2、游戏运行界面
    • 3、结束界面
    • 4、其他功能
  • 细节注意
  • 命名规范
  • 主要思想
  • 代码详解
    • 函数定义
      • 1、界面函数
      • 2、绘制与清除飞机函数
      • 3、运行刷新函数
      • 4、碰撞检测函数
      • 5、结束函数
      • 6、随机位置生成函数
    • 界面控制常量
    • 结构体
      • 1、创建己方飞机位置结构体
      • 2、创建敌方飞机位置结构体
      • 3、创建己方飞机炮弹结构体
      • 4、创建敌方飞机炮弹结构体
      • 5、创建敌方飞机横坐标随机参数及飞机大小
      • 6、创建敌方飞机移动随机参数
    • 开辟内存
      • 1、开辟指针型己方及敌方内存
      • 2、开辟指针型己方及敌方飞机炮弹内存
    • 光标操作
    • 简单绘制
      • 1、启动图案及版权绘制
      • 1、绘制墙壁
      • 2、绘制清除飞机和炮弹
    • 碰撞判断
      • 1、我方碰撞
      • 2、敌方碰撞
    • 主要业务逻辑
      • 1、敌方飞机移动
      • 2、重绘
    • 结束游戏
    • 绘制总控
  • 总代码

运行效果


项目技术点

1、启动欢迎界面

  • 界面绘制
  • 大小控制
  • 按任意键启动游戏

2、游戏运行界面

  • 飞机样式
  • 键盘控制
  • 炮弹飞行路线
  • 飞机炮弹升级
  • 飞机升级
  • 炮弹离开界面消失
  • 炮弹命中响应
  • 敌方飞机自动生成
  • 界面刷新

3、结束界面

  • 结束界面显示
  • 按任意键结束

4、其他功能

  • 分数显示
  • 分数更新

细节注意

当使用vs编译器以上应该添加依据宏定义,因为有些函数已经过时了

#define _CRT_SECURE_NO_WARNINGS

因为要实时接收键盘按键进行响应,getchar()效果不是太好,所以用windows.h里面的函数

#include<Windows.h>

因为要随机生成敌方飞机,所以要引入time.h,来依照当前时间随机生成数字

#include<time.h>

由于代码过长以及命名结构问题,代码中使用了重载技术,在新建工程时要选择新建C++项目,C项目时会报错

命名规范

我方飞机 Fly
敌方飞机 DisFly
绘制我方飞机 DrawFly
绘制敌方飞机 DrawDisFly
重新绘制我方飞机 ReDrawFly
重新绘制敌方飞机 ReDrawDisFly
我方飞机炮弹 FlyBoo
敌方飞机炮弹 DisFlyBoo
我方飞机是否被命中 isFlyBoo
敌方飞机是否被命中 isDisFlyBoo

主要思想

核心主要依靠Sleep函数进行控制游戏的速度,由于CPU运行速度非常快,所以使用Sleep来减慢速度

其实使用Sleep相当于每隔一段时间绘制一张的图片,每个100毫秒绘制一次,也就是界面刷新一次

int SleepTime = 100
void runGame(){while (1){       //进行游戏循环isFlyBoo();isDisFlyBoo();ReDrawFly();ReDrawDisFly();ReDrawFlyBoo();ReDrawDisFlyBoo();DisFlyMove();isUpFly();isUpDisFly();score();Sleep(SleepTime);}
}

代码详解

函数定义

1、界面函数

这部分代码用来控制游戏界面

void Cursor(int x, int y);                   //光标定位函数
void Draw();                                //绘制初始化界面
void copy();                                //绘制图标游戏名及版本号
void DrawWall();                            //绘制墙壁
void runGame();                             //游戏运行
void score();                               //得分系统

2、绘制与清除飞机函数

void DrawFly();                              //绘制己方飞机
void CleanFly();                            //清除己方飞机
void DrawDisFly();                          //绘制敌方飞机
void CleanDisFly();                         //清除敌方飞机
void DrawFlyBoo();                          //绘制己方飞机炮弹
void DrawFlyBoo(int x, int y);              //重载绘制带位置参数的己方炮弹
void CleanFlyoo();                          //清除己方炮弹
void CleanFlyBoo(int x,int y);              //重载清除带位置参数的己方炮弹
void DrawDisFlyBoo();                       //绘制敌方飞机炮弹
void DrawDisFlyBoo(int x,int y);            //重载绘制带位置参数的敌方炮弹
void CleanDisFlyBoo();                      //清除敌方炮弹
void CleanDisFlyBoo(int x,int y);           //重载清除带位置参数的敌方炮弹

3、运行刷新函数

void ReDrawFly();                            //重新绘制己方飞机
void ReDrawDisFly();                        //重新绘制敌方飞机
void ReDrawFlyBoo();                        //重新绘制己方炮弹
void ReDrawDisFlyBoo();                     //重新绘制敌方炮弹
void DisFlyMove();                          //控制敌方炮弹移动

4、碰撞检测函数

void isFlyBoo();                         //判断敌方飞机炮弹是否碰撞到己方飞机
void isDisFlyBoo();                         //判断己方飞机炮弹是否碰撞到敌方飞机
void isUpFly();                             //判断己方飞机是否升级
void isUpDisFly();                          //判断敌方飞机是否升级

5、结束函数

void OverDisFly();                           //结束敌方飞机生命
void OverFly();                             //结束己方飞机生命

6、随机位置生成函数

void ProductDisFlyRander();                  //生成敌方飞机横坐标随机位置
void MoveDisFlyRander();                    //生成敌方飞机移动随机值

界面控制常量

static const int Wall_x = 130;              //设置墙壁宽度值
static const int Wall_y = 40;              //设置墙壁高度值//设置刷新间隔时间SleepTime
//循环计数标志i
//当前循环计数标志i_now
//每次击中敌方飞机得分XXadd
//总得分XXscore
//当前击中敌方飞机得分XXscore_noe。
int SleepTime = 100, i = 0,i_now = 0;
int XXadd = 100, XXscore = 0, XXscore_now = 0;

结构体

1、创建己方飞机位置结构体

struct _Fly{int x, y;
};

2、创建敌方飞机位置结构体

struct Dis_Fly{int x, y;
};

3、创建己方飞机炮弹结构体

struct FlyBoo{int x, y;struct FlyBoo *next;
};

4、创建敌方飞机炮弹结构体

struct DisFlyBoo{int x, y;struct DisFlyBoo *next;
};

5、创建敌方飞机横坐标随机参数及飞机大小

struct DisFlyRander{int disflyRander_x;int disflybig;
}disflyRander;

6、创建敌方飞机移动随机参数

struct DisFlyMoveRander{int moveRander;
}disflymoveRander;

开辟内存

1、开辟指针型己方及敌方内存

_Fly* fly = (_Fly*)malloc(sizeof(_Fly));
Dis_Fly* disfly = (Dis_Fly*)malloc(sizeof(Dis_Fly));

2、开辟指针型己方及敌方飞机炮弹内存

FlyBoo* flyboo = (FlyBoo*)malloc(sizeof(FlyBoo));
DisFlyBoo* disflyboo = (DisFlyBoo*)malloc(sizeof(DisFlyBoo));

光标操作

void Cursor(int x, int y){COORD cursor;                                      //实例化结构体HANDLE hOutput;                                     //实例化句柄cursor.X = x;                                       //传入横坐标参数cursor.Y = y;                                     //传入纵坐标参数hOutput = GetStdHandle(STD_OUTPUT_HANDLE);            //获取输出框界面句柄SetConsoleCursorPosition(hOutput, cursor);           //定位坐标位置
}

简单绘制

1、启动图案及版权绘制

void copy(){Cursor(0,Wall_y / 2 - 6 );printf("    **********************                           *                       *\n");printf("                              *                               *                 *\n");printf("                            *                                    *            *\n");printf("                          *                                        *        *\n");printf("                        *                                            *    *\n");printf("                      *                                                **\n");printf("                    *                                                  **\n");printf("                  *                                                    **\n");printf("                *                                                      **\n");printf("              *                                                        **\n");printf("            *                                                          **\n");printf("         ***********************                                       **             。          。          。\n");Cursor(Wall_x-20, Wall_y );printf("打飞机   V 1.0");Cursor(0, Wall_y);     //使光标处在左下角
}

1、绘制墙壁

void DrawWall(){for (int i = 1; i < Wall_x; i+=2){Cursor(i, 0);        //定位上方墙壁printf("┰");      //绘制上方墙壁Cursor(i, Wall_y);  //定位下方墙壁printf("┸");      //绘制下方墙壁}
}

2、绘制清除飞机和炮弹

void DrawFly(){Cursor(fly->x, fly->y);             //定位己方待绘制飞机位置printf("◢■◣");                   //绘制己方飞机
}void CleanFly(){Cursor(fly->x, fly->y);              //定位己方待清除飞机位置printf("     ");                 //清除己方飞机
}void DrawDisFly(){Cursor(disfly->x, disfly->y);      //定位敌方待绘制飞机位置printf("◥□◤");                   //绘制敌方飞机
}void CleanDisFly(){Cursor(disfly->x, disfly->y);     //定位敌方待清除飞机位置printf("     ");                 //清除敌方飞机
}void DrawFlyBoo(){Cursor(flyboo->x, flyboo->y);      //定位己方待绘制炮弹位置printf("★");                     //绘制己方炮弹
}void DrawFlyBoo(int x, int y){Cursor(x, y);                        //定位己方待绘制炮弹位置printf("★");                     //绘制己方炮弹
}void CleanFlyBoo(){Cursor(flyboo->x, flyboo->y);     //定位己方待清除炮弹位置printf("  ");                        //清除己方炮弹
}
void CleanFlyBoo(int x,int y){Cursor(x, y);                     //定位己方待清除炮弹位置printf("  ");                        //清除己方炮弹
}void DrawDisFlyBoo(){Cursor(disflyboo->x, disflyboo->y); //定位敌方待绘制炮弹位置printf("☆");                     //绘制敌方炮弹
}void DrawDisFlyBoo(int x, int y){Cursor(x, y);                     //定位敌方待绘制炮弹位置printf("☆");                     //绘制敌方炮弹
}void CleanDisFlyBoo(){Cursor(disflyboo->x, disflyboo->y);    //定位敌方待清除炮弹位置printf("  ");                        //清除敌方炮弹
}void CleanDisFlyBoo(int x,int y){Cursor(x, y);                     //定位敌方待清除炮弹位置printf("  ");                        //清除敌方炮弹
}

碰撞判断

1、我方碰撞

void isFlyBoo(){DisFlyBoo* temp_disflyboo = (DisFlyBoo*)malloc(sizeof(DisFlyBoo));  //开辟指针型临时敌方飞机炮弹内存temp_disflyboo = disflyboo;                                           //通过临时变量进行下游遍历查找do{if ((temp_disflyboo->x >= fly->x) && (temp_disflyboo->x <= fly->x + 6) && (temp_disflyboo->y == fly->y - 1))    //当敌方飞机炮弹位于己方飞机平面坐标时OverFly();                                                  //执行结束己方飞机生命函数temp_disflyboo = temp_disflyboo->next;                            //指向下游节点} while (temp_disflyboo != NULL);                                  //遍历至最后一枚敌方炮弹}

2、敌方碰撞

void isDisFlyBoo(){FlyBoo* temp_flyboo = (FlyBoo*)malloc(sizeof(FlyBoo));               //开辟指针型临时己方飞机炮弹内存temp_flyboo = flyboo;                                             //通过临时变量进行下游遍历查找do{if ((temp_flyboo->x >= disfly->x) && (temp_flyboo->x <= disfly->x + 6) && (temp_flyboo->y == disfly->y + 1))   //当己方飞机炮弹位于敌方飞机平面坐标时OverDisFly();                                               //执行结束敌方飞机生命函数temp_flyboo = temp_flyboo->next;                              //指向下游节点} while (temp_flyboo != NULL);                                     //遍历至最后一枚己方炮弹
}

主要业务逻辑

1、敌方飞机移动

void DisFlyMove(){MoveDisFlyRander();                                                    //调用随机函数生成运动随机数if (!(disfly->x > Wall_x - 5 && disflymoveRander.moveRander > 0) && !(disfly->x < 5 && disflymoveRander.moveRander < 0)){//控股敌方飞机运动至墙面边界时无法持续滑动CleanDisFly();                                                  //将原有敌方飞机清除disfly->x += disflymoveRander.moveRander;                       //向指定随机方向进行运动DrawDisFly();                                                  //重新绘制敌方飞机}
}

2、重绘

void ReDrawFlyBoo(){FlyBoo* temp_flyboo = (FlyBoo*)malloc(sizeof(FlyBoo));          //开辟指针型己方临时飞机炮弹内存temp_flyboo->next = NULL;                                      //将其链接接口赋值为空//清除原有己方飞机炮弹temp_flyboo = flyboo;                              //通过临时变量进行下游查找遍历do{                                                 //至少进行一次遍历,普适第一枚己方炮弹CleanFlyBoo(temp_flyboo->x,temp_flyboo->y);        //清除己方飞机炮弹temp_flyboo = temp_flyboo->next;              //指向下游节点} while (temp_flyboo != NULL);                     //遍历至最后一枚己方炮弹//将每个炮弹进行向上移动temp_flyboo = flyboo;                                //通过临时变量进行下游查找遍历do{                                                 //至少进行一次遍历,普适第一枚己方炮弹temp_flyboo->y -= 1;                         //将每一枚己方炮弹纵坐标减一temp_flyboo = temp_flyboo->next;             //指向下游节点} while (temp_flyboo != NULL);                     //遍历至最后一枚己方炮弹//依照当前己方飞机链接新炮弹FlyBoo* next_flyboo = (FlyBoo*)malloc(sizeof(FlyBoo)); //开辟指针型递进己方飞机炮弹内存next_flyboo->x = fly->x + 2;                           //通过当前己方飞机横坐标位置定位己方炮弹横坐标位置next_flyboo->y = fly->y - 1;                           //通过当前己方飞机纵坐标位置定位己方炮弹纵坐标位置next_flyboo->next = flyboo;                               //将炮弹首部控制在前端flyboo = next_flyboo;//将己方炮弹全部重绘temp_flyboo = flyboo;                             //通过临时变量进行下游查找遍历do{                                                 //至少进行一次遍历,普适第一枚己方炮弹DrawFlyBoo(temp_flyboo->x, temp_flyboo->y);        //绘制己方炮弹temp_flyboo = temp_flyboo->next;                //指向下游节点} while (temp_flyboo != NULL);                     //遍历至最后一枚己方炮弹//判断己方炮弹是否超出画布if (i > 5){                                                           //避免己方初始炮弹无二阶next指向temp_flyboo = flyboo;                                           //通过临时变量进行下游查找遍历while (temp_flyboo->next->next != NULL)                          //查找至炮弹第后三个,避免无法指定释放内存炮弹上游指向为空temp_flyboo = temp_flyboo->next;                           //指向下游节点if (temp_flyboo->next->y <= 1){                                   //当己方飞机炮弹末端纵坐标小于墙面时CleanFlyBoo(temp_flyboo->next->x, temp_flyboo->next->y); //清除己方飞机炮弹free(temp_flyboo->next);                                   //释放己方飞机炮弹末端内存空间temp_flyboo->next = NULL;                                   //使被释放空间上游节点指向为空}}i++;                                                                //运行循环次数递增
}void ReDrawDisFlyBoo(){DisFlyBoo* temp_disflyboo = (DisFlyBoo*)malloc(sizeof(DisFlyBoo)); //开辟指针型敌方临时飞机炮弹内存temp_disflyboo->next = NULL;                                       //将其链接接口赋值为空//清除原有敌方飞机炮弹temp_disflyboo = disflyboo;                                            //通过临时变量进行下游查找遍历do{                                                                 //至少进行一次遍历,普适第一枚敌方炮弹CleanDisFlyBoo(temp_disflyboo->x,temp_disflyboo->y);           //清除敌方飞机炮弹temp_disflyboo = temp_disflyboo->next;                            //指向下游节点} while (temp_disflyboo != NULL);                                  //遍历至最后一枚敌方炮弹//将每个炮弹进行向上移动temp_disflyboo = disflyboo;                                          //通过临时变量进行下游查找遍历do{                                                                 //至少进行一次遍历,普适第一枚敌方炮弹temp_disflyboo->y += 1;                                         //将每一枚敌方炮弹纵坐标减一temp_disflyboo = temp_disflyboo->next;                           //指向下游节点} while (temp_disflyboo != NULL);                                  //遍历至最后一枚敌方炮弹//依照当前敌方飞机链接新炮弹DisFlyBoo* next_disflyboo = (DisFlyBoo*)malloc(sizeof(DisFlyBoo)); //开辟指针型递进敌方飞机炮弹内存next_disflyboo->x = disfly->x + 2;                                 //通过当前敌方飞机横坐标位置定位敌方炮弹横坐标位置next_disflyboo->y = disfly->y + 1;                                    //通过当前敌方飞机纵坐标位置定位敌方炮弹纵坐标位置next_disflyboo->next = disflyboo;                                 //将炮弹首部控制在前端disflyboo = next_disflyboo;//将敌方炮弹全部重绘temp_disflyboo = disflyboo;                                         //通过临时变量进行下游查找遍历do{                                                                 //至少进行一次遍历,普适第一枚敌方炮弹DrawDisFlyBoo(temp_disflyboo->x, temp_disflyboo->y);           //绘制敌方炮弹temp_disflyboo = temp_disflyboo->next;                          //指向下游节点} while (temp_disflyboo != NULL);                                  //遍历至最后一枚敌方炮弹//判断敌方炮弹是否超出画布if (i > 5){                                                           //避免敌方初始炮弹无二阶next指向temp_disflyboo = disflyboo;                                     //通过临时变量进行下游查找遍历while (temp_disflyboo->next->next != NULL)                       //查找至炮弹第后三个,避免无法指定释放内存炮弹上游指向为空temp_disflyboo = temp_disflyboo->next;                     //指向下游节点if (temp_disflyboo->next->y >= Wall_y - 1){                       //当敌方飞机炮弹末端纵坐标小于墙面时CleanDisFlyBoo(temp_disflyboo->next->x, temp_disflyboo->next->y);    //清除敌方飞机炮弹free(temp_disflyboo->next);                                    //释放敌方飞机炮弹末端内存空间temp_disflyboo->next = NULL;                                //使被释放空间上游节点指向为空}}
}

结束游戏

void OverDisFly(){                       CleanDisFly();                                      //清除敌方飞机ProductDisFlyRander();                              //生成敌方飞机待生成位置随机函数disfly->x = disflyRander.disflyRander_x + 2;      //指定敌方飞机所在横坐标disfly->y = 2;                                     //指定敌方飞机所在纵坐标DrawDisFly();                                      //绘制敌方飞机XXscore += XXadd;                                 //更新当前得分i_now = i;                                         //更新当前循环计数器XXscore_now = XXscore;                              //更新当前分数计数器
}
void OverFly(){Sleep(600);                                              //给予失败证据提示system("cls");                                          //清屏for (int i = 0; i <= 500; i++)                           //进行失败效果制作printf("Game Over!     ");                          //输出游戏失败system("pause");                                      //等待用户按任意键退出游戏exit(0);                                              //结束游戏关闭程序
}

绘制总控

void Draw(){system("mode con cols=132 lines=42");                    //改变DOS大小copy();                                                    //绘制商标信息system("pause");                                      //使用户按任意键继续system("cls");                                         //清屏,防止欠覆盖留白DrawWall();                                              //绘制墙体//初始化己方飞机fly->x = Wall_x / 2;                             //依照墙体指定己方飞机横坐标fly->y = Wall_y - 1;                             //依照墙体指定己方飞机纵坐标DrawFly();                                               //绘制己方飞机//初始化敌方飞机ProductDisFlyRander();                             //生成敌方飞机待生成位置随机函数disfly->x = disflyRander.disflyRander_x + 2;      //依照随机数指定敌方飞机横坐标disfly->y = 2;                                      //依照随机数指定敌方飞机纵坐标DrawDisFly();                                           //绘制敌方飞机//绘制己方飞机炮弹disflyRander.disflybig = 6;                          //指定敌方飞机初始大小flyboo->x = fly->x + 2;                             //依照当前己方飞机横坐标指定己方飞机炮弹横坐标flyboo->y = fly->y - 1;                              //依照当前己方飞机纵坐标指定己方飞机炮弹纵坐标flyboo->next = NULL;                                //将初始飞机炮弹下游指向位置赋值为空DrawFlyBoo();                                            //绘制己方飞机炮弹//绘制敌方飞机炮弹disflyboo->x = disfly->x + 2;                           //依照当前敌方飞机横坐标指定敌方飞机炮弹横坐标disflyboo->y = disfly->y + 1;                       //依照当前敌方飞机纵坐标指定敌方飞机炮弹纵坐标disflyboo->next = NULL;                             //将初始飞机炮弹下游指向位置赋值为空DrawDisFlyBoo();                                     //绘制敌方飞机炮弹
}

总代码

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<Windows.h>
#include<time.h>//界面函数
void Cursor(int x, int y);                  //光标定位函数
void Draw();                                //绘制初始化界面
void copy();                                //绘制图标游戏名及版本号
void DrawWall();                            //绘制墙壁
void runGame();                             //游戏运行
void score();                               //得分系统//绘制与清除飞机函数
void DrawFly();                             //绘制己方飞机
void CleanFly();                            //清除己方飞机
void DrawDisFly();                          //绘制敌方飞机
void CleanDisFly();                         //清除敌方飞机
void DrawFlyBoo();                          //绘制己方飞机炮弹
void DrawFlyBoo(int x, int y);              //重载绘制带位置参数的己方炮弹
void CleanFlyoo();                          //清除己方炮弹
void CleanFlyBoo(int x,int y);              //重载清除带位置参数的己方炮弹
void DrawDisFlyBoo();                       //绘制敌方飞机炮弹
void DrawDisFlyBoo(int x,int y);            //重载绘制带位置参数的敌方炮弹
void CleanDisFlyBoo();                      //清除敌方炮弹
void CleanDisFlyBoo(int x,int y);           //重载清除带位置参数的敌方炮弹//运行刷新函数
void ReDrawFly();                           //重新绘制己方飞机
void ReDrawDisFly();                        //重新绘制敌方飞机
void ReDrawFlyBoo();                        //重新绘制己方炮弹
void ReDrawDisFlyBoo();                     //重新绘制敌方炮弹
void DisFlyMove();                          //控制敌方炮弹移动//碰撞检测函数
void isFlyBoo();                            //判断敌方飞机炮弹是否碰撞到己方飞机
void isDisFlyBoo();                         //判断己方飞机炮弹是否碰撞到敌方飞机
void isUpFly();                             //判断己方飞机是否升级
void isUpDisFly();                          //判断敌方飞机是否升级//结束函数
void OverDisFly();                          //结束敌方飞机生命
void OverFly();                             //结束己方飞机生命//随机位置生成函数
void ProductDisFlyRander();                 //生成敌方飞机横坐标随机位置
void MoveDisFlyRander();                    //生成敌方飞机移动随机值//界面控制
static const int Wall_x = 130;             //设置墙壁宽度值
static const int Wall_y = 40;              //设置墙壁高度值//创建己方飞机位置结构体
struct _Fly{int x, y;
}; //创建敌方飞机位置结构体
struct Dis_Fly{int x, y;
};//创建己方飞机炮弹结构体
struct FlyBoo{int x, y;struct FlyBoo *next;
};//创建敌方飞机炮弹结构体
struct DisFlyBoo{int x, y;struct DisFlyBoo *next;
};//设置刷新间隔时间SleepTime,   循环计数标志i, 当前循环计数标志i_now,   每次击中敌方飞机得分XXadd, 总得分XXscore,  当前击中敌方飞机得分XXscore_noe。
int SleepTime = 100, i = 0,i_now = 0, XXadd = 100, XXscore = 0, XXscore_now = 0;//开辟指针型己方及敌方内存
_Fly* fly = (_Fly*)malloc(sizeof(_Fly));
Dis_Fly* disfly = (Dis_Fly*)malloc(sizeof(Dis_Fly));//开辟指针型己方及敌方飞机炮弹内存
FlyBoo* flyboo = (FlyBoo*)malloc(sizeof(FlyBoo));
DisFlyBoo* disflyboo = (DisFlyBoo*)malloc(sizeof(DisFlyBoo));//创建敌方飞机横坐标随机参数及飞机大小
struct DisFlyRander{int disflyRander_x;int disflybig;
}disflyRander;//创建敌方飞机移动随机参数
struct DisFlyMoveRander{int moveRander;
}disflymoveRander;void ProductDisFlyRander(){srand((unsigned)time(NULL));disflyRander.disflyRander_x = (rand() % (Wall_x - 3 * disflyRander.disflybig) + disflyRander.disflybig) / 2 * 2 + 1;//创建横坐标并使创建的横坐标在不可超出墙壁并处在偶数坐标格中(使用/2*2使得处在偶数格中)
}void MoveDisFlyRander(){srand((unsigned)time(NULL));disflymoveRander.moveRander = rand() % 3 - 1;//使生成-1,0,1的随机数控制敌方飞机向左,静止或向右运动
}void Cursor(int x, int y){COORD cursor;                                        //实例化结构体HANDLE hOutput;                                     //实例化句柄cursor.X = x;                                       //传入横坐标参数cursor.Y = y;                                     //传入纵坐标参数hOutput = GetStdHandle(STD_OUTPUT_HANDLE);            //获取输出框界面句柄SetConsoleCursorPosition(hOutput, cursor);           //定位坐标位置
}void copy(){Cursor(0,Wall_y / 2 - 6 );printf("      **********************                           *                       *\n");printf("                              *                               *                 *\n");printf("                            *                                    *            *\n");printf("                          *                                        *        *\n");printf("                        *                                            *    *\n");printf("                      *                                                **\n");printf("                    *                                                  **\n");printf("                  *                                                    **\n");printf("                *                                                      **\n");printf("              *                                                        **\n");printf("            *                                                          **\n");printf("         ***********************                                       **             。          。          。\n");Cursor(Wall_x-20, Wall_y );printf("打飞机   V 1.0");Cursor(0, Wall_y);     //使光标处在左下角
}void DrawWall(){for (int i = 1; i < Wall_x; i+=2){Cursor(i, 0);      //定位上方墙壁printf("┰");      //绘制上方墙壁Cursor(i, Wall_y);  //定位下方墙壁printf("┸");      //绘制下方墙壁}
}
void DrawFly(){Cursor(fly->x, fly->y);                //定位己方待绘制飞机位置printf("◢■◣");                   //绘制己方飞机
}void CleanFly(){Cursor(fly->x, fly->y);              //定位己方待清除飞机位置printf("     ");                 //清除己方飞机
}void DrawDisFly(){Cursor(disfly->x, disfly->y);      //定位敌方待绘制飞机位置printf("◥□◤");                   //绘制敌方飞机
}void CleanDisFly(){Cursor(disfly->x, disfly->y);     //定位敌方待清除飞机位置printf("     ");                 //清除敌方飞机
}void DrawFlyBoo(){Cursor(flyboo->x, flyboo->y);      //定位己方待绘制炮弹位置printf("★");                     //绘制己方炮弹
}void DrawFlyBoo(int x, int y){Cursor(x, y);                        //定位己方待绘制炮弹位置printf("★");                     //绘制己方炮弹
}void CleanFlyBoo(){Cursor(flyboo->x, flyboo->y);     //定位己方待清除炮弹位置printf("  ");                        //清除己方炮弹
}
void CleanFlyBoo(int x,int y){Cursor(x, y);                     //定位己方待清除炮弹位置printf("  ");                        //清除己方炮弹
}void DrawDisFlyBoo(){Cursor(disflyboo->x, disflyboo->y); //定位敌方待绘制炮弹位置printf("☆");                     //绘制敌方炮弹
}void DrawDisFlyBoo(int x, int y){Cursor(x, y);                     //定位敌方待绘制炮弹位置printf("☆");                     //绘制敌方炮弹
}void CleanDisFlyBoo(){Cursor(disflyboo->x, disflyboo->y);    //定位敌方待清除炮弹位置printf("  ");                        //清除敌方炮弹
}void CleanDisFlyBoo(int x,int y){Cursor(x, y);                     //定位敌方待清除炮弹位置printf("  ");                        //清除敌方炮弹
}void ReDrawFly(){if (GetAsyncKeyState(VK_LEFT) && fly->x > 4){   //当用户键入左键CleanFly();                                    //清除原有己方飞机fly->x -= 2;                              //向左移动单位网格长度DrawFly();                                  //重新绘制己方飞机}else if (GetAsyncKeyState(VK_RIGHT) && fly->x < Wall_x - 4){   //当用户键入右键CleanFly();                                                    //清除原有己方飞机fly->x += 2;                                             //向右移动单位网格长度DrawFly();                                                  //重新绘制己方飞机}else{DrawFly();                      //若用户没有键入按键,进行刷新己方飞机,防止得分刷新覆盖}
}void ReDrawDisFly(){DrawDisFly();                      //当敌方飞机死亡时,进行重新绘制}void ReDrawFlyBoo(){FlyBoo* temp_flyboo = (FlyBoo*)malloc(sizeof(FlyBoo));            //开辟指针型己方临时飞机炮弹内存temp_flyboo->next = NULL;                                      //将其链接接口赋值为空//清除原有己方飞机炮弹temp_flyboo = flyboo;                              //通过临时变量进行下游查找遍历do{                                                 //至少进行一次遍历,普适第一枚己方炮弹CleanFlyBoo(temp_flyboo->x,temp_flyboo->y);        //清除己方飞机炮弹temp_flyboo = temp_flyboo->next;              //指向下游节点} while (temp_flyboo != NULL);                     //遍历至最后一枚己方炮弹//将每个炮弹进行向上移动temp_flyboo = flyboo;                                //通过临时变量进行下游查找遍历do{                                                 //至少进行一次遍历,普适第一枚己方炮弹temp_flyboo->y -= 1;                         //将每一枚己方炮弹纵坐标减一temp_flyboo = temp_flyboo->next;             //指向下游节点} while (temp_flyboo != NULL);                     //遍历至最后一枚己方炮弹//依照当前己方飞机链接新炮弹FlyBoo* next_flyboo = (FlyBoo*)malloc(sizeof(FlyBoo)); //开辟指针型递进己方飞机炮弹内存next_flyboo->x = fly->x + 2;                           //通过当前己方飞机横坐标位置定位己方炮弹横坐标位置next_flyboo->y = fly->y - 1;                           //通过当前己方飞机纵坐标位置定位己方炮弹纵坐标位置next_flyboo->next = flyboo;                               //将炮弹首部控制在前端flyboo = next_flyboo;//将己方炮弹全部重绘temp_flyboo = flyboo;                             //通过临时变量进行下游查找遍历do{                                                 //至少进行一次遍历,普适第一枚己方炮弹DrawFlyBoo(temp_flyboo->x, temp_flyboo->y);        //绘制己方炮弹temp_flyboo = temp_flyboo->next;                //指向下游节点} while (temp_flyboo != NULL);                     //遍历至最后一枚己方炮弹//判断己方炮弹是否超出画布if (i > 5){                                                           //避免己方初始炮弹无二阶next指向temp_flyboo = flyboo;                                           //通过临时变量进行下游查找遍历while (temp_flyboo->next->next != NULL)                          //查找至炮弹第后三个,避免无法指定释放内存炮弹上游指向为空temp_flyboo = temp_flyboo->next;                           //指向下游节点if (temp_flyboo->next->y <= 1){                                   //当己方飞机炮弹末端纵坐标小于墙面时CleanFlyBoo(temp_flyboo->next->x, temp_flyboo->next->y); //清除己方飞机炮弹free(temp_flyboo->next);                                   //释放己方飞机炮弹末端内存空间temp_flyboo->next = NULL;                                   //使被释放空间上游节点指向为空}}i++;                                                                //运行循环次数递增
}void ReDrawDisFlyBoo(){DisFlyBoo* temp_disflyboo = (DisFlyBoo*)malloc(sizeof(DisFlyBoo)); //开辟指针型敌方临时飞机炮弹内存temp_disflyboo->next = NULL;                                       //将其链接接口赋值为空//清除原有敌方飞机炮弹temp_disflyboo = disflyboo;                                            //通过临时变量进行下游查找遍历do{                                                                 //至少进行一次遍历,普适第一枚敌方炮弹CleanDisFlyBoo(temp_disflyboo->x,temp_disflyboo->y);           //清除敌方飞机炮弹temp_disflyboo = temp_disflyboo->next;                            //指向下游节点} while (temp_disflyboo != NULL);                                  //遍历至最后一枚敌方炮弹//将每个炮弹进行向上移动temp_disflyboo = disflyboo;                                          //通过临时变量进行下游查找遍历do{                                                                 //至少进行一次遍历,普适第一枚敌方炮弹temp_disflyboo->y += 1;                                         //将每一枚敌方炮弹纵坐标减一temp_disflyboo = temp_disflyboo->next;                           //指向下游节点} while (temp_disflyboo != NULL);                                  //遍历至最后一枚敌方炮弹//依照当前敌方飞机链接新炮弹DisFlyBoo* next_disflyboo = (DisFlyBoo*)malloc(sizeof(DisFlyBoo)); //开辟指针型递进敌方飞机炮弹内存next_disflyboo->x = disfly->x + 2;                                 //通过当前敌方飞机横坐标位置定位敌方炮弹横坐标位置next_disflyboo->y = disfly->y + 1;                                    //通过当前敌方飞机纵坐标位置定位敌方炮弹纵坐标位置next_disflyboo->next = disflyboo;                                 //将炮弹首部控制在前端disflyboo = next_disflyboo;//将敌方炮弹全部重绘temp_disflyboo = disflyboo;                                         //通过临时变量进行下游查找遍历do{                                                                 //至少进行一次遍历,普适第一枚敌方炮弹DrawDisFlyBoo(temp_disflyboo->x, temp_disflyboo->y);           //绘制敌方炮弹temp_disflyboo = temp_disflyboo->next;                          //指向下游节点} while (temp_disflyboo != NULL);                                  //遍历至最后一枚敌方炮弹//判断敌方炮弹是否超出画布if (i > 5){                                                           //避免敌方初始炮弹无二阶next指向temp_disflyboo = disflyboo;                                     //通过临时变量进行下游查找遍历while (temp_disflyboo->next->next != NULL)                       //查找至炮弹第后三个,避免无法指定释放内存炮弹上游指向为空temp_disflyboo = temp_disflyboo->next;                     //指向下游节点if (temp_disflyboo->next->y >= Wall_y - 1){                       //当敌方飞机炮弹末端纵坐标小于墙面时CleanDisFlyBoo(temp_disflyboo->next->x, temp_disflyboo->next->y);    //清除敌方飞机炮弹free(temp_disflyboo->next);                                    //释放敌方飞机炮弹末端内存空间temp_disflyboo->next = NULL;                                //使被释放空间上游节点指向为空}}
}void DisFlyMove(){MoveDisFlyRander();                                                  //调用随机函数生成运动随机数if (!(disfly->x > Wall_x - 5 && disflymoveRander.moveRander > 0) && !(disfly->x < 5 && disflymoveRander.moveRander < 0)){//控股敌方飞机运动至墙面边界时无法持续滑动CleanDisFly();                                                  //将原有敌方飞机清除disfly->x += disflymoveRander.moveRander;                       //向指定随机方向进行运动DrawDisFly();                                                  //重新绘制敌方飞机}
}void score(){if ((XXscore != XXscore_now)||(i<=(i_now+3))){                      //当飞机的得分更新或显示次数小于三次时Cursor(0, Wall_y - i + i_now);                                 //将光标指向墙面左下角并向上递减输出printf("%d  !!!  %d  !!!  %d", XXscore, XXscore, XXscore);     //输出当前得分}
}void isFlyBoo(){DisFlyBoo* temp_disflyboo = (DisFlyBoo*)malloc(sizeof(DisFlyBoo));    //开辟指针型临时敌方飞机炮弹内存temp_disflyboo = disflyboo;                                           //通过临时变量进行下游遍历查找do{if ((temp_disflyboo->x >= fly->x) && (temp_disflyboo->x <= fly->x + 6) && (temp_disflyboo->y == fly->y - 1))    //当敌方飞机炮弹位于己方飞机平面坐标时OverFly();                                                  //执行结束己方飞机生命函数temp_disflyboo = temp_disflyboo->next;                            //指向下游节点} while (temp_disflyboo != NULL);                                  //遍历至最后一枚敌方炮弹}void isDisFlyBoo(){FlyBoo* temp_flyboo = (FlyBoo*)malloc(sizeof(FlyBoo));                //开辟指针型临时己方飞机炮弹内存temp_flyboo = flyboo;                                             //通过临时变量进行下游遍历查找do{if ((temp_flyboo->x >= disfly->x) && (temp_flyboo->x <= disfly->x + 6) && (temp_flyboo->y == disfly->y + 1))   //当己方飞机炮弹位于敌方飞机平面坐标时OverDisFly();                                               //执行结束敌方飞机生命函数temp_flyboo = temp_flyboo->next;                              //指向下游节点} while (temp_flyboo != NULL);                                     //遍历至最后一枚己方炮弹
}void isUpFly(){//待创建
}void isUpDisFly(){//待创建
}void OverDisFly(){                     CleanDisFly();                                      //清除敌方飞机ProductDisFlyRander();                              //生成敌方飞机待生成位置随机函数disfly->x = disflyRander.disflyRander_x + 2;      //指定敌方飞机所在横坐标disfly->y = 2;                                     //指定敌方飞机所在纵坐标DrawDisFly();                                      //绘制敌方飞机XXscore += XXadd;                                 //更新当前得分i_now = i;                                         //更新当前循环计数器XXscore_now = XXscore;                              //更新当前分数计数器}void Draw(){system("mode con cols=132 lines=42");                   //改变DOS大小copy();                                                    //绘制商标信息system("pause");                                      //使用户按任意键继续system("cls");                                         //清屏,防止欠覆盖留白DrawWall();                                              //绘制墙体//初始化己方飞机fly->x = Wall_x / 2;                             //依照墙体指定己方飞机横坐标fly->y = Wall_y - 1;                             //依照墙体指定己方飞机纵坐标DrawFly();                                               //绘制己方飞机//初始化敌方飞机ProductDisFlyRander();                             //生成敌方飞机待生成位置随机函数disfly->x = disflyRander.disflyRander_x + 2;      //依照随机数指定敌方飞机横坐标disfly->y = 2;                                      //依照随机数指定敌方飞机纵坐标DrawDisFly();                                           //绘制敌方飞机//绘制己方飞机炮弹disflyRander.disflybig = 6;                          //指定敌方飞机初始大小flyboo->x = fly->x + 2;                             //依照当前己方飞机横坐标指定己方飞机炮弹横坐标flyboo->y = fly->y - 1;                              //依照当前己方飞机纵坐标指定己方飞机炮弹纵坐标flyboo->next = NULL;                                //将初始飞机炮弹下游指向位置赋值为空DrawFlyBoo();                                            //绘制己方飞机炮弹//绘制敌方飞机炮弹disflyboo->x = disfly->x + 2;                           //依照当前敌方飞机横坐标指定敌方飞机炮弹横坐标disflyboo->y = disfly->y + 1;                       //依照当前敌方飞机纵坐标指定敌方飞机炮弹纵坐标disflyboo->next = NULL;                             //将初始飞机炮弹下游指向位置赋值为空DrawDisFlyBoo();                                     //绘制敌方飞机炮弹
}void runGame(){while (1){                                              //进行游戏循环isFlyBoo();isDisFlyBoo();ReDrawFly();ReDrawDisFly();ReDrawFlyBoo();ReDrawDisFlyBoo();DisFlyMove();isUpFly();isUpDisFly();score();Sleep(SleepTime);}
}void OverFly(){Sleep(600);                                             //给予失败证据提示system("cls");                                          //清屏for (int i = 0; i <= 500; i++)                           //进行失败效果制作printf("Game Over!     ");                          //输出游戏失败system("pause");                                      //等待用户按任意键退出游戏exit(0);                                              //结束游戏关闭程序
}int main(){Draw();                                                 //进行初始化绘制runGame();                                             //进行游戏运行
}

C语言飞机大战小游戏(2万字!完整精讲解版+源代码)相关推荐

  1. C语言—飞机大战小游戏

    哈工大经典C语言大作业-飞机大战小游戏,源码如下,已经通过编译获得评分19+ (满分20)当时还是太菜了呜呜呜. 可以给大家参考一下,好像本来是加了音乐的,但是你们可能没有对应的音乐MP3文件,所以如 ...

  2. C语言飞机大战小游戏

    说明 此设计可以作为C语言课程设计,主要用的是easyx图形库: 在VS2019成功运行,注释比较全面,对没有C语言基础的小白也很友好: 若有些地方还可以完善,请指正. 设计游戏的思路主要从以下几个当 ...

  3. html+javascript实现的网页版飞机大战小游戏源码

    html+javascript实现的网页版飞机大战小游戏源码 完整代码下载地址: html+javascript实现的网页版飞机大战小游戏源码 index.html <!DOCTYPE html ...

  4. 基于Java语言在窗体上实现飞机大战小游戏

    全套资料下载地址:https://download.csdn.net/download/sheziqiong/85594271 项目介绍 飞机大战:用 Java 语言在窗体上实现飞机大战小游戏,运行程 ...

  5. 用C语言实现飞机大战小游戏

    我的个人博客:谋仁·Blog 该项目已上传至GitHub:点击跳转 文章目录 摘要 运行环境 整体功能思维导图 效果预览 具体功能的实现 图形界面:EasyX EasyX图形库简介 EasyX图形库的 ...

  6. 华为官方解析开源鸿蒙 OpenHarmony 3.1关键特性画布,教你如何完成飞机大战小游戏

    华为技术有限公司的江英杰为大家揭晓了关于开源鸿蒙 OpenHarmony 3.1 Beta 版中的一个关键特性,也就是 ArkUI 开发框架中的 canvas 画布. 据介绍,canvas 是 Ark ...

  7. canvas绘制“飞机大战”小游戏,真香

    canvas是ArkUI开发框架里的画布组件,常用于自定义绘制图形.因为其轻量.灵活.高效等优点,被广泛应用于UI界面开发中. 本期,我们将为大家介绍canvas组件的使用. 目录 一.canvas介 ...

  8. 【python】飞机大战小游戏练习

    飞机大战小游戏练习 一.前提准备 二.制作步骤 1.库的导入与初始化 2.窗口操作 3.键盘按键监听相关操作 4.添加游戏背景 5.加载玩家飞机 6.获取玩家飞机矩阵 三.完整代码编写 游戏背景类编写 ...

  9. python 飞机大战小游戏

    飞机大战小游戏,这里需要下载pygame模块 这是需要的素材,需要的自取: 上代码: import time import pygame from pygame.locals import *#检测事 ...

  10. 点击list view中一行内容可以在combox中显示_java版飞机大战小游戏详细教程(零基础小白也可以分分钟学会!)...

    一:游戏展示 飞机大战小游戏我们都玩过,通过移动飞机来打敌机,这里给大家展示一下游戏成果:呜呜呜由于gif只能上传5M大小,所以就不能给大家展示操作了,如果大家有兴趣可以自己自己做出来再玩哟. 这里面 ...

最新文章

  1. VS中使用OpenCV构建应用程序
  2. 解决python读取json格式数据后提取object不存在报错KeyError
  3. window.external的使用
  4. 高性能 Windows Socket 服务端与客户端组件(HP-Socket v1.0.1 源代码及测试用例下载)...
  5. HashSet、TreeSet、LinkedHashSet的区别
  6. 网线RJ45接口排线示意图(做网线备用)
  7. Tolua使用笔记(上)
  8. go chan 类型用法
  9. 新元宇宙每周连载《地球人奇游天球记》第十五回土星种菜
  10. 转使用chrome命令行:disable-web-security 实现浏览器跨域
  11. 快速给图片加水印的方法
  12. Context-Free Grammar及形状规则集
  13. QT常用控件——QComboBox控件
  14. Shell 脚本小试牛刀(5) -- 超便捷脚本之高速ssh 登录其它主机
  15. 天猫精灵实现误无醒词推送断网负载播报
  16. 告别慢SQL,如何去写一手好SQL ?
  17. android卸载按钮不能用了,不用ROOT 干掉Android里无法卸载的APP
  18. 母亲节倒计时,选礼物救急指南
  19. 界面设计——东方快车安装界面
  20. [GO项目]开源免费在线客服系统-真正免费开源-GOFLY0.3.3发布-极简强大Go语言开发网页客服...

热门文章

  1. 如何安装服务器操作系统 HP服务器系统安装
  2. Python爬取豆瓣图书信息学习记录
  3. apt-get autoremove remove 新手收割者
  4. 东田纳西州立大学计算机排名,东田纳西州立大学排名在2020年USNEWS美国最佳综合大学排名第293-381...
  5. 护理管理学复习题及参考答案
  6. 【Excel学习笔记11】计数、求和、平均值函数,通配符
  7. 千万不要用efficientnet做bone net
  8. TFT-液晶显示屏的结构和原理
  9. 网页制作大作业HTML+CSS制作静态网页----原神
  10. RFBNet详细讲解(附图文解释)