1

So, I'm trying to make a simple snake game in C with raylib, and after adding the ability to eat apples, basically everything breaks. The way I'm doing this, is there is an array of Vector2s that give the position of every square of the snake, which gets rendered to a 20x20 grid. Here's the code, It's kinda spaghetti bc I'm a bad programmer, but I hope somebody can help me out.

#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;
}
FyreWolf
  • 11
  • 1
  • 3
  • To effectively debug C programs that compile without warnings, you'll need to use a debugger like `gdb`. Staring at your code and hoping to spot the issue, or adding a bunch of print statements to "trace", is a poor solution. Guess how I know :P. – erik258 Dec 27 '21 at 18:07

1 Answers1

0

Did the game work before adding the food? for example when starting with length 3 for the snake how it is moving?, because when considering how the snake is changing direction in your code it seems if the snake is moving in certain direction and changes direction then all the parts will change direction:

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

Lets say the snake is of length 5 and is moving vertically (on y-axis) the player presses 'D' then the direction will be towards right (x-axis), so basically only the head must move to the right and the rest must continue to move on y-axis, and then the square next to the head will move to the right will the rest of the body will continue moving on y-axis. But in your code all squares change their direction simultaneously, if you start your game with only one square you will not notice this but after eating and increasing in size you will notice the error.

The second thing you must consider is that when to change direction, for example if the user is moving to the right (after pressing 'D') then if he presses 'A' then the snake must not change direction, it changes only if it is going vertically, same thing goes for y-axis, but your code does not consider these special cases.

And finally, when you add a square to the snake after eating the snake is not getting any longer:

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

Let's say the snake is moving to the right (user presses 'D') so according to your code playerDir.x = 1, now in theory the snake must add square to the right so the code must be playerLoc[score - 1].x + 1, but because you are multiplying by -1 the added square's x will be equal to the previous head's x minus 1. There is no need to multiply by -1.

Also you should consider the possibility of the food being at the border, in this case adding a square by using the direction could cause the snake to go outside of the the limits, in this case you need to add a square only after the user presses a valid direction, you can add code to consider adding squares when the food is at the border (or close to the snake's body) only when the user presses a direction or you can find other solutions like adding squares to the tail, or let the head of the snake move one square while the rest of the body is frozen for one cycle and then add a square between the head the body with the location of the previous location of the head, etc... Adding a square to the head could cause bad experience for the user as the head will change it's location without interference from him.

Bashi
  • 174
  • 6
  • 1
    This found It. I found this before the answer was submitted, but the problem was moving the entire snake as a block, I later changed the `playerDir` to an array of vectors and changed the code to change direction in a sort of "whip motion" – FyreWolf Dec 29 '21 at 04:47