• 用VS开发一款“飞机大战“单机游戏<C++>


    显示界面如上图所示

    自己找的背景和飞机素材,先将素材奉上.

     

    接下来我先简单分析一下这个单机游戏的运行逻辑:

    就像显示界面所显示的那样,我们想要实现的是自己的飞机在发射子弹(子弹在上图没显示),然后当子弹射到敌方飞机,这里设置了两种类型的飞机,如果读者想定义更多类型的,直接添加属性就可以.当子弹射到飞机的时候,飞机的血量减少,就像CS一样,并不一定是一发子弹就死亡,读者可以根据自己喜欢去设置,博主这里设置大飞机的血量是3发子弹,而小飞机的血量是1发子弹,也就是说,当有3发子弹射到大飞机的时候,大飞机就消失,一发子弹小飞机消失.至于其他的动态效果,博主这里暂时不做介绍.具体往下看:

    面向对象开发,每一个对象我们都需要给他设置相对应的对象属性,在语言当中,我们将其设置成结构体就可以:

    1. enum My
    2. {
    3. WIDTH = 500,
    4. HIGHT = 700,
    5. BULLET_NUM = 100,//玩家子弹数量
    6. ENEMY_NUM = 10,//敌机的数量
    7. BIG,
    8. SMALL,
    9. };
    10. struct Plane
    11. {
    12. int x;
    13. int y;
    14. bool live;//是否存活
    15. int width;
    16. int hight;
    17. int hp;
    18. int type;//敌机类型 big small
    19. }player,bull[BULLET_NUM],enemy[ENEMY_NUM];

    首先设定了一个联合,用于设置弹出窗口的基本参数和其他属性. 

    上面是不是把敌方飞机,自己飞机和自己发射的子弹都定义成了一个结构体.下面我们就可以直接用了.

    (x,y)代表的是对象在窗口当中的坐标,width和hight是对象自身的尺寸,而hp是血量,type是博主自己定义了两种敌机类型.布尔类型live判断飞机是否存活状态.

    第一步我们应该是要先创建图形窗口

    1. /*测试
    2. circle(50, 50, 50);//画空心圆
    3. setfillcolor(GREEN);//圆的颜色
    4. fillcircle(100, 100, 50);///实心⚪*/
    5. //创建图形窗口
    6. initgraph(WIDTH, HIGHT,SHOWCONSOLE);//宽长

    initgraph()函数直接用

    第二步加载窗口里面使用到的图片   //无论什么时候用,我们都要进行图片加载的,因此此处我们将其设定到一个函数下,方便之后也可以随时添加和删除.

    1. //把图片加载进程序
    2. IMAGE bk;//背景图
    3. //保存玩家图片
    4. IMAGE img_role;
    5. //保存子弹
    6. IMAGE img_bull;
    7. //
    8. IMAGE img_enemy[4];
    9. void loadImg()
    10. {
    11. //加载图片
    12. loadimage(&bk, "D:/program/飞机大战/images/bk.png");
    13. //加载玩家图片
    14. loadimage(&img_role, "D:/program/飞机大战/images/fly.png");
    15. //加载子弹图片
    16. loadimage(&img_bull, "D:/program/飞机大战/images/子弹.jpg");
    17. //加载敌机的图片
    18. loadimage(&img_enemy[0], "D:/program/飞机大战/images/enemy1.png");
    19. loadimage(&img_enemy[1], "D:/program/飞机大战/images/enemy2.png");
    20. //loadimage(&img_enemy[2], "D:/program/飞机大战/images/enemy3.jpg");
    21. //loadimage(&img_enemy[3], "D:/program/飞机大战/images/enemy4.jpg");
    22. }

    IMAGE 是easyx里面的一个参数,直接用

    此案例当中,需要我们加载的图片有背景图,自己飞机图,子弹图,敌方飞机1和敌方飞机2,如果读者也自己添加第三台和第四台敌机,也可以直接添加,不过要注意,当一种对象,存在多个类型的时候,要采用数组将其存储,方便之后进行使用.

    第三步,要干嘛?设置好窗口了,加载完图片了,是不是要把图片添加进去了?

    那图片添加到哪里去?怎么添加?哪一种图片应该添加在哪里呢?

    这里我们是不是首先要初始化一下图片的基本属性?of course,买衣服我总的知道我适合穿多大尺码的衣服吧?

    1. void gameinit()//初始化数据
    2. {
    3. player.x = WIDTH / 2;
    4. player.y = HIGHT - 120;
    5. player.live = true;
    6. //初始化子弹
    7. for (int i = 0; i < BULLET_NUM; i++)
    8. {
    9. bull[i].x = 0;
    10. bull[i].y = 0;
    11. bull[i].live = false;
    12. }
    13. //初始化敌机
    14. for (int i = 0; i < ENEMY_NUM; i++)
    15. {
    16. enemy[i].live = false;
    17. enemyHP(i);
    18. }
    19. }

    想想我们一共有几个对象,去除背景图片不需要我们在这里初始化之外,另外就是自己飞机,敌方飞机和子弹三个对象.那么我们就定义一个函数,用于初始化这些对象的第一属性.

    在初始化敌方飞机的时候,博主之前把敌方飞机设置有两种类型,那么这两种类型飞机的基本属性一定有一些是不一样的呀,要不然怎么叫做2呢?

    博主这里主要用飞机的大小和血量来区分这两种飞机.具体看enemyHP()函数

    1. void enemyHP(int i)
    2. {
    3. int flag = rand() % 10;
    4. if (flag>=0 && flag<=2)//0-9
    5. {
    6. enemy[i].type = BIG;
    7. enemy[i].hp = 3;
    8. enemy[i].width = 100;
    9. enemy[i].hight = 100;
    10. }
    11. else
    12. {
    13. enemy[i].type = SMALL;
    14. enemy[i].hp = 1;
    15. enemy[i].width = 50;
    16. enemy[i].hight = 50;
    17. }
    18. }

    在这个函数当中,我们要注意,大飞机和小飞机出现的次数是不是正常情况下是不一样的?比如小飞机出现了5次,而大飞机才出现一次这样,当然敌飞机出现肯定不是我们可以控制的,它肯定是随机出现的,所以这里我们采用一个随机范围,如果在0-2之间就出现大飞机,3-9之间小飞机,这样是不是小飞机的概率要高于大飞机.其余的进入条件之内直接初始化就可以了.

    第四步,上面我们把全部图片都加载好,然后对象都进行了初始化,接下来我们要干嘛?

    那肯定是要将这些图片绘制到对应的窗口坐标上了!!!!!!!

    1. void gameDraw()
    2. {
    3. loadImg();
    4. //把背景贴在窗口上
    5. putimage(0, 0, &bk);
    6. putimage(player.x, player.y, &img_role,SRCINVERT);
    7. for (int i = 0; i < BULLET_NUM; i++)
    8. {
    9. if (bull[i].live)
    10. {
    11. putimage(bull[i].x, bull[i].y, &img_bull, SRCINVERT);
    12. }
    13. }
    14. //绘制敌机
    15. for (int i = 0; i < ENEMY_NUM; i++)
    16. {
    17. if (enemy[i].live)
    18. {
    19. if(enemy[i].type==SMALL)
    20. putimage(enemy[i].x, enemy[i].y, &img_enemy[0], SRCINVERT);//x和y是飞机在窗口中的坐标
    21. else
    22. putimage(enemy[i].x, enemy[i].y, &img_enemy[1], SRCINVERT);
    23. }
    24. }
    25. }

    绘制背景,绘制自己飞机,绘制子弹,绘制敌方飞机都采用putimage()函数就可以了

    需要注意的有可能就是对于敌方飞机和子弹只有live是true的时候才绘制,而对于敌方飞机还区分了两种类型的飞机,加一个if-else输出对应的敌方飞机就可以了;

    第五步,第四步我们绘制的图片是个啥,是初始化的位置,是一个静态的图,我们要实现的动态图,那接下来我们应该干嘛????????

    当然是让子弹,自己飞机和敌方飞机都动起来了,也就是创建动画

    首先让自己飞机动起来

    1. void playermove(int speed)
    2. {
    3. #if 0
    4. if (_kbhit) {
    5. //有两种方式
    6. //1,getch() 阻塞函数,和scanf一样,如果没有输入,就会卡住程序,一直等待输入,
    7. //这个函数不是c语言标准函数,需要头文件<conio.h>
    8. char key = _getch();
    9. switch (key)
    10. {
    11. case 'w':
    12. case 'W':
    13. player.y -= speed;
    14. break;
    15. case 's':
    16. case 'S':
    17. player.y += speed;
    18. break;
    19. case 'a':
    20. case 'A':
    21. player.x -= speed;
    22. break;
    23. case 'd':
    24. case 'D':
    25. player.x += speed;
    26. break;
    27. default:
    28. break;
    29. }
    30. }
    31. }
    32. #elif 1
    33. //2.使用Windows函数获取键盘输入
    34. //非阻塞函数,特别流畅
    35. //如果用字母,必须要用大写,大写可以识别大小写
    36. if (GetAsyncKeyState(VK_UP) || GetAsyncKeyState('W'))
    37. {
    38. if(player.y > 0)
    39. player.y -= speed;
    40. }
    41. if (GetAsyncKeyState(VK_DOWN) || GetAsyncKeyState('S'))
    42. {
    43. if (player.y < HIGHT-78)//78是飞机的高度
    44. player.y += speed;
    45. }
    46. if (GetAsyncKeyState(VK_LEFT) || GetAsyncKeyState('A'))
    47. {
    48. if(player.x+59>0)// 119/2 = 59是控制飞机子弹在左右边界的时候可以打到敌机
    49. player.x -= speed;
    50. }
    51. if (GetAsyncKeyState(VK_RIGHT) || GetAsyncKeyState('D'))
    52. {
    53. if (player.x-59 < WIDTH-119)//119是飞机的宽度
    54. player.x += speed;
    55. }
    56. #endif // 0
    57. if (GetAsyncKeyState(VK_SPACE) && Timer(100,1))//
    58. {
    59. //创建一个子弹
    60. createBullet();
    61. }
    62. }

    这里尝试了两种让自己飞机动起来的方法,第一种是_kbhit,如果按下键盘,判断按下的是什么键,如果wsad当中的一个则执行对应的操作,但是这种方法运行之后,你会发现很卡,就是一个帧当中只能运行一个动作,不能运行右上这样的操作,关键是很卡

    所以我们用了第二种方案非阻塞函数GetAsyncKeyState(),分别对键盘当中的上下左右和英文字符当中的wasd进行case分析,其他不变,此处要注意的有可能就是要控制自己的飞机运行,只能在窗口范围内运行,为其设定边界就可以.

    最后还加了一个和子弹相关的函数,如果说按下空格键了,就要发射子弹了,同时这里结合了一个定时器的函数,用于控制子弹发射的速度100ms,不要再100ms内发射两颗子弹,防止出现子弹重叠的现象.

    1. bool Timer(int ms, int id)//定时器
    2. {
    3. static DWORD t[10];
    4. if (clock() - t[id] > ms)
    5. {
    6. t[id] = clock();
    7. return true;
    8. }
    9. return false;
    10. }

    定义了一个无符号长整形的时间数组,是因为本案例当中有多个函数都用到了定时器函数.

    自己飞机动起来,接下来就很明显了,让子弹跟着发射,对不对????也就是进入createBullet()函数

    1. void createBullet()
    2. {
    3. for (int i = 0; i < BULLET_NUM; i++)
    4. {
    5. if (!bull[i].live)
    6. {
    7. bull[i].x = player.x+59;
    8. bull[i].y = player.y;
    9. bull[i].live = true;
    10. break;
    11. }
    12. }
    13. }

     刚开始子弹都是的状态都是false,然后条件正确后,初始化了子弹的第一个位置发射出来,然后将子弹的状态改为true.跳出这一个,执行下一个,要注意此时只是静态化绘制了子弹,还没有动起来,那么接下来就让子弹垂直向上运行就好.

    1. void Bullmove(int speed)
    2. {
    3. for (int i = 0; i < BULLET_NUM; i++)
    4. {
    5. if (bull[i].live)
    6. {
    7. bull[i].y -=speed;
    8. if (bull[i].y < 0)
    9. {
    10. bull[i].live = false;
    11. }
    12. }
    13. }
    14. }

    如果子弹到了最上方了,改变子弹的状态为false,继续循环

    自己飞机和子弹都结束了,接下来就是敌方飞机了

    1. //产生敌机
    2. void createenemy()
    3. {
    4. for (int i = 0; i < ENEMY_NUM; i++)
    5. {
    6. if (!enemy[i].live)
    7. {
    8. enemy[i].live = true;
    9. enemy[i].x = rand()%(WIDTH-75);
    10. enemy[i].y = 0;
    11. enemyHP(i);
    12. printf("pos(%d,%d) %d %d\n", enemy[i].x, enemy[i].y, enemy[i].live, enemy[i].hp);
    13. break;
    14. }
    15. }
    16. }

    在窗口的最上面随机产生敌机,敌机也要动的.是不是参考子弹的就可以了,如下

    1. //敌机的移动
    2. void enemymove(int speed)
    3. {
    4. for (int i = 0; i < ENEMY_NUM; i++)
    5. {
    6. if (enemy[i].live)
    7. {
    8. enemy[i].y += speed;
    9. if (enemy[i].y > HIGHT)
    10. {
    11. enemy[i].live = false;
    12. }
    13. }
    14. }
    15. }

     最后就是打飞机,当子弹到了敌方飞机的范围内是,敌方飞机就消失

    1. //开始打飞机
    2. void playplane()
    3. {
    4. for (int i = 0; i < ENEMY_NUM; i++)
    5. {
    6. if (!enemy[i].live)
    7. continue;
    8. for (int k = 0; k < BULLET_NUM; k++)
    9. {
    10. if (!bull[k].live)
    11. continue;
    12. if (bull[k].x > enemy[i].x && bull[k].x<enemy[i].x + enemy[i].width
    13. && bull[k].y>enemy[i].y && bull[k].y < enemy[i].y + enemy[i].hight)//子弹在飞机的界面内
    14. //则代表子弹打住了飞机
    15. {
    16. bull[k].live = false;
    17. enemy[i].hp--;
    18. }
    19. }
    20. if (enemy[i].hp == 0)
    21. {
    22. enemy[i].live = false;
    23. }
    24. }
    25. }

    1. if (bull[k].x > enemy[i].x && bull[k].x<enemy[i].x + enemy[i].width
    2. && bull[k].y>enemy[i].y && bull[k].y < enemy[i].y + enemy[i].hight)//子弹在飞机的界面内
    3. //则代表子弹打住了飞机

    这是个啥?意思是当子弹到了敌方飞机那个矩形图之内,条件就正确

     这里要注意大飞机血量是3,小飞机血量是1,一颗子弹一格血量.当血量为0,则飞机死亡

    最后一步,上主函数

    1. int main()
    2. {
    3. /*测试
    4. circle(50, 50, 50);//画空心圆
    5. setfillcolor(GREEN);//圆的颜色
    6. fillcircle(100, 100, 50);///实心⚪*/
    7. //创建图形窗口
    8. initgraph(WIDTH, HIGHT,SHOWCONSOLE);//宽长
    9. gameinit();
    10. //双缓冲绘图
    11. BeginBatchDraw();
    12. while (1)
    13. {
    14. gameDraw();
    15. FlushBatchDraw();
    16. playermove(5);
    17. Bullmove(5);
    18. //防止飞机全部一起出来
    19. if (Timer(500,0))
    20. {
    21. //创建一个飞机
    22. createenemy();
    23. }
    24. if (Timer(20, 2))
    25. {
    26. enemymove(1);
    27. }
    28. playplane();
    29. }
    30. EndBatchDraw();
    31. return 0;
    32. }

    注意这里的

    1. //双缓冲绘图
    2. BeginBatchDraw();
    3. EndBatchDraw();

    是easyx插件里面的一个双缓冲绘图,防止图片在窗口当中出现闪屏

    总代码:

    1. #include<stdio.h>
    2. //图形库,帮助我们新手,快速入门图形编程easyx
    3. #include<graphics.h>
    4. #include<conio.h>
    5. #include<time.h>
    6. enum My
    7. {
    8. WIDTH = 500,
    9. HIGHT = 700,
    10. BULLET_NUM = 100,//玩家子弹数量
    11. ENEMY_NUM = 10,//敌机的数量
    12. BIG,
    13. SMALL,
    14. };
    15. struct Plane
    16. {
    17. int x;
    18. int y;
    19. bool live;//是否存活
    20. int width;
    21. int hight;
    22. int hp;
    23. int type;//敌机类型 big small
    24. }player,bull[BULLET_NUM],enemy[ENEMY_NUM];
    25. //把图片加载进程序
    26. IMAGE bk;//背景图
    27. //保存玩家图片
    28. IMAGE img_role;
    29. //保存子弹
    30. IMAGE img_bull;
    31. //
    32. IMAGE img_enemy[4];
    33. void loadImg()
    34. {
    35. //加载图片
    36. loadimage(&bk, "D:/program/飞机大战/images/bk.png");
    37. //加载玩家图片
    38. loadimage(&img_role, "D:/program/飞机大战/images/fly.png");
    39. //加载子弹图片
    40. loadimage(&img_bull, "D:/program/飞机大战/images/子弹.jpg");
    41. //加载敌机的图片
    42. loadimage(&img_enemy[0], "D:/program/飞机大战/images/enemy1.png");
    43. loadimage(&img_enemy[1], "D:/program/飞机大战/images/enemy2.png");
    44. //loadimage(&img_enemy[2], "D:/program/飞机大战/images/enemy3.jpg");
    45. //loadimage(&img_enemy[3], "D:/program/飞机大战/images/enemy4.jpg");
    46. }
    47. bool Timer(int ms, int id)//定时器
    48. {
    49. static DWORD t[10];
    50. if (clock() - t[id] > ms)
    51. {
    52. t[id] = clock();
    53. return true;
    54. }
    55. return false;
    56. }
    57. void enemyHP(int i)
    58. {
    59. int flag = rand() % 10;
    60. if (flag>=0 && flag<=2)//0-9
    61. {
    62. enemy[i].type = BIG;
    63. enemy[i].hp = 3;
    64. enemy[i].width = 100;
    65. enemy[i].hight = 100;
    66. }
    67. else
    68. {
    69. enemy[i].type = SMALL;
    70. enemy[i].hp = 1;
    71. enemy[i].width = 50;
    72. enemy[i].hight = 50;
    73. }
    74. }
    75. void gameinit()//初始化数据
    76. {
    77. player.x = WIDTH / 2;
    78. player.y = HIGHT - 120;
    79. player.live = true;
    80. //初始化子弹
    81. for (int i = 0; i < BULLET_NUM; i++)
    82. {
    83. bull[i].x = 0;
    84. bull[i].y = 0;
    85. bull[i].live = false;
    86. }
    87. //初始化敌机
    88. for (int i = 0; i < ENEMY_NUM; i++)
    89. {
    90. enemy[i].live = false;
    91. enemyHP(i);
    92. }
    93. }
    94. //游戏绘制函数
    95. void gameDraw()
    96. {
    97. loadImg();
    98. //把背景贴在窗口上
    99. putimage(0, 0, &bk);
    100. putimage(player.x, player.y, &img_role,SRCINVERT);
    101. for (int i = 0; i < BULLET_NUM; i++)
    102. {
    103. if (bull[i].live)
    104. {
    105. putimage(bull[i].x, bull[i].y, &img_bull, SRCINVERT);
    106. }
    107. }
    108. //绘制敌机
    109. for (int i = 0; i < ENEMY_NUM; i++)
    110. {
    111. if (enemy[i].live)
    112. {
    113. if(enemy[i].type==SMALL)
    114. putimage(enemy[i].x, enemy[i].y, &img_enemy[0], SRCINVERT);//x和y是飞机在窗口中的坐标
    115. else
    116. putimage(enemy[i].x, enemy[i].y, &img_enemy[1], SRCINVERT);
    117. }
    118. }
    119. }
    120. void createBullet()
    121. {
    122. for (int i = 0; i < BULLET_NUM; i++)
    123. {
    124. if (!bull[i].live)
    125. {
    126. bull[i].x = player.x+59;
    127. bull[i].y = player.y;
    128. bull[i].live = true;
    129. break;
    130. }
    131. }
    132. }
    133. void Bullmove(int speed)
    134. {
    135. for (int i = 0; i < BULLET_NUM; i++)
    136. {
    137. if (bull[i].live)
    138. {
    139. bull[i].y -=speed;
    140. if (bull[i].y < 0)
    141. {
    142. bull[i].live = false;
    143. }
    144. }
    145. }
    146. }
    147. //角色移动,获取键盘信息,上下左右
    148. void playermove(int speed)
    149. {
    150. #if 0
    151. if (_kbhit) {
    152. //有两种方式
    153. //1,getch() 阻塞函数,和scanf一样,如果没有输入,就会卡住程序,一直等待输入,
    154. //这个函数不是c语言标准函数,需要头文件<conio.h>
    155. char key = _getch();
    156. switch (key)
    157. {
    158. case 'w':
    159. case 'W':
    160. player.y -= speed;
    161. break;
    162. case 's':
    163. case 'S':
    164. player.y += speed;
    165. break;
    166. case 'a':
    167. case 'A':
    168. player.x -= speed;
    169. break;
    170. case 'd':
    171. case 'D':
    172. player.x += speed;
    173. break;
    174. default:
    175. break;
    176. }
    177. }
    178. }
    179. #elif 1
    180. //2.使用Windows函数获取键盘输入
    181. //非阻塞函数,特别流畅
    182. //如果用字母,必须要用大写,大写可以识别大小写
    183. if (GetAsyncKeyState(VK_UP) || GetAsyncKeyState('W'))
    184. {
    185. if(player.y > 0)
    186. player.y -= speed;
    187. }
    188. if (GetAsyncKeyState(VK_DOWN) || GetAsyncKeyState('S'))
    189. {
    190. if (player.y < HIGHT-78)//78是飞机的高度
    191. player.y += speed;
    192. }
    193. if (GetAsyncKeyState(VK_LEFT) || GetAsyncKeyState('A'))
    194. {
    195. if(player.x+59>0)// 119/2 = 59是控制飞机子弹在左右边界的时候可以打到敌机
    196. player.x -= speed;
    197. }
    198. if (GetAsyncKeyState(VK_RIGHT) || GetAsyncKeyState('D'))
    199. {
    200. if (player.x-59 < WIDTH-119)//119是飞机的宽度
    201. player.x += speed;
    202. }
    203. #endif // 0
    204. if (GetAsyncKeyState(VK_SPACE) && Timer(100,1))//
    205. {
    206. //创建一个子弹
    207. createBullet();
    208. }
    209. }
    210. //产生敌机
    211. void createenemy()
    212. {
    213. for (int i = 0; i < ENEMY_NUM; i++)
    214. {
    215. if (!enemy[i].live)
    216. {
    217. enemy[i].live = true;
    218. enemy[i].x = rand()%(WIDTH-75);
    219. enemy[i].y = 0;
    220. enemyHP(i);
    221. printf("pos(%d,%d) %d %d\n", enemy[i].x, enemy[i].y, enemy[i].live, enemy[i].hp);
    222. break;
    223. }
    224. }
    225. }
    226. //敌机的移动
    227. void enemymove(int speed)
    228. {
    229. for (int i = 0; i < ENEMY_NUM; i++)
    230. {
    231. if (enemy[i].live)
    232. {
    233. enemy[i].y += speed;
    234. if (enemy[i].y > HIGHT)
    235. {
    236. enemy[i].live = false;
    237. }
    238. }
    239. }
    240. }
    241. //开始打飞机
    242. void playplane()
    243. {
    244. for (int i = 0; i < ENEMY_NUM; i++)
    245. {
    246. if (!enemy[i].live)
    247. continue;
    248. for (int k = 0; k < BULLET_NUM; k++)
    249. {
    250. if (!bull[k].live)
    251. continue;
    252. if (bull[k].x > enemy[i].x && bull[k].x<enemy[i].x + enemy[i].width
    253. && bull[k].y>enemy[i].y && bull[k].y < enemy[i].y + enemy[i].hight)//子弹在飞机的界面内
    254. //则代表子弹打住了飞机
    255. {
    256. bull[k].live = false;
    257. enemy[i].hp--;
    258. }
    259. }
    260. if (enemy[i].hp == 0)
    261. {
    262. enemy[i].live = false;
    263. }
    264. }
    265. }
    266. void showenemy()//测试飞机能不能一直往下面落
    267. {
    268. for (int i = 0; i < ENEMY_NUM; i++)
    269. {
    270. printf("pos(%d,%d) %d %d\n", enemy[i].x, enemy[i].y,enemy[i].live, enemy[i].hp);
    271. }
    272. }
    273. int main()
    274. {
    275. /*测试
    276. circle(50, 50, 50);//画空心圆
    277. setfillcolor(GREEN);//圆的颜色
    278. fillcircle(100, 100, 50);///实心⚪*/
    279. //创建图形窗口
    280. initgraph(WIDTH, HIGHT,SHOWCONSOLE);//宽长
    281. gameinit();
    282. //双缓冲绘图
    283. BeginBatchDraw();
    284. while (1)
    285. {
    286. gameDraw();
    287. FlushBatchDraw();
    288. playermove(5);
    289. Bullmove(5);
    290. //防止飞机全部一起出来
    291. if (Timer(500,0))
    292. {
    293. //创建一个飞机
    294. createenemy();
    295. }
    296. if (Timer(20, 2))
    297. {
    298. enemymove(1);
    299. }
    300. playplane();
    301. }
    302. EndBatchDraw();
    303. return 0;
    304. }

  • 相关阅读:
    论文阅读之Reasoning Implicit Sentiment with Chain-of-Thought Prompting
    聊城两化融合管理体系贯标
    Pytorch学习——Pytorch的入门操作 02(未完)
    3.5背景图像固定(背景附着)
    【数据结构】静态分配的顺序表插入元素
    spring boot中使用Bean Validation做优雅的参数校验
    virtualbox 网络设置实现主机和虚拟机互相访问
    LangChain和Hub的前世今生
    java+springboot+vue水果蔬菜篮子商城经营平台系统
    【Mycat】Mycat主从复制
  • 原文地址:https://blog.csdn.net/Lukegood/article/details/128140242