skkkkkkkks 2024-05-26 11:57 采纳率: 25%
浏览 7

C++贪吃蛇代码直接输出game over

C++编写贪吃蛇代码后直接输出game over并且蛇不动是为什么

img


代码如下:

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <graphics.h>
#include <conio.h>
#include<time.h>
#include <stdlib.h>
#undef UNICODE
#undef _UNICODE
//坐标属性
typedef struct Point
{
    int x;
    int y;
}MYPOINT;

//蛇的属性
struct Snake
{
    MYPOINT xy[100];
    int num;
    char position;
}snake;

//食物的属性
struct Food
{
    MYPOINT foodxy;//食物坐标
    int flag;//标记
    int grade;
}food;

HWND hwnd = NULL;

enum position { up, down, left, right };

//初始化蛇
void Initiatesnake() {
    snake.xy[0].x = 20; // 蛇头
    snake.xy[0].y = 0;
    snake.xy[1].x = 10; // 蛇身第一段
    snake.xy[1].y = 0;

    snake.num = 2;         // 初始长度为2,因为只有头和一个身体部分
    snake.position = right;
}

//初始化食物
//void Initiatefood()
//{
//    srand((unsigned int)time(NULL));
//    food.foodxy.x  = rand() % 80 * 10;
//    food.foodxy.y = rand() % 60 * 10;
//    food.flag = 1;
//    for (int i = 0; i < snake.num; i++)
//    {
//        if (food.foodxy.x == snake.xy[i].x && food.foodxy.y == snake.xy[i].y)
//        {
//            food.foodxy.x = rand() % 80 * 10;
//            food.foodxy.y = rand() % 60 * 10;
//        }
//    }
//}
void Initiatefood() {
    srand((unsigned int)time(NULL));
    do {
        food.foodxy.x = rand() % 80 * 10;
        food.foodxy.y = rand() % 60 * 10;
    } while (food.foodxy.x == snake.xy[0].x && food.foodxy.y == snake.xy[0].y); // 确保食物不与蛇头重叠
    food.flag = 1;
}

//画蛇

void Drawsnake()
{
    for (int i = 0; i < snake.num; i++)
    {
        setlinecolor(BLACK);
        setfillcolor(BLUE);
        fillrectangle(snake.xy[i].x, snake.xy[i].y, snake.xy[i].x + 10, snake.xy[i].y + 10);
    }
}
//画食物

void Drawfood()
{
    setlinecolor(BLACK);
    setfillcolor(RED);
    fillrectangle(food.foodxy.x , food.foodxy.y, food.foodxy.x + 10, food.foodxy.x + 10);
}
//移动蛇
void Movesnake()
{
    //移动
    for (int i = snake.num - 1; i > 0; i--)
    {
        snake.xy[i].x = snake.xy[i - 1].x;
        snake.xy[i].y = snake.xy[i - 1].y;
    }

    //蛇头移动
    switch (snake.position)
    {
    case up:
        snake.xy[0].y -= 10;
        break;
    case down:
        snake.xy[0].y += 10;
        break;
    case left:
        snake.xy[0].x -= 10;
        break;
    case right:
        snake.xy[0].x += 10;
        break;

    default :
        break;
    }
}

//按键控制

void Keydown()
{
    char Key = _getch();
    if (Key == 32)
    {
        while (_getch() != 32);
    }

    switch (Key)
    {
    case 'w':
    case 'W':
        if (snake.position != down)
        {
            snake.position = up;
        }
        break;
    case 's':
    case 'S':
        if (snake.position != up)
        {
            snake.position = down;
        }
        break;
    case 'a':
    case 'A':
        if (snake.position != right)
        {
            snake.position = left;
        }
        break;
    case 'd':
    case 'D':
        if (snake.position != left)
        {
            snake.position = right;
        }
        break;
    }
}

//吃食物
void Eatfood()
{
    if (snake.xy[0].x == food.foodxy.x && snake.xy[0].y == food.foodxy.y)
    {
        food.flag = 0;
        snake.num++;
        food.grade += 10;
    }
}

//显示分数
void Showgrade()
{
    char grade[100] = "";
    sprintf_s(grade, "分数:%d", food.grade);
    setbkmode(TRANSPARENT);
    settextcolor(LIGHTBLUE);
    outtextxy(650, 30, grade);
}

//游戏结束
int SnakeDie()
{
    if (snake.xy[0].x < 0 || snake.xy[0].x >800 || snake.xy[0].y < 0 || snake.xy[0].y > 600)
    {
        printf("Snake died due to hitting the wall.\n");
        MessageBox(hwnd,"撞墙了,游戏结束!", "撞墙警告", 0);
        return 1;
    }

    for (int i = 1; i < snake.num; i++)
    {
        if (snake.xy[0].x == snake.xy[i].x && snake.xy[0].y == snake.xy[i].y)
        {
            printf("Snake died due to self-collision.\n");
            MessageBox(hwnd, "自杀了,游戏结束!", "自杀警告", 0);

        }return 1;
    }
    return 0;
}
int main()
{
    hwnd = initgraph(800, 600);
    setbkcolor(WHITE);
    cleardevice();
    Initiatesnake();
    Initiatefood();
    while (true)
    {
        printf("Game Loop Iteration\n");
        cleardevice();
        Drawsnake();
        Movesnake();
        Drawfood();
        Eatfood();
        Showgrade();
        int temp = SnakeDie();
        if (temp)
        {
            printf("Game Over Detected\n"); // 游戏结束时的输出
            break;
        }
        if (food.flag == 0)
        {
            Initiatefood();
        }
        if (_kbhit())
        {
            Keydown();
        }
        Sleep(80);

    }
    _getch();
    closegraph();
    system("pause");
    return 0;
}

  • 写回答

3条回答 默认 最新

  • 阿里嘎多学长 2024-05-26 12:00
    关注

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    根据您提供的代码和描述,程序直接输出"Game Over"并且蛇不再移动的原因可能有以下几点:

    1. 游戏循环中断:您的代码中使用了while (true)来创建一个无限循环的游戏循环,但是当SnakeDie()函数返回1时,游戏循环会通过break语句中断。这是正确的行为,但需要确保SnakeDie()函数在适当的情况下返回1。

    2. 游戏结束条件:您的代码中已经设置了蛇撞墙或自撞的条件,但是需要确保这些条件能够被正确触发。从代码看,这部分逻辑是正确的。

    3. 初始化问题:您的初始化代码Initiatesnake()Initiatefood()看起来是正确的,但是注释掉的Initiatefood()函数可能会导致食物不初始化。确保使用正确的初始化函数。

    4. 按键控制:按键控制的逻辑在Keydown()函数中实现,从代码看这部分逻辑也是正确的。但是,需要确保玩家的按键能够被正确读取,并且_kbhit()函数能够检测到按键。

    5. 分数显示:分数显示逻辑在Showgrade()函数中实现,但是您的分数显示是基于食物的等级food.grade,而不是蛇的长度。如果这是您想要的逻辑,那么这部分是正确的。如果不是,您可能需要修改分数的计算方式。

    6. 游戏结束提示:您的代码中使用了MessageBox来显示游戏结束的提示,这是正确的。但是,MessageBox函数是在Windows环境中使用的,如果您在非Windows环境编译运行代码,这部分将不会工作。

    7. 其他潜在问题

      • 确保initgraph(800, 600)能够正确初始化图形模式,并且窗口大小是合适的。
      • 检查cleardevice()函数是否正确清除了屏幕,以便在每次循环时正确绘制蛇和食物。
      • 确保Sleep(80)提供了足够的时间间隔,使得游戏运行流畅。

    修复建议

    • 确保Initiatefood()函数没有被注释掉,并且在游戏循环中每次食物被吃掉后都能正确调用。
    • 如果您希望蛇的长度增加分数,需要修改Showgrade()函数,使其显示蛇的长度而不是食物的等级。
    • 检查_kbhit()Keydown()函数是否能够正确处理按键事件。
    • 如果您在非Windows环境编译,考虑替换MessageBox为其他方式来显示游戏结束信息。

    参考资料

    请注意,由于您的代码是使用BGI库编写的,这在现代操作系统中可能不再受支持。您可能需要考虑使用其他图形库,如SDL或SFML,来创建图形界面。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 5月26日