0

所以,我正在尝试用 raylib 用 C 语言制作一个简单的蛇游戏,在添加了吃苹果的能力之后,基本上一切都崩溃了。我这样做的方式是,有一个 Vector2 数组,它给出了蛇的每个正方形的位置,它被渲染为 20x20 网格。这是代码,这有点像意大利面条,因为我是一个糟糕的程序员,但我希望有人能帮助我。

#include <stdlib.h>
#include <time.h>
#include <raylib.h>

#define WIDTH 1080
#define HEIGHT 1080
#define FPS 4
#define GRIDSIZE 20

int main()
{
    // Random Numbers
    srand(time(NULL));

    // Define locations
    Vector2 playerLoc[10] = {(Vector2) {rand() % GRIDSIZE, rand() % GRIDSIZE}};
    Vector2 appleLoc = (Vector2) {rand() % GRIDSIZE, rand() % GRIDSIZE};

    // Player Score
    int score = 0;
    // Define Direction
    Vector2 playerDir = (Vector2) {1, 0};

    // With of Grid Squares
    int gridSize = HEIGHT / GRIDSIZE;

    // Initialization
    InitWindow(WIDTH, HEIGHT, "Snake Game Test");

    SetTargetFPS(FPS);

    while (!WindowShouldClose())
    {
        // Update Variables Here
        if (IsKeyPressed('D') || IsKeyPressed('A'))
        {
            playerDir.x = (int) IsKeyPressed('D') - (int) IsKeyPressed('A');
            playerDir.y = 0.0f;
        }
        else if (IsKeyPressed('S') || IsKeyPressed('W'))
        {
            playerDir.y = (int) IsKeyPressed('S') - (int) IsKeyPressed('W');
            playerDir.x = 0;
        }
        for (int i = 0; i <= score; i++)
        {
            playerLoc[i].x += playerDir.x;
            playerLoc[i].y += playerDir.y;
        }
        if (playerLoc[0].x < 0)
            break;
        else if (playerLoc[0].x >= 1080)
            break;
        else if (playerLoc[0].y < 0)
            break;
        else if (playerLoc[0].y >= 1080)
            break;

        if (playerLoc[0].x == appleLoc.x && playerLoc[0].y == appleLoc.y)
        {
            appleLoc = (Vector2) {rand() % GRIDSIZE, rand() % GRIDSIZE};
            score++;
            playerLoc[score].x = playerLoc[score - 1].x + (playerDir.x * -1);
            playerLoc[score].y = playerLoc[score - 1].y + (playerDir.y * -1);
        }

        // Draw
        BeginDrawing();

            ClearBackground(RAYWHITE);

            for (int i = 0; i < GRIDSIZE; i++)
            {
                for (int j = 0; j < GRIDSIZE; j++)
                {
                    for (int k = 0; k <= score; k++)
                    {
                        if (i == playerLoc[k].x && j == playerLoc[k].y)
                            DrawRectangle(i * gridSize, j * gridSize, gridSize, gridSize, BLACK);
                    }
                    if (i == appleLoc.x && j == appleLoc.y)
                    {
                        DrawRectangle(i * gridSize, j * gridSize, gridSize, gridSize, RED);
                    }
                }
            }

        EndDrawing();
        // Update Late Variables Here
    }

    // De-Initialization
    CloseWindow();

    return 0;
}
4

1 回答 1

0

游戏在添加食物之前有效吗?例如,当蛇的长度为 3 开始时,它是如何移动的?,因为在考虑蛇如何在代码中改变方向时,如果蛇在某个方向移动并改变方向,那么所有部分都会改变方向:

    for (int i = 0; i <= score; i++)
        {
            playerLoc[i].x += playerDir.x;
            playerLoc[i].y += playerDir.y;
        }

假设蛇的长度为 5 并且垂直移动(在 y 轴上)玩家按下“D”然后方向将向右(x 轴),所以基本上只有头部必须向右移动,其余的必须继续在y轴上移动,然后头部旁边的方块将向右移动,身体的其余部分将继续在y轴上移动。但是在你的代码中,所有的方块都会同时改变它们的方向,如果你只用一个方块开始你的游戏,你不会注意到这一点,但是在吃完并增加大小之后你会注意到错误。

您必须考虑的第二件事是何时改变方向,例如,如果用户向右移动(在按下“D”之后),那么如果他按下“A”,那么蛇一定不能改变方向,只有当它改变垂直方向,y 轴也是如此,但您的代码没有考虑这些特殊情况。

最后,当你在吃完蛇后给蛇添加一个正方形时,它不再变大:

   playerLoc[score].x = playerLoc[score - 1].x + (playerDir.x * -1);
   playerLoc[score].y = playerLoc[score - 1].y + (playerDir.y * -1);

假设蛇向右移动(用户按下“D”),因此根据您的代码 playerDir.x = 1,现在理论上蛇必须向右添加正方形,因此代码必须是 playerLoc[score - 1]。 x + 1,但是因为您要乘以 -1,所以添加的正方形的 x 将等于前一个头的 x 减 1。不需要乘以 -1。

另外你应该考虑食物在边界的可能性,在这种情况下使用方向添加一个正方形可能会导致蛇超出限制,在这种情况下你需要在用户按下后添加一个正方形一个有效的方向,您可以添加代码以考虑在食物在边界(或靠近蛇的身体)时仅在用户按下方向时添加正方形,或者您可以找到其他解决方案,例如在尾部添加正方形,或者让蛇的头部移动一个正方形,而身体的其余部分被冻结一个周期,然后在头部和身体之间添加一个正方形与头部的前一个位置,等等......在头部添加一个正方形可以给用户带来不好的体验,因为头部会在不受他干扰的情况下改变它的位置。

于 2021-12-27T22:44:32.243 回答