在您的代码中,有几个地方出现了问题:
1.在初始化蛇身体时,您错误地给蛇尾赋值了两次,导致初始化错误。您需要将第二个初始化蛇尾的部分注释掉。
2.在移动蛇身体的循环中,您没有正确更新蛇身体的坐标。应该将`snake->list[i]`更新为`snake->list[i-1]`。
3.在控制蛇移动的函数中,您只获取到当前按下的键,但是并没有判断按下键的有效性。您可以将获取按键的部分放在一个循环中,直到按下了有效的键(wasd)或者游戏结束。
4.在判断蛇是否咬到自己的函数中,您错误地使用了同样的坐标名称,导致判断错误。应该将其中一个更改为其他名称。
根据上述问题的修正,下面是修改后的代码:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <time.h>
#define WIDE 60
#define HIGH 30
typedef struct _boby
{
int x, y;
} BODY;
typedef struct snake
{
BODY list[100]; // 身体,身体每一节坐标都是BODY
int size; //蛇身体的大小
BODY food; // 食物的坐标
COORD coord; // 光标的位置信息
int dx; // 蛇沿x轴移动的方向
int dy; // 蛇沿y轴移动的方向
int score; //分数
} SNAKE;
void show_ui(SNAKE *snake)
{
// 清屏
system("cls");
// 显示蛇
for (int i = 0; i < snake->size; i++)
{
snake->coord.X = snake->list[i].x;
snake->coord.Y = snake->list[i].y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
if (i == 0)
printf("@");
else
printf("*");
}
// 显示食物
snake->coord.X = snake->food.x;
snake->coord.Y = snake->food.y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
printf("#");
}
// 初始化食物
void init_food(SNAKE *snake)
{
srand(time(NULL)); //设置随机数种子
snake->food.x = rand() % WIDE;
snake->food.y = rand() % HIGH;
}
void init_snake(SNAKE *snake)
{
// 初始化蛇头
snake->list[0].x = WIDE / 2;
snake->list[0].y = HIGH / 2;
// 初始化蛇身体的大小
snake->size = 1;
// 初始化食物的坐标
init_food(snake);
//初始化蛇的移动方向
snake->dx = 1;
snake->dy = 0;
// 初始化分数
snake->score = 0;
}
void move_snake(SNAKE *snake)
{
// 更新蛇的身体坐标,除蛇头
for (int i = snake->size - 1; i > 0; i--)
{
snake->list[i] = snake->list[i - 1];
}
// 更新蛇头
snake->list[0].x += snake->dx;
snake->list[0].y += snake->dy;
}
void control_snake(SNAKE *snake)
{
char key = 0;
while (1) // 循环获取按键
{
if (_kbhit()) // 判断是否有键盘输入
{
key = _getch();
if (key == 'a' || key == 'w' || key == 's' || key == 'd')
break; // 按下了有效的键则退出循环
}
}
switch (key)
{
case 'a':
snake->dx = -1;
snake->dy = 0;
break;
case 'w':
snake->dx = 0;
snake->dy = -1;
break;
case 's':
snake->dx = 0;
snake->dy = 1;
break;
case 'd':
snake->dx = 1;
snake->dy = 0;
break;
}
}
void game_end(SNAKE *snake)
{
snake->coord.X = 25;
snake->coord.Y = 25;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
printf("游戏结束,得分为%d\n", snake->score);
Sleep(3000);
exit(0);
}
// 咬到自己
void snake_eat_body(SNAKE *snake)
{
// 如果蛇头和蛇身体任意一节身体坐标相同,则吃到自己的身体
for (int i = 1; i < snake->size; i++)
{
if (snake->list[0].x == snake->list[i].x && snake->list[0].y == snake->list[i].y)
{
game_end(snake);
}
}
}
void snake_eat_food(SNAKE *snake)
{
// 如果蛇头与食物坐标相同,则吃到了食物
if (snake->list[0].x == snake->food.x && snake->list[0].y == snake->food.y)
{
// 原食物消失,生成新的食物(由于先更新的蛇,所以不用让食物消失)
init_food(snake);
// 蛇的身体增长一节
snake->size++;
// 分数增加(if去实现多个条件)
snake->score += 10;
}
}
void start_game(SNAKE *snake)
{
while (snake->list[0].x >= 0 && snake->list[0].x <= WIDE && snake->list[0].y >= 0 && snake->list[0].y <= HIGH)
{
// 控制蛇更新的方向
control_snake(snake);
// 更新蛇的坐标
move_snake(snake);
// 清屏
system("cls");
// 蛇移动
show_ui(snake);
// 蛇是否碰到自己
snake_eat_body(snake);
// 蛇是否碰到食物
snake_eat_food(snake);
Sleep(500); //延时0.5s
}
game_end(snake);
}
int main()
{
SNAKE *snake = (SNAKE *)malloc(sizeof(SNAKE));
init_snake(snake); //初始化蛇和食物
show_ui(snake); //显示界面
start_game(snake); // 开始游戏
system("pause");
return 0;
}
希望这次的修改能够帮助您解决问题!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 |