当前位置:   article > 正文

C语言实现超简单贪吃蛇(代码是抄的),我做一下讲解_贪吃蛇代码

贪吃蛇代码

首先声明,代码是抄的,代码是抄的,代码是抄的,重要的事情说三遍。。

如果有侵权请联系我删除。。

贴原作者的视频。

在b站看的,视频找不到了,我等下会贴代码。。

先分析一下游戏的数据结构

1.游戏地图用一个数组bk[20][20]存储,有四种状态。0表示没东西;1表示墙;2表示果实;3表示蛇。

2.用xy[2]来存放蛇前进的坐标,xy[0]表示横坐标,xy[1]表示纵坐标。。

3.move[20][20]表示蛇的运动轨迹。也是在和地图一样的格子上,其中move[0][0]记录当前的步数.这个主要是用来刷新蛇使用。

3.look[4]用来记录游戏的各种数据,look[0]为朝向,look[1]为蛇的长度,look[2]为失败判定,look[3]为分数

接下来分析游戏的刷新策略:

1.一开始初始化地图,随机生成果实位置,蛇固定出现在 8,8坐标处。

2.接下来接收移动命令之后进行蛇头位置的刷新。

3.根据move数组的值和蛇的长度进行蛇尾的刷新(实际上每次移动蛇只需要将蛇尾变成地图就行了),这是关键,一定要理解.

举个栗子:


对于这种情况,格子里记录的是轨迹数,一开始在1的位置,刷新一次之后就在2的位置了,加入此时蛇的长度为1,那么1 == 2 -1,那么判定蛇尾已经不在1的位置而跑到2的位置了。(可以自行将2替换成x+1,1替换成x,这样有普遍意义)

分析完了,接下啦贴代码:

  1. #include "stdafx.h"
  2. #include <stdio.h>
  3. #include <windows.h>
  4. #include <time.h>
  5. #include <conio.h>
  6. #include <stdlib.h>
  7. //方向键的ASCLL值:上72,左75,右77,下80
  8. //背景颜色的代码: 0=黑色 1蓝色 2 绿色 3湖蓝色 4红色 5紫色 6黄色 7白色 8灰色 9淡蓝色
  9. //**改变当前光标方块的背景颜色和字体颜色**//
  10. void BackGround(unsigned int ForeColor = 7, unsigned int BackGroundColor = 0) {
  11. HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台的句柄
  12. SetConsoleTextAttribute(handle, ForeColor + BackGroundColor * 0x10);//改变当前光标的背景和字体颜色
  13. }
  14. //**改变光标的位置**//
  15. void gotoxy(int x, int y) {
  16. HANDLE handle;
  17. COORD coord; //获取坐标轴结构体
  18. coord.X = x;
  19. coord.Y = y;
  20. handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄,值为-11
  21. SetConsoleCursorPosition(handle, coord); //移动光标到x,y处
  22. }
  23. //**初始化地图数据**//
  24. void restart(int bk[20][20], int look[4], int move[20][20]) {
  25. //bk为总的地图数据记录整个地图,为1时表示墙体,为2时表示果实,为3时表示蛇
  26. //look记录数据,为0时表示朝向,为1时表示长度,为3时表示胜负情况,为4表示分数
  27. //move记录蛇走过的路程,用来打印蛇时判断用
  28. int pp, qq; //用来记录获取的随机坐标
  29. //接下来要初始化整个地图//
  30. for(int i=0;i<=16;i++)
  31. for (int j = 0; j <= 16; j++) {
  32. if (i == 0 || i == 16 || j == 0 || j == 16) bk[i][j] = 1;//1表示墙体
  33. else bk[i][j] = 0; //0表示什么都没有
  34. move[i][j] = 0; //该数组用来记录蛇移动的轨迹
  35. }
  36. //将蛇初始化在8,8坐标上
  37. bk[8][8] = 3;
  38. move[8][8] = 1;//则此时8,8,上的轨迹就应该记录为1
  39. move[0][0] = 1;//用此来记录步数
  40. pp = rand() % 15 + 1;//范围是1-15
  41. qq = rand() % 15 + 1;
  42. bk[pp][qq] = 2;//表示这个位置有果实了
  43. look[0] = 1;//表示朝向,向上
  44. look[1] = 1;//表示长度
  45. look[2] = 0;//当为1是表示失败
  46. look[3] = 0;//记录得分
  47. //接下来要绘制地图//
  48. for(int i=0;i<=16;i++)
  49. for (int j = 0; j <= 16; j++) {
  50. gotoxy(i * 2, j);//光标移动,每个光标都是矩形
  51. switch (bk[i][j]) {
  52. case 0:
  53. BackGround(0, 0);
  54. break;//如果没有东西打印黑色
  55. case 1:
  56. BackGround(0, 1);
  57. break;//墙打印蓝色
  58. case 2:
  59. BackGround(0, 2);
  60. break;//果实打印绿色
  61. case 3:
  62. BackGround(0, 3);
  63. break;//蛇打印湖蓝色
  64. default:
  65. break;
  66. }
  67. printf(" ");//地图中直接就是涂空格符
  68. }
  69. //接下来要显示积分//
  70. gotoxy(35, 0);
  71. BackGround(7, 0);//用白字黑底打印
  72. printf("现在得分是:%d,请再接再厉!^_^", look[2]);
  73. }
  74. //**运动主体**//
  75. void map(int bk[20][20], int look[4], int xy[2], int move[20][20]) {
  76. //bk是地图信息,look作数据记录,xy记录坐标,move记录蛇的运动轨迹
  77. int b[10], qq=0, pp=0;//b用来吸收输入,qq和pp用来随机初始化果实坐标
  78. if (kbhit()) {//记录按下的是哪个方向键
  79. b[0] = getch();//用b来记录
  80. if (b[0] == 224) b[0] = getch();//如果为224表示为方向键,但是要再一次获取才行
  81. if (b[0] == 72 && look[0] != 2)
  82. //如果输入的为上并且朝向不为下
  83. look[0] = 1;
  84. if (b[0] == 80 && look[0] != 1)
  85. look[0] = 2;
  86. if (b[0] == 75 && look[0] != 4)
  87. look[0] = 3;
  88. if (b[0] == 77 && look[0] != 3)
  89. look[0] = 4;
  90. }
  91. switch (look[0]) {
  92. case 1:
  93. //往上走
  94. xy[1]--;
  95. break;
  96. case 2:
  97. //往下走
  98. xy[1]++;
  99. break;
  100. case 3:
  101. //往左走
  102. xy[0]--;
  103. break;
  104. case 4:
  105. //往右走
  106. xy[0]++;
  107. break;
  108. }
  109. //接下来蛇就开始走动了//
  110. move[0][0]++;//蛇的步数加一
  111. move[xy[0]][xy[1]] = move[0][0];//记录当前格子中蛇的轨迹
  112. gotoxy(35, 2);
  113. BackGround(7, 0);
  114. printf("横坐标:%d,纵坐标:%d", xy[0],xy[1]);
  115. gotoxy(xy[0] * 2, xy[1]);//这里蛇头就往前移动了
  116. BackGround(0, 3);//与蛇体一个颜色
  117. printf(" ");
  118. //如果吃了果实//
  119. if (bk[xy[0]][xy[1]] == 2) {
  120. look[2]++;//分数加一
  121. look[1]++;//长度加一
  122. //更新分数
  123. gotoxy(35, 0);
  124. BackGround(7, 0);
  125. printf("现在得分是:%d,请再接再厉!^_^", look[2]);
  126. while (bk[pp][qq] != 0) {
  127. pp = rand() % 15 + 1;
  128. qq = rand() % 15 + 1;
  129. }
  130. bk[pp][qq] = 2;//将这个地方变为果实
  131. gotoxy(pp * 2, qq);
  132. BackGround(0, 2);
  133. printf(" ");
  134. }
  135. //如果撞了墙或者自己//
  136. if (bk[xy[0]][xy[1]] == 1 || bk[xy[0]][xy[1]] == 3) {
  137. look[3] = 1;//表示已经输了
  138. gotoxy(6, 6);
  139. BackGround(7, 0);
  140. printf("你输了,最后得分:%d", look[2]);
  141. }
  142. bk[xy[0]][xy[1]] = 3;//使这个位置变成蛇
  143. //接下来要检测蛇然后刷新蛇的位置//
  144. for(int i=0;i<=16;i++)
  145. for (int j = 0; j <= 16; j++) {
  146. if (move[i][j] == move[xy[0]][xy[1]] - look[1]){
  147. //如果符合这个条件,则表示蛇已经移动出这个位置了
  148. //要删除这个位置的蛇尾巴
  149. //一次只有一个方块会符合要求吧?
  150. bk[i][j] = 0;
  151. gotoxy(i * 2, j);
  152. BackGround(0, 0);
  153. printf(" ");
  154. break;//一次只找一个
  155. }
  156. }
  157. end:;
  158. }
  159. int main() {
  160. int bk[20][20], xy[2], move[20][20], look[4];
  161. xy[1] = xy[0] = 8;
  162. srand((unsigned) time(NULL));//初始化随机种子
  163. system("pause");
  164. restart(bk, look, move);
  165. while (look[3] == 0) {
  166. Sleep(200);//休眠400ms一次
  167. map(bk, look, xy, move);
  168. }
  169. system("pause");
  170. printf("游戏结束,谢谢游玩!^_^");
  171. return 0;
  172. }

下面是运行界面:


没有对界面进行美化,小伙伴们可以自行进行美化,如果想要让这个界面处于屏幕中间的话,只要定义一个很大的坐标系,然后去中间的坐标点就行了。。

关于FPS显示的想法:

我认为可以在while循环里面进行Fps显示,首先定义一个帧数计数器count,然后进行计时,每当一秒钟的时候,count在屏幕上刷新一次,然后重置为0,每当运行一次map的时候count++。。

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

闽ICP备14008679号