• C语言游戏实战(9):球球大作战


      前言:

    这款简易版的球球大作战是一款单人游戏,玩家需要控制一个小球在地图上移动,吞噬其他小球来增大自己的体积。本游戏使用C语言和easyx图形库编写,旨在帮助初学者了解游戏开发的基本概念和技巧。

    在开始编写代码之前,我们需要先了解一下游戏的基本规则和功能:

    游戏界面:游戏界面是一个矩形区域,玩家可以在这个区域内控制球的移动。

    玩家小球:玩家控制的小球可以在游戏界面内自由移动,按下空格键可以加速。

    其他小球:其他小球又分为食物小球,和ai控制的小球

    体积:玩家每吃一个其他小球体积就会增大一点,ai小球也可以通过吃食物和玩家小球增大体积。

    玩家被吃:当玩家小球被ai小球吃了,玩家小球就会回到初始点,体积也会变成初始大小。

    ai小球的追击和逃跑:当玩家小球与ai小球靠近时,ai小球会根据自身体积的大小选择追击玩家小球或者逃跑。

    接下来,我们将通过以下几个步骤来实现这个游戏:

    初始化游戏界面和小球的信息。

    处理键盘输入,实现玩家小球的移动和加速。

    生成足够数量的食物小球。

    生成ai小球,并控制其移动。

    检测小球之间的吞噬关系,增加相应的体积。

    通过学习这个游戏的开发过程,初学者将能够掌握C语言编程和easyx图形库的基本技巧。

    1. 小球的要素

    在此游戏中一个小球的要素无非就是小球所在的位置(坐标)、小球的半径、以及小球的颜色,这里我们可以用一个结构体数组来存放这些要素,以方便初始化小球的信息。

    1. struct Ball
    2. {
    3. int x;
    4. int y;
    5. float r;
    6. DWORD color;
    7. };

    2. 初始化小球的信息

    将玩家小球的初始位置设置在窗口的中间,半径大小为10。食物小球和ai小球的位置则通过rand函数、srand函数和time函数生成的随机数,随机分布在地图的各个位置,食物小球半径为1-5,ai小球的半径10.其中在这里使用了RGB随机生成一个颜色,使每个食物小球的颜色都不尽相同。

    RGB色彩模式是一种工业标准,它通过红(R)、绿(G)、蓝(B)三个颜色通道的组合来表示不同的颜色。每个通道通常分配一个0到255之间的数值,其中0表示该颜色通道没有亮度,255表示该颜色通道的最大亮度。通过调整这三个通道的值,可以生成几乎所有人类视觉系统能够感知的颜色。例如:

    • 橙色可以通过RGB值(255, 128, 0)来表示。
    • 黄色的RGB值为(255, 255, 0)。
    • 绿色的RGB值是(0, 255, 0)。
    • 蓝色的RGB值为(0, 0, 255)。
    • 紫色可以通过RGB值(170, 0, 255)来表示。
    • 黑色的RGB值为(0, 0, 0)。
    • 白色的RGB值为(255, 255, 255)。
    • 灰色的RGB值可以是(128, 128, 128),其中三个值相等即可,值越接近255,颜色就越接近白色,反之亦然。
    1. void Inset()
    2. {
    3. //玩家小球
    4. srand((unsigned)time(NULL));
    5. player.x = Wide / 2;
    6. player.y = Hight / 2;
    7. player.r = 10;
    8. //食物小球
    9. for (int i = 0; i < Food_num; i++)
    10. {
    11. Food[i].x = rand() % Wide_map;
    12. Food[i].y = rand() % Hight_map;
    13. Food[i].r = rand() % 5 + 1;
    14. Food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
    15. }
    16. //ai小球
    17. for (int i = 0; i < Enemy_num; i++)
    18. {
    19. Enemy[i].x = rand() % Wide_map;
    20. Enemy[i].y = rand() % Hight_map;
    21. Enemy[i].r = 10;
    22. Enemy[i].color = RGB(0,255,0);
    23. }
    24. }

    3. 玩家操作小球

    在这里需要用到GetAsyncKeyState(vk virtual key)函数获取异步按键状态,其中vk virtual key是虚拟键值,如果接受到这个虚拟键值,它会返回真。VK_UP、VK_DOWN、VK_LEFT、VK_RIGHT、0x20分别是上箭头键、下箭头键、左箭头键、右箭头键、空格键的虚拟键值。

    1. void Player_move()
    2. {
    3. if (GetAsyncKeyState(VK_UP))
    4. {
    5. if (player.y > 0)
    6. {
    7. player.y -= player_sleep;
    8. }
    9. }
    10. if (GetAsyncKeyState(VK_DOWN))
    11. {
    12. if (player.y < Hight_map)
    13. player.y += player_sleep;
    14. }
    15. if (GetAsyncKeyState(VK_LEFT))
    16. {
    17. if (player.x > 0)
    18. player.x -= player_sleep;
    19. }
    20. if (GetAsyncKeyState(VK_RIGHT))
    21. {
    22. if (player.x < Wide_map)
    23. player.x += player_sleep;
    24. }
    25. if (GetAsyncKeyState(0x20))
    26. {
    27. player_sleep = l + 5;
    28. }
    29. else
    30. {
    31. player_sleep = l;
    32. }
    33. }

    4. 显示出小球

    在此游戏中,小球是一个实心圆,在easyx图形库中提供了一个画实心圆的函数—solidcircle函数,通过它我们就可以在窗口中显示小球了,但显示出的小球默认颜色为白色,为了区分不同的小球,我们还需使用setfillcolor函数来改变小球的颜色。因为显示的函数、玩家操作小球的函数等函数都是放在同一个while循环重复执行的,这样就会重复显示小球,所以我们还需要用到一个清屏函数cleardevice。为了使窗口更好看可以使用setbkcolor函数修改窗口的背景颜色,以及使用line函数在窗口中画一些线,函数setlinecolor可以改变线的颜色。

    1. void Show()
    2. {
    3. //设置地图
    4. SetWorkingImage(&map);
    5. //清屏
    6. cleardevice();
    7. //背景颜色
    8. setbkcolor(WHITE);
    9. //划线颜色
    10. setlinecolor(RGB(230,231,239));
    11. //划线
    12. for (int i = 0; i < Wide_map; i += 10)
    13. {
    14. line(i, 0, i, Hight_map);
    15. }
    16. for (int i = 0; i < Hight_map; i += 10)
    17. {
    18. line(0, i, Wide_map, i);
    19. }
    20. //食物
    21. for (int i = 0; i < Food_num; i++)
    22. {
    23. setfillcolor(Food[i].color);
    24. solidcircle(Food[i].x, Food[i].y, Food[i].r);
    25. }
    26. //敌人
    27. for (int i = 0; i < Enemy_num; i++)
    28. {
    29. setfillcolor(Enemy[i].color);
    30. solidcircle(Enemy[i].x, Enemy[i].y, Enemy[i].r);
    31. }
    32. //玩家
    33. setfillcolor(RED);
    34. solidcircle(player.x, player.y, player.r);
    35. SetWorkingImage();
    36. int x = player.x - (Wide / 2);
    37. int y = player.y - (Hight / 2);
    38. //防止窗口越界
    39. if (x < 0)
    40. {
    41. x = 0;
    42. }
    43. if (y < 0)
    44. {
    45. y = 0;
    46. }
    47. if (x > Wide_map - Wide)
    48. {
    49. x = Wide_map - Wide;
    50. }
    51. if (y > Hight_map - Hight)
    52. {
    53. y = Hight_map - Hight;
    54. }
    55. //把map输出到窗口上
    56. putimage(0, 0, Wide, Hight, &map, x, y);
    57. }

    5. 生成地图

    可以使用IMAGE map(Wide_map, Hight_map) 创建一个图像映射,其中 Wide_map 代表图像的宽度,而 Hight_map 代表图像的高度。然后使用SetWorkingImage(&map),将map的地址作为参数传递给SetWorkingImage函数。这个函数的作用是将map作为当前操作的对象,以便在后续的图像处理过程中使用。最后使用putimage(0, 0, Wide, Hight, &map, x, y) 将地址绘制到窗口上,其中要让玩家小球始终出现在窗口的中央位置,那么其中的x=player.x - (Wide / 2);y=player.y - (Hight / 2);但是单单这样写就会出现窗口越界的情况,所以我们还需要限制x和y的范围:

    1. //防止窗口越界
    2. if (x < 0)
    3. {
    4. x = 0;
    5. }
    6. if (y < 0)
    7. {
    8. y = 0;
    9. }
    10. if (x > Wide_map - Wide)
    11. {
    12. x = Wide_map - Wide;
    13. }
    14. if (y > Hight_map - Hight)
    15. {
    16. y = Hight_map - Hight;
    17. }

    putimage(0, 0, Wide, Hight, &map, x, y) 这个函数调用是用于在屏幕上的特定位置绘制或显示一个图像。下面是对这个函数调用中各个参数的具体解释:

    1. (0, 0):这是图像要绘制的目标位置的左上角坐标,即x=0和y=0,通常表示屏幕的左上角。

    2. Wide:这个参数指定了要绘制的图像的宽度。

    3. Hight:这个参数指定了要绘制的图像的高度。

    4. &map:这是一个指向图像内存地址的指针,该图像将被绘制到屏幕上。在这个上下文中,map可能是一个包含了图像数据的数据结构或数组。

    5. x:这个参数通常指定了要开始绘制图像的起始点的x坐标(在图像数据中)。

    6. y:这个参数通常指定了要开始绘制图像的起始点的y坐标(在图像数据中)。

    6. ai小球的移动

    随机生成0-3的数字分别代表ai小球上下左右的移动,这样小球就会自由移动了。当玩家小球与ai小球靠近时,ai小球会追击或者逃跑,这里我们需要先计算小球的之间的距离,小球之间的距离就是两小球的圆心坐标的x相减的平方加上y相减的平方再开根号。开根号的函数为sqrt,它的头文件是

    1. //距离
    2. int Distance(int x, int y, int x1, int y1)
    3. {
    4. return sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
    5. }

    然后判断两小球的距离是否小于50个像素点,即判断是否小于玩家小球的半径 + ai小球的半径 + 50。判断完后比较两小球的半径大小,如果ai小球的半径大于玩家小球的半径,那么ai小球就要追击玩家小球,即ai小球的坐标需要靠近玩家小球的坐标,就是如果ai小球的x大于玩家小球的x那么ai小球的x就减小,同理可得剩下的操作。

    1. void Enemy_move()
    2. {
    3. srand((unsigned)time(NULL));
    4. for (int i = 0; i < Enemy_num; i++)
    5. {
    6. int direction = rand() % 4;
    7. if (Distance(player.x, player.y, Enemy[i].x, Enemy[i].y) > player.r + Enemy[i].r + 50)
    8. {
    9. if (direction == 0)
    10. {
    11. if (Enemy[i].y > 0)//防止小球越界的判断语句
    12. {
    13. Enemy[i].y -= enemy_sleep;
    14. }
    15. }
    16. if (direction == 1)
    17. {
    18. if (Enemy[i].y < Hight_map)
    19. Enemy[i].y += enemy_sleep;
    20. }
    21. if (direction == 2)
    22. {
    23. if (Enemy[i].x > 0)
    24. Enemy[i].x -= enemy_sleep;
    25. }
    26. if (direction == 3)
    27. {
    28. if (Enemy[i].x < Wide_map)
    29. Enemy[i].x += enemy_sleep;
    30. }
    31. }
    32. //敌人追击玩家
    33. if (Distance(player.x, player.y, Enemy[i].x, Enemy[i].y) < player.r + Enemy[i].r + 50)
    34. {
    35. if (Enemy[i].r > player.r)
    36. {
    37. if (Enemy[i].x < player.x)
    38. {
    39. if (Enemy[i].x < Wide_map)
    40. {
    41. Enemy[i].x += enemy_sleep;
    42. }
    43. }
    44. if (Enemy[i].x > player.x)
    45. {
    46. if (Enemy[i].x > 0)
    47. {
    48. Enemy[i].x -= enemy_sleep;
    49. }
    50. }
    51. if (Enemy[i].y < player.y)
    52. {
    53. if (Enemy[i].y < Hight_map)
    54. {
    55. Enemy[i].y += enemy_sleep;
    56. }
    57. }
    58. if (Enemy[i].y > player.y)
    59. {
    60. if (Enemy[i].y > 0)
    61. {
    62. Enemy[i].y -= enemy_sleep;
    63. }
    64. }
    65. }
    66. //敌人逃跑
    67. else
    68. {
    69. if (Enemy[i].x < player.x)
    70. {
    71. if (Enemy[i].x > 0)
    72. {
    73. Enemy[i].x -= enemy_sleep;
    74. }
    75. }
    76. if (Enemy[i].x > player.x)
    77. {
    78. if (Enemy[i].x < Wide_map)
    79. {
    80. Enemy[i].x += enemy_sleep;
    81. }
    82. }
    83. if (Enemy[i].y < player.y)
    84. {
    85. if (Enemy[i].y > 0)
    86. {
    87. Enemy[i].y -= enemy_sleep;
    88. }
    89. }
    90. if (Enemy[i].y > player.y)
    91. {
    92. if (Enemy[i].y < Hight_map)
    93. {
    94. Enemy[i].y += enemy_sleep;
    95. }
    96. }
    97. }
    98. }
    99. }
    100. }

    7. 小球之间的吞噬关系

    玩家小球与ai小球、ai小球与ai小球:

    当两小球的圆心小于最大的那个圆的半径时,小的那个球就会被吃掉。吃点就是那个小球重新找个位置生成。吃完后,吃的那个小球半径增加被吃小球半径的十分之一。

    ai小球与食物小球、玩家小球与食物小球:同上。

    1. void EatFood()
    2. {
    3. for (int i = 0; i < Food_num; i++)
    4. {
    5. //玩家吃食物
    6. if (Distance(player.x, player.y, Food[i].x, Food[i].y) < player.r)
    7. {
    8. player.r += Food[i].r / 100;
    9. Food[i].x = rand() % Wide_map;
    10. Food[i].y = rand() % Hight_map;
    11. Food[i].r = rand() % 5 + 1;
    12. Food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
    13. }
    14. }
    15. for (int j = 0; j < Enemy_num; j++)
    16. {
    17. //敌人吃食物
    18. for (int i = 0; i < Food_num; i++)
    19. {
    20. if (Distance(Enemy[j].x, Enemy[j].y, Food[i].x, Food[i].y) < Enemy[j].r)
    21. {
    22. Enemy[j].r += Food[i].r / 50;
    23. Food[i].x = rand() % Wide_map;
    24. Food[i].y = rand() % Hight_map;
    25. Food[i].r = rand() % 5 + 1;
    26. Food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
    27. }
    28. }
    29. //敌人吃敌人
    30. for (int i = 0; i < Enemy_num; i++)
    31. {
    32. if (Distance(Enemy[j].x, Enemy[j].y, Enemy[i].x, Enemy[i].y) < Enemy[j].r&& Enemy[j].r > Enemy[i].r)
    33. {
    34. Enemy[j].r += Enemy[i].r / 10;
    35. Enemy[i].x = rand() % Wide_map;
    36. Enemy[i].y = rand() % Hight_map;
    37. Enemy[i].r = 10;
    38. Enemy[i].color = RGB(0, 255, 0);
    39. }
    40. if (Distance(Enemy[j].x, Enemy[j].y, Enemy[i].x, Enemy[i].y) < Enemy[i].r && Enemy[j].r < Enemy[i].r)
    41. {
    42. Enemy[i].r += Enemy[j].r / 10;
    43. Enemy[j].x = rand() % Wide_map;
    44. Enemy[j].y = rand() % Hight_map;
    45. Enemy[j].r = 10;
    46. Enemy[j].color = RGB(0, 255, 0);
    47. }
    48. }
    49. if (Distance(player.x, player.y, Enemy[j].x, Enemy[j].y) < player.r)
    50. {
    51. //玩家吃敌人
    52. if (player.r > Enemy[j].r)
    53. {
    54. player.r += Enemy[j].r / 10;
    55. Enemy[j].x = rand() % Wide_map;
    56. Enemy[j].y = rand() % Hight_map;
    57. Enemy[j].r = 10;
    58. Enemy[j].color = RGB(0, 255, 0);
    59. }
    60. //敌人吃玩家
    61. else
    62. {
    63. if (invincibility == 0)
    64. {
    65. Enemy[j].r += player.r / 10;
    66. player.x = Wide / 2;
    67. player.y = Hight / 2;
    68. player.r = 10;
    69. invincibility = 10;
    70. }
    71. }
    72. }
    73. }
    74. }

    最终效果:

    球球大作战

    源码:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #define Wide 1024
    6. #define Hight 640
    7. #define Wide_map (Wide*5)
    8. #define Hight_map (Hight*5)
    9. #define Food_num 1888
    10. #define Enemy_num 888
    11. //整个游戏地图
    12. IMAGE map(Wide_map, Hight_map);
    13. //复活时的无敌时间
    14. int invincibility = 10;
    15. //玩家速度
    16. int player_sleep = 5;
    17. int l = 5;
    18. int enemy_sleep = 5;
    19. struct Ball
    20. {
    21. int x;
    22. int y;
    23. float r;
    24. DWORD color;
    25. };
    26. struct Ball player;
    27. struct Ball Food[Food_num];
    28. struct Ball Enemy[Enemy_num];
    29. //初始化球的数据
    30. void Inset()
    31. {
    32. srand((unsigned)time(NULL));
    33. player.x = Wide / 2;
    34. player.y = Hight / 2;
    35. player.r = 10;
    36. for (int i = 0; i < Food_num; i++)
    37. {
    38. Food[i].x = rand() % Wide_map;
    39. Food[i].y = rand() % Hight_map;
    40. Food[i].r = rand() % 5 + 1;
    41. Food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
    42. }
    43. for (int i = 0; i < Enemy_num; i++)
    44. {
    45. Enemy[i].x = rand() % Wide_map;
    46. Enemy[i].y = rand() % Hight_map;
    47. Enemy[i].r = 10;
    48. Enemy[i].color = RGB(0,255,0);
    49. }
    50. }
    51. //玩家操作
    52. void Player_move()
    53. {
    54. if (GetAsyncKeyState(VK_UP))
    55. {
    56. if (player.y > 0)
    57. {
    58. player.y -= player_sleep;
    59. }
    60. }
    61. if (GetAsyncKeyState(VK_DOWN))
    62. {
    63. if (player.y < Hight_map)
    64. player.y += player_sleep;
    65. }
    66. if (GetAsyncKeyState(VK_LEFT))
    67. {
    68. if (player.x > 0)
    69. player.x -= player_sleep;
    70. }
    71. if (GetAsyncKeyState(VK_RIGHT))
    72. {
    73. if (player.x < Wide_map)
    74. player.x += player_sleep;
    75. }
    76. if (GetAsyncKeyState(0x20))
    77. {
    78. player_sleep = l + 5;
    79. }
    80. else
    81. {
    82. player_sleep = l;
    83. }
    84. }
    85. //距离
    86. int Distance(int x, int y, int x1, int y1)
    87. {
    88. return sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
    89. }
    90. //敌人移动
    91. void Enemy_move()
    92. {
    93. srand((unsigned)time(NULL));
    94. for (int i = 0; i < Enemy_num; i++)
    95. {
    96. int direction = rand() % 400;
    97. if (Distance(player.x, player.y, Enemy[i].x, Enemy[i].y) > player.r + Enemy[i].r + 50)
    98. {
    99. if (direction < 100)
    100. {
    101. if (Enemy[i].y > 0)
    102. {
    103. Enemy[i].y -= enemy_sleep;
    104. }
    105. }
    106. if (direction < 200 && direction >= 100)
    107. {
    108. if (Enemy[i].y < Hight_map)
    109. Enemy[i].y += enemy_sleep;
    110. }
    111. if (direction < 300 && direction >= 200)
    112. {
    113. if (Enemy[i].x > 0)
    114. Enemy[i].x -= enemy_sleep;
    115. }
    116. if (direction <400 && direction >= 300)
    117. {
    118. if (Enemy[i].x < Wide_map)
    119. Enemy[i].x += enemy_sleep;
    120. }
    121. }
    122. //敌人追击玩家
    123. if (Distance(player.x, player.y, Enemy[i].x, Enemy[i].y) < player.r + Enemy[i].r + 50)
    124. {
    125. if (Enemy[i].r > player.r)
    126. {
    127. if (Enemy[i].x < player.x)
    128. {
    129. if (Enemy[i].x < Wide_map)
    130. {
    131. Enemy[i].x += enemy_sleep;
    132. }
    133. }
    134. if (Enemy[i].x > player.x)
    135. {
    136. if (Enemy[i].x > 0)
    137. {
    138. Enemy[i].x -= enemy_sleep;
    139. }
    140. }
    141. if (Enemy[i].y < player.y)
    142. {
    143. if (Enemy[i].y < Hight_map)
    144. {
    145. Enemy[i].y += enemy_sleep;
    146. }
    147. }
    148. if (Enemy[i].y > player.y)
    149. {
    150. if (Enemy[i].y > 0)
    151. {
    152. Enemy[i].y -= enemy_sleep;
    153. }
    154. }
    155. }
    156. //敌人逃跑
    157. else
    158. {
    159. if (Enemy[i].x < player.x)
    160. {
    161. if (Enemy[i].x > 0)
    162. {
    163. Enemy[i].x -= enemy_sleep;
    164. }
    165. }
    166. if (Enemy[i].x > player.x)
    167. {
    168. if (Enemy[i].x < Wide_map)
    169. {
    170. Enemy[i].x += enemy_sleep;
    171. }
    172. }
    173. if (Enemy[i].y < player.y)
    174. {
    175. if (Enemy[i].y > 0)
    176. {
    177. Enemy[i].y -= enemy_sleep;
    178. }
    179. }
    180. if (Enemy[i].y > player.y)
    181. {
    182. if (Enemy[i].y < Hight_map)
    183. {
    184. Enemy[i].y += enemy_sleep;
    185. }
    186. }
    187. }
    188. }
    189. //for (int j = 0; j < Enemy_num; j++)
    190. //{
    191. // if (Distance(Enemy[j].x, Enemy[j].y, Enemy[i].x, Enemy[i].y) < Enemy[j].r + Enemy[i].r + 30)
    192. // {
    193. // //敌人追敌人
    194. // if (Enemy[i].r > Enemy[j].r)
    195. // {
    196. // int sleep = rand() % 6;
    197. // int enemy_sleep1;
    198. // if (sleep > 2)
    199. // {
    200. // enemy_sleep1 = enemy_sleep;
    201. // }
    202. // else
    203. // {
    204. // enemy_sleep1 = enemy_sleep + 5;
    205. // }
    206. // if (Enemy[i].x < Enemy[j].x)
    207. // {
    208. // if (Enemy[i].x < Wide_map)
    209. // {
    210. // Enemy[i].x += enemy_sleep1;
    211. // }
    212. // }
    213. // if (Enemy[i].x > Enemy[j].x)
    214. // {
    215. // if (Enemy[i].x > 0)
    216. // {
    217. // Enemy[i].x -= enemy_sleep1;
    218. // }
    219. // }
    220. // if (Enemy[i].y < Enemy[j].y)
    221. // {
    222. // if (Enemy[i].y < Hight_map)
    223. // {
    224. // Enemy[i].y += enemy_sleep1;
    225. // }
    226. // }
    227. // if (Enemy[i].y > Enemy[j].y)
    228. // {
    229. // if (Enemy[i].y > 0)
    230. // {
    231. // Enemy[i].y -= enemy_sleep1;
    232. // }
    233. // }
    234. // }
    235. // //逃跑
    236. // else
    237. // {
    238. // int sleep = rand() % 6;
    239. // int enemy_sleep1;
    240. // if (sleep > 2)
    241. // {
    242. // enemy_sleep1 = enemy_sleep;
    243. // }
    244. // else
    245. // {
    246. // enemy_sleep1 = enemy_sleep + 5;
    247. // }
    248. // if (Enemy[i].x < Enemy[j].x)
    249. // {
    250. // if (Enemy[i].x > 0)
    251. // {
    252. // Enemy[i].x -= enemy_sleep1;
    253. // }
    254. // }
    255. // if (Enemy[i].x > Enemy[j].x)
    256. // {
    257. // if (Enemy[i].x < Wide_map)
    258. // {
    259. // Enemy[i].x += enemy_sleep1;
    260. // }
    261. // }
    262. // if (Enemy[i].y < Enemy[j].y)
    263. // {
    264. // if (Enemy[i].y > 0)
    265. // {
    266. // Enemy[i].y -= enemy_sleep1;
    267. // }
    268. // }
    269. // if (Enemy[i].y > Enemy[j].y)
    270. // {
    271. // if (Enemy[i].y < Hight_map)
    272. // {
    273. // Enemy[i].y += enemy_sleep1;
    274. // }
    275. // }
    276. // }
    277. // }
    278. //}
    279. }
    280. }
    281. //吃食物
    282. void EatFood()
    283. {
    284. for (int i = 0; i < Food_num; i++)
    285. {
    286. //玩家吃食物
    287. if (Distance(player.x, player.y, Food[i].x, Food[i].y) < player.r)
    288. {
    289. player.r += Food[i].r / 100;
    290. Food[i].x = rand() % Wide_map;
    291. Food[i].y = rand() % Hight_map;
    292. Food[i].r = rand() % 5 + 1;
    293. Food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
    294. }
    295. }
    296. for (int j = 0; j < Enemy_num; j++)
    297. {
    298. //敌人吃食物
    299. for (int i = 0; i < Food_num; i++)
    300. {
    301. if (Distance(Enemy[j].x, Enemy[j].y, Food[i].x, Food[i].y) < Enemy[j].r)
    302. {
    303. Enemy[j].r += Food[i].r / 50;
    304. Food[i].x = rand() % Wide_map;
    305. Food[i].y = rand() % Hight_map;
    306. Food[i].r = rand() % 5 + 1;
    307. Food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
    308. }
    309. }
    310. //敌人吃敌人
    311. for (int i = 0; i < Enemy_num; i++)
    312. {
    313. if (Distance(Enemy[j].x, Enemy[j].y, Enemy[i].x, Enemy[i].y) < Enemy[j].r&& Enemy[j].r > Enemy[i].r)
    314. {
    315. Enemy[j].r += Enemy[i].r / 10;
    316. Enemy[i].x = rand() % Wide_map;
    317. Enemy[i].y = rand() % Hight_map;
    318. Enemy[i].r = 10;
    319. Enemy[i].color = RGB(0, 255, 0);
    320. }
    321. if (Distance(Enemy[j].x, Enemy[j].y, Enemy[i].x, Enemy[i].y) < Enemy[i].r && Enemy[j].r < Enemy[i].r)
    322. {
    323. Enemy[i].r += Enemy[j].r / 10;
    324. Enemy[j].x = rand() % Wide_map;
    325. Enemy[j].y = rand() % Hight_map;
    326. Enemy[j].r = 10;
    327. Enemy[j].color = RGB(0, 255, 0);
    328. }
    329. }
    330. if (Distance(player.x, player.y, Enemy[j].x, Enemy[j].y) < player.r)
    331. {
    332. //玩家吃敌人
    333. if (player.r > Enemy[j].r)
    334. {
    335. player.r += Enemy[j].r / 10;
    336. Enemy[j].x = rand() % Wide_map;
    337. Enemy[j].y = rand() % Hight_map;
    338. Enemy[j].r = 10;
    339. Enemy[j].color = RGB(0, 255, 0);
    340. }
    341. //敌人吃玩家
    342. else
    343. {
    344. if (invincibility == 0)
    345. {
    346. Enemy[j].r += player.r / 10;
    347. player.x = Wide / 2;
    348. player.y = Hight / 2;
    349. player.r = 10;
    350. invincibility = 10;
    351. }
    352. }
    353. }
    354. }
    355. }
    356. //显示
    357. void Show()
    358. {
    359. //设置地图
    360. SetWorkingImage(&map);
    361. //清屏
    362. cleardevice();
    363. //背景颜色
    364. setbkcolor(WHITE);
    365. //划线颜色
    366. setlinecolor(RGB(230,231,239));
    367. //划线
    368. for (int i = 0; i < Wide_map; i += 10)
    369. {
    370. line(i, 0, i, Hight_map);
    371. }
    372. for (int i = 0; i < Hight_map; i += 10)
    373. {
    374. line(0, i, Wide_map, i);
    375. }
    376. //食物
    377. for (int i = 0; i < Food_num; i++)
    378. {
    379. setfillcolor(Food[i].color);
    380. solidcircle(Food[i].x, Food[i].y, Food[i].r);
    381. }
    382. //敌人
    383. for (int i = 0; i < Enemy_num; i++)
    384. {
    385. setfillcolor(Enemy[i].color);
    386. solidcircle(Enemy[i].x, Enemy[i].y, Enemy[i].r);
    387. }
    388. //玩家
    389. setfillcolor(RED);
    390. solidcircle(player.x, player.y, player.r);
    391. SetWorkingImage();
    392. int x = player.x - (Wide / 2);
    393. int y = player.y - (Hight / 2);
    394. //防止窗口越界
    395. if (x < 0)
    396. {
    397. x = 0;
    398. }
    399. if (y < 0)
    400. {
    401. y = 0;
    402. }
    403. if (x > Wide_map - Wide)
    404. {
    405. x = Wide_map - Wide;
    406. }
    407. if (y > Hight_map - Hight)
    408. {
    409. y = Hight_map - Hight;
    410. }
    411. //把map输出到窗口上
    412. putimage(0, 0, Wide, Hight, &map, x, y);
    413. }
    414. int main()
    415. {
    416. initgraph(Wide, Hight);
    417. Inset();
    418. //缓冲
    419. BeginBatchDraw();
    420. while (1)
    421. {
    422. if (invincibility > 0)
    423. invincibility--;
    424. Show();
    425. //玩家操作
    426. Player_move();
    427. Enemy_move();
    428. EatFood();
    429. //刷新
    430. FlushBatchDraw();
    431. }
    432. closegraph();
    433. return 0;
    434. }

  • 相关阅读:
    封装composer包
    高等数学(第七版)同济大学 习题5-3 个人解答(前3题)
    [设计模式] 浅谈奇异递归模板模式
    Django笔记二十之手动编写migration文件
    手把手教你写一个图片预览组件
    Java字符串常量池
    java 阿里云上传照片
    C#往数据库上传文件
    ChatGPT提示词(prompt)资源汇总
    全局事件总线概述
  • 原文地址:https://blog.csdn.net/weixin_58252863/article/details/136639127