鱼C论坛

 找回密码
 立即注册
查看: 233|回复: 1

为什么运行之后蛇会动不了,直接结束程序了,不知道哪里出了bug,求修改

[复制链接]
发表于 2024-2-17 21:35:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <windows.h>
  5. #include <time.h>
  6. #include <conio.h>
  7. #define WIDE 60
  8. #define HIGH 30
  9. // 1 设置地图范围(边界)宽 高
  10. // 2 初始化蛇
  11. // 3 将蛇和食物显示在屏幕上
  12. // 4 蛇的移动(wasdk控制)
  13. /*
  14.    蛇碰到墙
  15.    蛇碰到蛇的身体
  16.    蛇碰到障碍物
  17.    蛇碰到食物(蛇身体增长一节,原食物消失,增加新的食物,获得分数)
  18. */
  19. typedef struct _boby
  20. {
  21.     int x,y;
  22. }BODY;
  23. typedef struct snake
  24. {
  25.     BODY list [WIDE*HIGH]; // 身体,身体每一节坐标都是BODY
  26.     int size; //蛇身体的大小
  27.     BODY food; // 食物的坐标
  28.     COORD coord;  // 光标的位置信息
  29.     int dx;    // 蛇沿x轴移动的方向
  30.     int dy;    // 蛇沿y轴移动的方向
  31.     int score; //分数
  32. }SNAKE;


  33. void init_ui()
  34. {
  35.     for(int i=0;i<HIGH;i++)
  36.     {
  37.         for(int j=0;j<WIDE;j++)
  38.         {
  39.             printf("#");
  40.         }
  41.         printf("\n");
  42.     }
  43. }
  44. void show_ui(SNAKE *snake)
  45. {
  46.     // 显示蛇 注意:每次显示蛇或食物,都要显示蛇的位置
  47.     for(int i=0;i<snake->size;i++)
  48.     {
  49.         snake->coord.X=snake->list[i].x;
  50.         snake->coord.Y=snake->list[i].y;
  51.         SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),snake->coord);
  52.         if(i==0) printf("@");
  53.         else printf("*");
  54.     }
  55.     // 显示食物
  56.     snake->coord.X=snake->food.x;
  57.     snake->coord.Y=snake->food.y;
  58.     SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),snake->coord);
  59.     printf("#");

  60. }
  61. // 初始化食物
  62. void init_food(SNAKE *snake)
  63. {
  64.     srand(time(NULL)); //设置随机数种子
  65.     snake->food.x=rand()%WIDE;
  66.     snake->food.y=rand()%HIGH;

  67. }
  68. void init_snake(SNAKE *snake)
  69. {
  70.     // 初始化蛇头
  71.     snake->list[0].x=WIDE/2;
  72.     snake->list[0].y=HIGH/2;
  73.     // 初始化蛇尾
  74.     snake->list[0].x=WIDE/2-1;
  75.     snake->list[0].y=HIGH/2;
  76.     // 初始化蛇身体的大小
  77.     snake->size=2;
  78.     // 初始化食物的坐标
  79.     init_food(snake);
  80.     //初始化蛇的移动方向
  81.     snake->dx=1;
  82.     snake->dy=0;
  83.     // 初始化分数
  84.     snake->score=0;

  85. }
  86. void move_snake(SNAKE *snake)
  87. {
  88.     // 更新蛇的身体坐标,除蛇头
  89.     for(int i=snake->size-1;i>0;i--)
  90.     {
  91.         snake->list[i]=snake->list[i-1];
  92.     }
  93.     // 更新蛇头
  94.     snake->list[0].x+=snake->dx;
  95.     snake->list[0].y+=snake->dy;
  96. }

  97. void control_snake(SNAKE *snake)
  98. {
  99.     char key=0;
  100.     while(_kbhit())  //判断按键是否按下,按下则不等于0w
  101.     {
  102.         key=_getch();
  103.     }
  104.     switch (key)
  105.     {
  106.         case 'a':snake->dx=-1;snake->dy=0;break;
  107.         case 'w':snake->dx=0;snake->dy=-1;break;
  108.         case 's':snake->dx=0;snake->dy=1;break;
  109.         case 'd':snake->dx=1;snake->dy=0;break;
  110.     }

  111. }
  112. void game_end(SNAKE *snake)
  113. {
  114.     snake->coord.X=25;
  115.     snake->coord.Y=25;
  116.     SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),snake->coord);
  117.     printf("游戏结束,得分为%d\n",snake->score);
  118.     Sleep(3000);
  119.     exit(0);

  120. }
  121. // 咬到自己
  122. void snake_eat_body(SNAKE *snake)
  123. {
  124.     // 如果蛇头和蛇身体任意一节身体坐标相同,则吃到自己的身体
  125.     for(int i=0;i<snake->size;i++)
  126.     {
  127.         if(snake->list[0].x==snake->list[i].x&&snake->list[0].y==snake->list[i].y)
  128.         {
  129.             game_end(snake);
  130.         }
  131.     }
  132. }
  133. void snake_eat_food(SNAKE *snake)
  134. {
  135.     // 如果蛇头与食物坐标相同,则吃到了食物
  136.     if(snake->list[0].x==snake->food.x&&snake->list[0].y==snake->food.y)
  137.     {
  138.         // 原食物消失,生成新的食物(由于先更新的蛇,所以不用让食物消失)
  139.         init_food(snake);
  140.         // 蛇的身体增长一节
  141.         snake->size++;
  142.         // 分数增加(if去实现多个条件)
  143.         snake->score+=10;

  144.     }
  145. }
  146. void start_game(SNAKE *snake)
  147. {
  148.     while(snake->list[0].x<60&&snake->list[0].x>=0&&snake->list[0].y<30&&snake->list[0].y>=0)
  149.     {
  150.         // 控制蛇更新的方向
  151.         control_snake(snake);
  152.         // 更新蛇的坐标
  153.         move_snake(snake);
  154.         // 清屏
  155.         system("cls");
  156.         // 蛇移动
  157.         show_ui(snake);
  158.         // 蛇是否碰到墙
  159.         // 蛇是否碰到自己
  160.         snake_eat_body(snake);
  161.         // 蛇是否碰到食物
  162.         snake_eat_food(snake);
  163.         Sleep(500); //延时0.5s
  164.     }
  165.     game_end(snake);
  166. }
  167. int main()
  168. {
  169.     // init_ui();
  170.     SNAKE *snake =(SNAKE *)malloc(sizeof(SNAKE));
  171.     init_snake(snake); //初始化蛇和食物
  172.     show_ui(snake); //显示界面
  173.     start_game(snake);  // 开始游戏
  174.     system("pause");
  175.     return 0;
  176. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-2-17 21:35:39 | 显示全部楼层
在您的代码中,有几个地方出现了问题:

1.在初始化蛇身体时,您错误地给蛇尾赋值了两次,导致初始化错误。您需要将第二个初始化蛇尾的部分注释掉。

2.在移动蛇身体的循环中,您没有正确更新蛇身体的坐标。应该将`snake->list`更新为`snake->list[i-1]`。

3.在控制蛇移动的函数中,您只获取到当前按下的键,但是并没有判断按下键的有效性。您可以将获取按键的部分放在一个循环中,直到按下了有效的键(wasd)或者游戏结束。

4.在判断蛇是否咬到自己的函数中,您错误地使用了同样的坐标名称,导致判断错误。应该将其中一个更改为其他名称。

根据上述问题的修正,下面是修改后的代码:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <conio.h>
  4. #include <windows.h>
  5. #include <time.h>

  6. #define WIDE 60
  7. #define HIGH 30

  8. typedef struct _boby
  9. {
  10.     int x, y;
  11. } BODY;

  12. typedef struct snake
  13. {
  14.     BODY list[100]; // 身体,身体每一节坐标都是BODY
  15.     int size;       //蛇身体的大小
  16.     BODY food;      // 食物的坐标
  17.     COORD coord;    // 光标的位置信息
  18.     int dx;         // 蛇沿x轴移动的方向
  19.     int dy;         // 蛇沿y轴移动的方向
  20.     int score;      //分数
  21. } SNAKE;

  22. void show_ui(SNAKE *snake)
  23. {
  24.     // 清屏
  25.     system("cls");

  26.     // 显示蛇
  27.     for (int i = 0; i < snake->size; i++)
  28.     {
  29.         snake->coord.X = snake->list[i].x;
  30.         snake->coord.Y = snake->list[i].y;
  31.         SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
  32.         if (i == 0)
  33.             printf("@");
  34.         else
  35.             printf("*");
  36.     }

  37.     // 显示食物
  38.     snake->coord.X = snake->food.x;
  39.     snake->coord.Y = snake->food.y;
  40.     SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
  41.     printf("#");
  42. }

  43. // 初始化食物
  44. void init_food(SNAKE *snake)
  45. {
  46.     srand(time(NULL));                    //设置随机数种子
  47.     snake->food.x = rand() % WIDE;
  48.     snake->food.y = rand() % HIGH;
  49. }

  50. void init_snake(SNAKE *snake)
  51. {
  52.     // 初始化蛇头
  53.     snake->list[0].x = WIDE / 2;
  54.     snake->list[0].y = HIGH / 2;

  55.     // 初始化蛇身体的大小
  56.     snake->size = 1;

  57.     // 初始化食物的坐标
  58.     init_food(snake);

  59.     //初始化蛇的移动方向
  60.     snake->dx = 1;
  61.     snake->dy = 0;

  62.     // 初始化分数
  63.     snake->score = 0;
  64. }

  65. void move_snake(SNAKE *snake)
  66. {
  67.     // 更新蛇的身体坐标,除蛇头
  68.     for (int i = snake->size - 1; i > 0; i--)
  69.     {
  70.         snake->list[i] = snake->list[i - 1];
  71.     }

  72.     // 更新蛇头
  73.     snake->list[0].x += snake->dx;
  74.     snake->list[0].y += snake->dy;
  75. }

  76. void control_snake(SNAKE *snake)
  77. {
  78.     char key = 0;
  79.     while (1) // 循环获取按键
  80.     {
  81.         if (_kbhit()) // 判断是否有键盘输入
  82.         {
  83.             key = _getch();
  84.             if (key == 'a' || key == 'w' || key == 's' || key == 'd')
  85.                 break; // 按下了有效的键则退出循环
  86.         }
  87.     }
  88.     switch (key)
  89.     {
  90.     case 'a':
  91.         snake->dx = -1;
  92.         snake->dy = 0;
  93.         break;
  94.     case 'w':
  95.         snake->dx = 0;
  96.         snake->dy = -1;
  97.         break;
  98.     case 's':
  99.         snake->dx = 0;
  100.         snake->dy = 1;
  101.         break;
  102.     case 'd':
  103.         snake->dx = 1;
  104.         snake->dy = 0;
  105.         break;
  106.     }
  107. }

  108. void game_end(SNAKE *snake)
  109. {
  110.     snake->coord.X = 25;
  111.     snake->coord.Y = 25;
  112.     SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
  113.     printf("游戏结束,得分为%d\n", snake->score);
  114.     Sleep(3000);
  115.     exit(0);
  116. }

  117. // 咬到自己
  118. void snake_eat_body(SNAKE *snake)
  119. {
  120.     // 如果蛇头和蛇身体任意一节身体坐标相同,则吃到自己的身体
  121.     for (int i = 1; i < snake->size; i++)
  122.     {
  123.         if (snake->list[0].x == snake->list[i].x && snake->list[0].y == snake->list[i].y)
  124.         {
  125.             game_end(snake);
  126.         }
  127.     }
  128. }

  129. void snake_eat_food(SNAKE *snake)
  130. {
  131.     // 如果蛇头与食物坐标相同,则吃到了食物
  132.     if (snake->list[0].x == snake->food.x && snake->list[0].y == snake->food.y)
  133.     {
  134.         // 原食物消失,生成新的食物(由于先更新的蛇,所以不用让食物消失)
  135.         init_food(snake);
  136.         // 蛇的身体增长一节
  137.         snake->size++;
  138.         // 分数增加(if去实现多个条件)
  139.         snake->score += 10;
  140.     }
  141. }

  142. void start_game(SNAKE *snake)
  143. {
  144.     while (snake->list[0].x >= 0 && snake->list[0].x <= WIDE && snake->list[0].y >= 0 && snake->list[0].y <= HIGH)
  145.     {
  146.         // 控制蛇更新的方向
  147.         control_snake(snake);
  148.         // 更新蛇的坐标
  149.         move_snake(snake);
  150.         // 清屏
  151.         system("cls");
  152.         // 蛇移动
  153.         show_ui(snake);
  154.         // 蛇是否碰到自己
  155.         snake_eat_body(snake);
  156.         // 蛇是否碰到食物
  157.         snake_eat_food(snake);
  158.         Sleep(500); //延时0.5s
  159.     }
  160.     game_end(snake);
  161. }

  162. int main()
  163. {
  164.     SNAKE *snake = (SNAKE *)malloc(sizeof(SNAKE));
  165.     init_snake(snake); //初始化蛇和食物
  166.     show_ui(snake);    //显示界面
  167.     start_game(snake); // 开始游戏
  168.     system("pause");
  169.     return 0;
  170. }
复制代码


希望这次的修改能够帮助您解决问题!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-11 03:37

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表