当前位置:   article > 正文

贪吃蛇游戏(C语言实现)_c语言贪吃蛇游戏代码

c语言贪吃蛇游戏代码

 前言

本篇基于Esayx图形库的基础上,在Visual Studio编译器上运行,主要通过构建各个不同功能的函数(面向过程)来实现这款经典的小游戏———贪吃蛇

 一 主要函数

//该函数用于绘制出一个网格出来
void paintGrid();

//该函数用于绘制出一个蛇
void paintSnake(node* snake, int n);

//该函数将依次移动蛇节头并根据前进方向设置蛇头
//以此来控制蛇的移动
node snakeMove(node* snake, int length, int direction);

//该函数通过键盘输入的方式来调整蛇移动的方向
void changDirection(enum direction* p);

//该函数用于在画布中创建出一个食物类型
node creatFood(node* snake, int length);

//该函数用于在画布中生成一个食物
void paintFood(node* food);

//该函数用于判断游戏是否结束
bool isGameover(node* snake, int length);

//该函数用于将游戏数据初始化
void reset(node* snake, int* plength, enum direction* pd);

 二 对各个函数进行实现

1.定义结构体以及一些枚举变量、常量

  1. //我们创建的画布大小是600*800大小的,将其分成宽为40的小矩形
  2. #define NOOD_WIDTH 40
  3. //该枚举类型分别对应四个方向,用键盘上的wsad来表示上下左右
  4. enum direction
  5. {
  6. eUp,
  7. eDown,
  8. eLeft,
  9. eRight
  10. };
  11. //该结构node用于记录蛇的每一个节点
  12. typedef struct
  13. {
  14. int x;
  15. int y;
  16. }node;

 2.//该函数用于绘制出一个网格出来
void paintGrid();

  1. void paintGrid()
  2. {
  3. setlinecolor(WHITE);
  4. for (int x = 0; x < 800; x += NOOD_WIDTH)//以这个宽度为间距进行画竖线
  5. {
  6. line(x, 0, x, 600);//画竖线
  7. }
  8. for (int y = 0; y < 600; y += NOOD_WIDTH)//以这个宽度为间距进行画横线
  9. {
  10. line(0, y, 800, y);//画横线
  11. }
  12. }

3.//该函数用于绘制出一个蛇
void paintSnake(node* snake, int n);

  1. void paintSnake(node* snake, int n)
  2. {
  3. int left, top, right, bottom;
  4. for (int i = 0; i < n; i++)
  5. {
  6. left = snake[i].x * NOOD_WIDTH;//*(snake + i).x
  7. top = snake[i].y * NOOD_WIDTH;
  8. right = (snake[i].x + 1) * NOOD_WIDTH;
  9. bottom = (snake[i].y + 1) * NOOD_WIDTH;
  10. setlinecolor(BLACK);
  11. fillrectangle(left, top, right, bottom);
  12. }
  13. }

 4.//该函数将依次移动蛇节头并根据前进方向设置蛇头
//以此来控制蛇的移动
node snakeMove(node* snake, int length, int direction);

  1. node snakeMove(node* snake, int length, int direction)
  2. {
  3. node tail = snake[length - 1];
  4. //用一个循环将数组中的元素从后往前依次进行覆盖
  5. for (int i = length - 1; i > 0; i--)
  6. {
  7. snake[i] = snake[i - 1];//将前一个节点覆盖后一个节点
  8. }
  9. node newhead = snake[0];
  10. if (direction == eUp)
  11. {
  12. newhead.y--;//在原蛇头的基础上进行修改
  13. }
  14. if (direction == eDown)
  15. {
  16. newhead.y++;
  17. }
  18. if (direction == eLeft)
  19. {
  20. newhead.x--;
  21. }
  22. if (direction == eRight)
  23. {
  24. newhead.x++;
  25. }
  26. snake[0] = newhead;//最后在把修改后的蛇头数据赋值给原数组的首元素
  27. return tail;
  28. }

5. //该函数通过键盘输入的方式来调整蛇移动的方向
void changDirection(enum direction* p);

 

  1. void changDirection(enum direction* p)
  2. {
  3. if (_kbhit() != 0)
  4. {
  5. char c = _getch();
  6. switch (c)
  7. {
  8. case 'a':
  9. if(*p != eRight)
  10. *p = eLeft;
  11. break;
  12. case 'd':
  13. if (*p != eLeft)
  14. *p = eRight;
  15. break;
  16. case 'w':
  17. if (*p != eDown)
  18. *p = eUp;
  19. break;
  20. case's':
  21. if (*p != eUp)
  22. *p = eDown;
  23. break;
  24. }
  25. }
  26. }

 6.//该函数用于在画布中创建出一个食物类型
node creatFood(node* snake, int length);

  1. node creatFood(node* snake, int length)
  2. {
  3. //先在画布圈定的范围之内随机生成一个食物点
  4. node food;
  5. //然后用一个死循环来对食物点进行检验(不能与蛇的身体进行重合)
  6. while (1)
  7. {
  8. food.x = rand() % (800 / NOOD_WIDTH);
  9. food.y = rand() % (600 / NOOD_WIDTH);
  10. int i = 0;
  11. for (i = 0; i < length; i++)
  12. {
  13. if (food.x == snake[i].x && food.y == snake[i].y)
  14. break;
  15. }
  16. if (i < length)
  17. continue;
  18. else
  19. break;
  20. }
  21. return food;
  22. }

7.//该函数用于在画布中生成一个食物
void paintFood(node* food);

  1. void paintFood(node* food)
  2. {
  3. int left, top, right, bottom;
  4. left = food->x * NOOD_WIDTH;//*(snake + i).x
  5. top = food->y* NOOD_WIDTH;
  6. right = (food->x + 1) * NOOD_WIDTH;
  7. bottom = (food->y + 1) * NOOD_WIDTH;
  8. setfillcolor(YELLOW);
  9. solidrectangle(left, top, right, bottom);
  10. setfillcolor(WHITE);
  11. }

 8.//该函数用于判断游戏是否结束
bool isGameover(node* snake, int length);

 

  1. bool isGameover(node* snake, int length)
  2. {
  3. if (snake[0].x < 0 || snake[0].x>800 / NOOD_WIDTH)
  4. {
  5. return true;
  6. }
  7. if (snake[0].y < 0 || snake[0].y>600 / NOOD_WIDTH)
  8. {
  9. return true;
  10. }
  11. for (int i = 1; i < length; i++)
  12. {
  13. if (snake[0].x == snake[i].x && snake[0].y == snake[i].y)
  14. return true;
  15. }
  16. return false;
  17. }

9. //该函数用于将游戏数据初始化
void reset(node* snake, int* plength, enum direction* pd);

  1. void reset(node* snake, int* plength, enum direction* pd)
  2. {
  3. for (int i = 0; i < 5; i++)
  4. {
  5. for (int j = 5; j > 0; j--)
  6. {
  7. snake[i].x = j;
  8. }
  9. snake[i].y = 7;
  10. }
  11. *plength = 5;
  12. *pd = eRight;
  13. }

三 主函数部分 

 

  1. int main()
  2. {
  3. initgraph(800, 600);
  4. setbkcolor(RGB(164, 225, 202));
  5. cleardevice();
  6. node snake[100] = { {5,7},{4,7},{3,7},{2,7},{1,7} };
  7. int length = 5;
  8. enum direction d = eRight;
  9. srand(unsigned int(time(NULL)));//用当前时间作为随机数种子
  10. node food = creatFood(snake,length);
  11. while (1)
  12. {
  13. cleardevice();
  14. paintGrid();
  15. paintSnake(snake, length);
  16. paintFood(&food);
  17. Sleep(500);
  18. changDirection(&d);
  19. node last_tail = snakeMove(snake, length, d);
  20. if (snake[0].x == food.x && snake[0].y == food.y)
  21. {
  22. if (length < 100)
  23. {
  24. snake[length] = last_tail;
  25. length++;
  26. }
  27. food = creatFood(snake, length);
  28. }
  29. if (isGameover(snake, length) == true)
  30. {
  31. reset(snake, &length, &d);
  32. food = creatFood(snake, length);
  33. }
  34. }
  35. getchar();
  36. closegraph();
  37. return 0;
  38. }

 四 完整代码

完整代码如下: 

  1. #include <easyx.h>
  2. #include <stdio.h>
  3. #include <conio.h>
  4. #include <time.h>
  5. #define NODE_WIDTH 40
  6. // 节点
  7. typedef struct {
  8. int x;
  9. int y;
  10. }node;
  11. enum direction
  12. {
  13. eUp,
  14. eDown,
  15. eLeft,
  16. eRight
  17. };
  18. void paintGrid()
  19. {
  20. setlinecolor(WHITE);
  21. for (int x = 0; x < 800; x += NOOD_WIDTH)
  22. {
  23. line(x, 0, x, 600);//画竖直线段
  24. }
  25. for (int y = 0; y < 600; y += NOOD_WIDTH)
  26. {
  27. line(0, y, 800, y);//画竖直线段
  28. }
  29. }
  30. void paintSnake(node* snake, int n)
  31. {
  32. int left, top, right, bottom;
  33. for (int i = 0; i < n; i++)
  34. {
  35. left = snake[i].x * NOOD_WIDTH;//*(snake + i).x
  36. top = snake[i].y * NOOD_WIDTH;
  37. right = (snake[i].x + 1) * NOOD_WIDTH;
  38. bottom = (snake[i].y + 1) * NOOD_WIDTH;
  39. setlinecolor(BLACK);
  40. fillrectangle(left, top, right, bottom);
  41. }
  42. }
  43. node snakeMove(node* snake, int length, int direction)
  44. {
  45. node tail = snake[length - 1];
  46. //用一个循环将数组中的元素从后往前依次进行覆盖
  47. for (int i = length - 1; i > 0; i--)
  48. {
  49. snake[i] = snake[i - 1];//将前一个节点覆盖后一个节点
  50. }
  51. node newhead = snake[0];
  52. if (direction == eUp)
  53. {
  54. newhead.y--;//在原蛇头的基础上进行修改
  55. }
  56. if (direction == eDown)
  57. {
  58. newhead.y++;
  59. }
  60. if (direction == eLeft)
  61. {
  62. newhead.x--;
  63. }
  64. if (direction == eRight)
  65. {
  66. newhead.x++;
  67. }
  68. snake[0] = newhead;//最后在把修改后的蛇头数据赋值给原数组的首元素
  69. return tail;
  70. }
  71. void changDirection(enum direction* p)
  72. {
  73. if (_kbhit() != 0)
  74. {
  75. char c = _getch();
  76. switch (c)
  77. {
  78. case 'a':
  79. if(*p != eRight)
  80. *p = eLeft;
  81. break;
  82. case 'd':
  83. if (*p != eLeft)
  84. *p = eRight;
  85. break;
  86. case 'w':
  87. if (*p != eDown)
  88. *p = eUp;
  89. break;
  90. case's':
  91. if (*p != eUp)
  92. *p = eDown;
  93. break;
  94. }
  95. }
  96. }
  97. node creatFood(node* snake, int length)
  98. {
  99. //先在画布圈定的范围之内随机生成一个食物点
  100. node food;
  101. //然后用一个死循环来对食物点进行检验(不能与蛇的身体进行重合)
  102. while (1)
  103. {
  104. food.x = rand() % (800 / NOOD_WIDTH);
  105. food.y = rand() % (600 / NOOD_WIDTH);
  106. int i = 0;
  107. for (i = 0; i < length; i++)
  108. {
  109. if (food.x == snake[i].x && food.y == snake[i].y)
  110. break;
  111. }
  112. if (i < length)
  113. continue;
  114. else
  115. break;
  116. }
  117. return food;
  118. }
  119. void paintFood(node* food)
  120. {
  121. int left, top, right, bottom;
  122. left = food->x * NOOD_WIDTH;//*(snake + i).x
  123. top = food->y* NOOD_WIDTH;
  124. right = (food->x + 1) * NOOD_WIDTH;
  125. bottom = (food->y + 1) * NOOD_WIDTH;
  126. setfillcolor(YELLOW);
  127. solidrectangle(left, top, right, bottom);
  128. setfillcolor(WHITE);
  129. }
  130. bool isGameover(node* snake, int length)
  131. {
  132. if (snake[0].x < 0 || snake[0].x>800 / NOOD_WIDTH)
  133. {
  134. return true;
  135. }
  136. if (snake[0].y < 0 || snake[0].y>600 / NOOD_WIDTH)
  137. {
  138. return true;
  139. }
  140. for (int i = 1; i < length; i++)
  141. {
  142. if (snake[0].x == snake[i].x && snake[0].y == snake[i].y)
  143. return true;
  144. }
  145. return false;
  146. }
  147. void reset(node* snake, int* plength, enum direction* pd)
  148. {
  149. for (int i = 0; i < 5; i++)
  150. {
  151. for (int j = 5; j > 0; j--)
  152. {
  153. snake[i].x = j;
  154. }
  155. snake[i].y = 7;
  156. }
  157. *plength = 5;
  158. *pd = eRight;
  159. }
  160. int main()
  161. {
  162. initgraph(800, 600);
  163. setbkcolor(RGB(164, 225, 202));
  164. cleardevice();
  165. node snake[100] = { {5,7},{4,7},{3,7},{2,7},{1,7} };
  166. int length = 5;
  167. enum direction d = eRight;
  168. srand(unsigned int(time(NULL)));//用当前时间作为随机数种子
  169. node food = creatFood(snake,length);
  170. while (1)
  171. {
  172. cleardevice();
  173. paintGrid();
  174. paintSnake(snake, length);
  175. paintFood(&food);
  176. Sleep(500);
  177. changDirection(&d);
  178. node last_tail = snakeMove(snake, length, d);
  179. if (snake[0].x == food.x && snake[0].y == food.y)
  180. {
  181. if (length < 100)
  182. {
  183. snake[length] = last_tail;
  184. length++;
  185. }
  186. food = creatFood(snake, length);
  187. }
  188. if (isGameover(snake, length) == true)
  189. {
  190. reset(snake, &length, &d);
  191. food = creatFood(snake, length);
  192. }
  193. }
  194. getchar();
  195. closegraph();
  196. return 0;
  197. }

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/358862
推荐阅读
相关标签
  

闽ICP备14008679号