鱼C论坛

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

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

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

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

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

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


void init_ui()
{
    for(int i=0;i<HIGH;i++)
    {
        for(int j=0;j<WIDE;j++)
        {
            printf("#");
        }
        printf("\n");
    }
}
void show_ui(SNAKE *snake)
{
    // 显示蛇 注意:每次显示蛇或食物,都要显示蛇的位置
    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->list[0].x=WIDE/2-1;
    snake->list[0].y=HIGH/2;
    // 初始化蛇身体的大小
    snake->size=2;
    // 初始化食物的坐标
    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(_kbhit())  //判断按键是否按下,按下则不等于0w
    {
        key=_getch();
    }
    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=0;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<60&&snake->list[0].x>=0&&snake->list[0].y<30&&snake->list[0].y>=0)
    {
        // 控制蛇更新的方向
        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()
{
    // init_ui();
    SNAKE *snake =(SNAKE *)malloc(sizeof(SNAKE));
    init_snake(snake); //初始化蛇和食物
    show_ui(snake); //显示界面
    start_game(snake);  // 开始游戏
    system("pause");
    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

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 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-7-6 03:43

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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