Raylib c++ 在一定时间后停止工作

问题描述 投票:0回答:1

我使用 raylib 库用 C++ 编写了一个蛇程序。我的游戏在一定时间(几分钟)后完全冻结。

这是我的程序的完整代码:

#include <iostream>
#include "raylib.h"
#include "raymath.h"
#include <deque>

using namespace std;
  
// Constant Values
const int cell_size = 40; // Cell size has to be equal to assets dimension in pixels
const int cell_count_x = 20, cell_count_y = 15;
const int game_width = cell_size * cell_count_x;
const int game_height = cell_size * cell_count_y;
const int FPS = 60;
const int offset = cell_size * 2;
const int font_size = 40;

// Classes
class Food {
public:
    Vector2 position;
    Texture texture;

    Food(deque<Vector2> snake_body) {
        Image image = LoadImage("Graphics/apple.png");
        texture = LoadTextureFromImage(image);
        UnloadImage(image);
        position = GetRandomPos(snake_body);
    }

    ~Food() {
        UnloadTexture(texture);
    }

    void Draw() {
        DrawTexture(texture, offset + position.x * cell_size, offset + position.y * cell_size, WHITE);
    }

    Vector2 GetRandomPos(deque<Vector2> snake_body) {
        float x = GetRandomValue(0, cell_count_x - 1);
        float y = GetRandomValue(0, cell_count_y - 1);

        Vector2 position = { x, y };
        while (CheckPos(snake_body, position) == false) {
            float x = GetRandomValue(0, cell_count_x - 1);
            float y = GetRandomValue(0, cell_count_y - 1);
            Vector2 position = { x, y };
        }
        
        return position;
    }

    bool CheckPos(deque<Vector2> snake_body, Vector2 position) {
        for (int i = 0; i < snake_body.size(); i++)
            if (Vector2Equals(snake_body[i], position)) 
                return false;

        return true;
    }
};
 
class Snake {
public:
    deque<Vector2> body = { Vector2{cell_count_x / 3, cell_count_y / 3}, Vector2{cell_count_x / 3 - 1, cell_count_y / 3} , Vector2{cell_count_x / 3 - 1, cell_count_y / 3} };
    Vector2 direction = { 1, 0 };
    bool fruit_collision = false;

    void Draw() {
        for (int i = 0; i < body.size(); i++) {
            float x = body[i].x;
            float y = body[i].y;
            Rectangle body_part = Rectangle{ offset + x * cell_size, offset + y * cell_size, (float)cell_size, (float)cell_size };
            DrawRectangleRounded(body_part, 0.5, 10, DARKGREEN);
        }
    }

    void UpdateMovement() {
        if (fruit_collision)
            fruit_collision = false;
        else
            body.pop_back();

        body.push_front(Vector2Add(body[0], direction));
    }

    void UpdateDirection() {
        if (IsKeyPressed(KEY_UP) && direction.y != 1)
            direction = { 0, -1 };
        if (IsKeyPressed(KEY_DOWN) && direction.y != -1)
            direction = { 0, 1 };
        if (IsKeyPressed(KEY_LEFT) && direction.x != 1)
            direction = { -1, 0 };
        if (IsKeyPressed(KEY_RIGHT) && direction.x != -1)
            direction = { 1, 0 };
    }

    void Reset() {
        body = { Vector2{cell_count_x / 3, cell_count_y / 3}, Vector2{cell_count_x / 3 - 1, cell_count_y / 3} , Vector2{cell_count_x / 3 - 1, cell_count_y / 3} };
        direction = { 1, 0 };
    }
};

class Game {
public:
    Snake snake = Snake();
    Food food = Food(snake.body);

    double last_update_time = 0;
    int score = 0, max_score = 0;

    Sound food_sound, death_sound;

    Game() {
        InitAudioDevice();
        food_sound = LoadSound("Sounds/food_sound.mp3");
        death_sound = LoadSound("Sounds/death_sound.mp3");
    }

    ~Game() {
        UnloadSound(food_sound);
        UnloadSound(death_sound);
        CloseAudioDevice();
    }

    void Draw() {
        food.Draw();
        snake.Draw();
    }

    void DisplayText() {
        DrawText("Snake Game", offset, offset / 2, font_size, DARKGREEN);

        DrawText("Score: ", offset, offset + game_height + 5, font_size, DARKGREEN);
        DrawText(TextFormat("%i", score), offset + 150, offset + game_height + 5, font_size, DARKGREEN);

        DrawText("Max Score: ", offset + game_width - 260, offset + game_height + 5, font_size, DARKGREEN);
        DrawText(TextFormat("%i", max_score), offset + game_width - 15, offset + game_height + 5, font_size, DARKGREEN);
    }

    void Update() {
        snake.UpdateDirection();
        if (EventTriggered(0.2))
            snake.UpdateMovement();

        CheckCollisionWithFood();
        CheckCollisionWithEdge();
        CheckCollisionWithBody();
    }

    void CheckCollisionWithFood() {
        if (Vector2Equals(snake.body[0], food.position)) {
            food.position = food.GetRandomPos(snake.body);
            
            snake.fruit_collision = true;

            score++;

            PlaySound(food_sound);
        }
    }

    void CheckCollisionWithEdge() {
        if (snake.body[0].x >= cell_count_x || snake.body[0].x == -1 || snake.body[0].y >= cell_count_y || snake.body[0].y == -1)
            GameOver();
    }

    void CheckCollisionWithBody() {
        for (int i = 2; i < snake.body.size(); i++)
            if (Vector2Equals(snake.body[0], snake.body[i]))
                GameOver();
    }

    void GameOver() {
        snake.Reset();
        food.position = food.GetRandomPos(snake.body);

        if (score > max_score)
            max_score = score;
        score = 0;

        PlaySound(death_sound);
    }

    bool EventTriggered(double interval) {
        double current_time = GetTime();

        if (current_time - last_update_time >= interval) {
            last_update_time = current_time;
            return true;
        }

        return false;
    }
};

int main()
{
    InitWindow(game_width + offset * 2, game_height + offset * 2, "Snake");
    SetTargetFPS(FPS);

    // Game Class
    Game game = Game();

    // Main Loop
    while (WindowShouldClose() == false) {
        BeginDrawing();

        // Update
        game.Update();

        // Draw
        ClearBackground(GREEN);
        DrawRectangleLinesEx(Rectangle{ offset - 5, offset - 5, cell_size * cell_count_x + 10, cell_size * cell_count_y + 10 }, 5, DARKGREEN);
        game.Draw();
        game.DisplayText();

        EndDrawing();
    }

    CloseWindow();

    return 0;
}
c++ freeze raylib
1个回答
0
投票

问题出在

GetRandomPos
中,您声明了一个新的
position
,它遮盖了您打算重新分配的
position

Vector2 position = { x, y };
while (CheckPos(snake_body, position) == false) {  // position 1
    float x = GetRandomValue(0, cell_count_x - 1);
    float y = GetRandomValue(0, cell_count_y - 1);
    Vector2 position = { x, y };                   // position 2
}

每当选择蛇体顶部的随机位置时,这都会使游戏陷入无限循环。

只需重新分配即可:

    Vector2 position = { x, y };
© www.soinside.com 2019 - 2024. All rights reserved.