diff options
| author | fschildt <florian.schildt@protonmail.com> | 2025-10-06 09:25:04 +0200 | 
|---|---|---|
| committer | fschildt <florian.schildt@protonmail.com> | 2025-10-06 09:25:04 +0200 | 
| commit | 606d028dac5118329e7561af33b15988db84465f (patch) | |
| tree | 8a5b92b51a88714fee71d7f908283426f70b7dc1 /src/games/snake | |
| parent | 7d9500d27fc91356c580e365351ff6e1bc1c95e1 (diff) | |
make everything prettier
Diffstat (limited to 'src/games/snake')
| -rw-r--r-- | src/games/snake/Snake.cpp | 269 | ||||
| -rw-r--r-- | src/games/snake/Snake.hpp | 50 | 
2 files changed, 163 insertions, 156 deletions
diff --git a/src/games/snake/Snake.cpp b/src/games/snake/Snake.cpp index 4c6ca18..7969616 100644 --- a/src/games/snake/Snake.cpp +++ b/src/games/snake/Snake.cpp @@ -1,196 +1,218 @@ -#include "renderer/Renderer.hpp" +#include "common/defs.hpp" +#include <chrono>  #include <games/snake/Snake.hpp> +#include <renderer/Renderer.hpp>  #include <imgui.h> +std::mt19937 Snake::s_rng{std::random_device{}()}; + +  Snake::Snake()  { -    m_IsPaused = false; -    m_IsRunning = true; - -    m_DtInSecondsRemaining = 0.0f; -    m_LastMillisecondsSinceT0 = SDL_GetTicks(); +    static_assert(max_map_width <= sizeof(m_body_bitmap[0])*8); +    static_assert(max_map_height <= sizeof(m_body_bitmap[0])*8); +} -    m_TilesPerSecond = 4.0f; -    m_Direction = right; -    m_LastAdvancedDirection = right; +void +Snake::Start(int32_t map_width, int32_t map_height) +{ +    m_dt_remaining_seconds = 0.0f; +    m_tlast_milliseconds = SDL_GetTicks(); -    m_MapWidth = 16; -    m_MapHeight = 16; -    assert(MAX_MAP_WIDTH <= 64); // m_BodyBitmap is uint64_t[]. We can't exceed that! -    assert(MAX_MAP_HEIGHT <= 64); -    assert(m_MapWidth <= MAX_MAP_WIDTH); -    assert(m_MapHeight <= MAX_MAP_WIDTH); +    m_direction = right; +    m_last_advanced_direction = right; -    m_Tail = 0; -    m_Head = 1; -    memset(m_BodyBitmap, 0, sizeof(m_BodyBitmap)); +    assert(map_width <= max_map_width); +    assert(map_height <= max_map_height); +    m_map_width = map_width; +    m_map_height = map_height; -    int32_t head_x = m_MapWidth / 2; -    int32_t head_y = m_MapHeight / 2; -    m_BodyPositions[0] = {head_x -1, head_y}; -    m_BodyPositions[1] = {head_x, head_y}; +    m_tail = 0; +    m_head = 1; -    m_Rng = std::mt19937((std::random_device()())); -    m_Dist = std::uniform_int_distribution<int32_t>(0, m_MapWidth * m_MapHeight - 3); +    int32_t head_x = m_map_width / 2; +    int32_t head_y = m_map_height / 2; +    m_body_positions[0] = {head_x -1, head_y}; +    m_body_positions[1] = {head_x, head_y}; +    memset(m_body_bitmap, 0, sizeof(m_body_bitmap)); +    m_dist = std::uniform_int_distribution<int32_t>(0, m_map_width*m_map_height - 3);      SpawnFood(); -} - -bool Snake::Update(std::vector<SDL_Event> &events) { -    uint64_t milliseconds_since_t0 = SDL_GetTicks(); -    uint64_t milliseconds_since_t0_last = m_LastMillisecondsSinceT0; -    uint64_t dt_in_milliseconds = milliseconds_since_t0 - milliseconds_since_t0_last; -    float dt_in_seconds = (float)dt_in_milliseconds / 1000.0f; -    m_LastMillisecondsSinceT0 = milliseconds_since_t0; +    m_game_status = game_resuming; +} +bool +Snake::Update(std::vector<SDL_Event> &events) +{      Color clear_color = {0.3f, 0.3f, 0.3f, 1.0f};      g_renderer.SetCameraSize(4.0f, 3.0f);      g_renderer.Clear(clear_color); +    if (m_game_status == game_starting) { +        int32_t map_width = 16; +        int32_t map_height = 16; +        Start(map_width, map_height); +    } + +      for (SDL_Event &event : events) { -        if (!m_IsRunning) { -            printf("event loop is running just false\n"); -            return false; +        if (m_game_status == game_resuming) { +            ProcessEventDuringResume(event);          } -        if (m_IsPaused) { +        else if (m_game_status == game_paused) {              ProcessEventDuringPause(event);          } -        else { -            ProcessEventDuringResume(event); -        }      } -    if (!m_IsPaused) { -        MaybeMoveSnake(dt_in_seconds); + +    float dt = ProcessDt(); + +    switch (m_game_status) { +    case game_starting: { +    } break; +    case game_resuming: { +        MaybeMoveSnake(dt); +    } break; +    case game_over: { +        DrawGameOverMenu(); +    } break; +    case game_paused: { +        DrawGamePausedMenu(); +    } break; +    case game_exit: { +        return false; +    } break;      }      Draw(); -    DoImgui(); - -    return m_IsRunning; +    return true;  } -void Snake::MaybeMoveSnake(float dt_in_seconds) { -    float dt_in_seconds_to_use = m_DtInSecondsRemaining + dt_in_seconds; -    float tiles_per_second = m_TilesPerSecond; +void +Snake::MaybeMoveSnake(float dt) +{      float seconds_per_tile = 1.0f / tiles_per_second; -    while (dt_in_seconds_to_use > seconds_per_tile) { -        V2I32 head_pos = m_BodyPositions[m_Head]; -        V2I32 tail_pos = m_BodyPositions[m_Tail]; +    while (dt > seconds_per_tile) { +        V2I32 head_pos = m_body_positions[m_head]; +        V2I32 tail_pos = m_body_positions[m_tail];          // find head_pos -        if (m_Direction == up) { +        if (m_direction == up) {              head_pos.y += 1;          } -        else if (m_Direction == down) { +        else if (m_direction == down) {              head_pos.y -= 1;          } -        else if (m_Direction == right) { +        else if (m_direction == right) {              head_pos.x += 1;          } -        else if (m_Direction == left) { +        else if (m_direction == left) {              head_pos.x -= 1;          } -        if ((head_pos.x < 0 || head_pos.x >= m_MapWidth) || -            (head_pos.y < 0 || head_pos.y >= m_MapHeight)) +        if ((head_pos.x < 0 || head_pos.x >= m_map_width) || +            (head_pos.y < 0 || head_pos.y >= m_map_height))          { -            m_IsRunning = false; +            m_game_status = game_over;              return;          }          uint64_t head_bit = 1 << head_pos.x; -        uint64_t body_bits = m_BodyBitmap[head_pos.y]; +        uint64_t body_bits = m_body_bitmap[head_pos.y];          if (head_pos.y == tail_pos.y) {              body_bits &= ~(1 << tail_pos.x);          }          if (head_bit & body_bits) { -            m_IsRunning = false; +            m_game_status = game_over;              return;          }          // advance head -        int32_t max_positions = sizeof(m_BodyPositions) / sizeof(m_BodyPositions[0]); -        m_Head += 1; -        if (m_Head >= max_positions) { -            m_Head = 0; +        int32_t max_positions = ARRAY_COUNT(m_body_positions); +        m_head += 1; +        if (m_head >= max_positions) { +            m_head = 0;          } -        m_BodyPositions[m_Head] = head_pos; -        m_BodyBitmap[head_pos.y] |= (1 << head_pos.x); +        m_body_positions[m_head] = head_pos; +        m_body_bitmap[head_pos.y] |= (1 << head_pos.x); -        if (m_BodyPositions[m_Head] == m_FoodPosition) { +        if (m_body_positions[m_head] == m_food_position) {              SpawnFood();          }          else {              // advance tail -            V2I32 next_tail_pos = m_BodyPositions[m_Tail]; -            m_BodyBitmap[next_tail_pos.y] &= ~(1 << next_tail_pos.x); +            V2I32 next_tail_pos = m_body_positions[m_tail]; +            m_body_bitmap[next_tail_pos.y] &= ~(1 << next_tail_pos.x); -            m_Tail += 1; -            if (m_Tail >= max_positions) { -                m_Tail = 0; +            m_tail += 1; +            if (m_tail >= max_positions) { +                m_tail = 0;              }          } -        m_LastAdvancedDirection = m_Direction; -        dt_in_seconds_to_use -= seconds_per_tile; +        m_last_advanced_direction = m_direction; +        dt -= seconds_per_tile;      } -    m_DtInSecondsRemaining = dt_in_seconds_to_use; +    m_dt_remaining_seconds = dt;  } -void Snake::ProcessEventDuringPause(SDL_Event &event) { +void +Snake::ProcessEventDuringPause(SDL_Event &event) +{      switch (event.type) {      case SDL_EVENT_KEY_DOWN: {          if (event.key.key == SDLK_ESCAPE) { -            m_IsPaused = false; +            m_game_status = game_resuming;          }      }      default:;      }  } -void Snake::ProcessEventDuringResume(SDL_Event &event) { +void +Snake::ProcessEventDuringResume(SDL_Event &event) +{      switch (event.type) {      case SDL_EVENT_KEY_DOWN: {          if (event.key.key == SDLK_UP) { -            if (m_LastAdvancedDirection == right || -                m_LastAdvancedDirection == left) +            if (m_last_advanced_direction == right || +                m_last_advanced_direction == left)              { -                m_Direction = up; +                m_direction = up;              }          }          else if (event.key.key == SDLK_DOWN) { -            if (m_LastAdvancedDirection == right || -                m_LastAdvancedDirection == left) +            if (m_last_advanced_direction == right || +                m_last_advanced_direction == left)              { -                m_Direction = down; +                m_direction = down;              }          }          else if (event.key.key == SDLK_RIGHT) { -            if (m_LastAdvancedDirection == up || -                m_LastAdvancedDirection == down) +            if (m_last_advanced_direction == up || +                m_last_advanced_direction == down)              { -                m_Direction = right; +                m_direction = right;              }          }          else if (event.key.key == SDLK_LEFT) { -            if (m_LastAdvancedDirection == up || -                m_LastAdvancedDirection == down) +            if (m_last_advanced_direction == up || +                m_last_advanced_direction == down)              { -                m_Direction = left; +                m_direction = left;              }          }          else if (event.key.key == SDLK_ESCAPE) { -            m_IsPaused = true; +            m_game_status = game_paused;          }      } @@ -198,21 +220,23 @@ void Snake::ProcessEventDuringResume(SDL_Event &event) {      }  } -void Snake::SpawnFood() { -    int32_t bit0_counts[MAX_MAP_HEIGHT]; +void +Snake::SpawnFood() +{ +    int32_t bit0_counts[max_map_height];      int32_t bit0_count_total = 0;      // count bits -    for (int32_t y = 0; y < m_MapHeight; y++) { +    for (int32_t y = 0; y < m_map_height; y++) {          int32_t bit1_count = 0; -        uint64_t bitmap_row = m_BodyBitmap[y]; +        uint64_t bitmap_row = m_body_bitmap[y];          while (bitmap_row != 0) {              bitmap_row = bitmap_row & (bitmap_row - 1);              bit1_count += 1;          } -        int32_t bit0_count = m_MapWidth - bit1_count; +        int32_t bit0_count = m_map_width - bit1_count;          bit0_counts[y] = bit0_count;          bit0_count_total += bit0_count;      } @@ -221,13 +245,13 @@ void Snake::SpawnFood() {          return;      } -    m_Dist.param(std::uniform_int_distribution<int32_t>::param_type(0, bit0_count_total - 1)); -    int32_t bit0_index = m_Dist(m_Rng); +    m_dist.param(std::uniform_int_distribution<int32_t>::param_type(0, bit0_count_total - 1)); +    int32_t bit0_index = m_dist(s_rng);      int32_t bit0_x = 0;      int32_t bit0_y = 0;      // find y -    for (int32_t y = 0; y < m_MapHeight; y++) { +    for (int32_t y = 0; y < m_map_height; y++) {          if (bit0_index < bit0_counts[y]) {              bit0_y = y;              break; @@ -236,8 +260,8 @@ void Snake::SpawnFood() {      }      // find x -    uint64_t bitmap_row_not = ~m_BodyBitmap[bit0_y]; -    for (int32_t x = 0; x < m_MapWidth; x++) { +    uint64_t bitmap_row_not = ~m_body_bitmap[bit0_y]; +    for (int32_t x = 0; x < m_map_width; x++) {          if (bitmap_row_not & 1) {              if (bit0_index == 0) {                  bit0_x = x; @@ -248,23 +272,25 @@ void Snake::SpawnFood() {          bitmap_row_not >>= 1;      } -    m_FoodPosition = {bit0_x, bit0_y}; +    m_food_position = {bit0_x, bit0_y};  } -void Snake::Draw() { +void +Snake::Draw() +{      float world_width = 4.0f;      float world_height = 3.0f; -    float tile_size = (world_width / 2) / MAX_MAP_WIDTH; +    float tile_size = (world_width / 2) / max_map_width;      float bodypart_size = 0.8f * tile_size;      float bodypart_offset = (tile_size - bodypart_size) / 2; -    float map_view_width = tile_size * (float)m_MapWidth; -    float map_view_height = tile_size * (float)m_MapHeight; +    float map_view_width = tile_size * (float)m_map_width; +    float map_view_height = tile_size * (float)m_map_height;      float map_x = (world_width - map_view_width) / 2;      float map_y = (world_height - map_view_height) / 2; -    int32_t max_positions = sizeof(m_BodyPositions) / sizeof(m_BodyPositions[0]); +    int32_t max_positions = ARRAY_COUNT(m_body_positions);      /* draw map background */ @@ -282,12 +308,12 @@ void Snake::Draw() {      /* draw snake */      // 1) if tail > head: advance to end first -    int32_t tail = m_Tail; -    if (tail > m_Head) { +    int32_t tail = m_tail; +    if (tail > m_head) {          while (tail < max_positions) {              V3F32 local_pos = { -                (float)m_BodyPositions[tail].x * tile_size + bodypart_offset, -                (float)m_BodyPositions[tail].y * tile_size + bodypart_offset, +                (float)m_body_positions[tail].x * tile_size + bodypart_offset, +                (float)m_body_positions[tail].y * tile_size + bodypart_offset,                  1.0f              };              V2F32 local_dim = {bodypart_size, bodypart_size}; @@ -312,10 +338,10 @@ void Snake::Draw() {          tail = 0;      }      // 2) advance to head -    while (tail <= m_Head) { +    while (tail <= m_head) {          V3F32 local_pos = { -            (float)m_BodyPositions[tail].x * tile_size + bodypart_offset, -            (float)m_BodyPositions[tail].y * tile_size + bodypart_offset, +            (float)m_body_positions[tail].x * tile_size + bodypart_offset, +            (float)m_body_positions[tail].y * tile_size + bodypart_offset,              1.0f          };          V2F32 local_dim = {bodypart_size, bodypart_size}; @@ -341,8 +367,8 @@ void Snake::Draw() {      /* draw food */      V3F32 pos = { -        map_world_pos.x + (float)m_FoodPosition.x * tile_size + bodypart_offset, -        map_world_pos.y + (float)m_FoodPosition.y * tile_size + bodypart_offset, +        map_world_pos.x + (float)m_food_position.x * tile_size + bodypart_offset, +        map_world_pos.y + (float)m_food_position.y * tile_size + bodypart_offset,          1.0f      };      V2F32 dim = {bodypart_size, bodypart_size}; @@ -356,16 +382,3 @@ void Snake::Draw() {      g_renderer.PushRectangle(rect, pos.z, color);  } -void Snake::DoImgui() { -    if (m_IsPaused) { -        ImGui::Begin("SnakePause"); -        if (ImGui::Button("Resume")) { -            m_IsPaused = false; -        } -        if (ImGui::Button("Exit")) { -            m_IsRunning = false; -        } -        ImGui::End(); -    } -} - diff --git a/src/games/snake/Snake.hpp b/src/games/snake/Snake.hpp index 51d98fb..103255c 100644 --- a/src/games/snake/Snake.hpp +++ b/src/games/snake/Snake.hpp @@ -18,45 +18,39 @@ public:  public:      Snake(); -    bool Update(std::vector<SDL_Event> &events) override; +    bool Update(std::vector<SDL_Event>& events) override;  private: -    void ProcessEventDuringPause(SDL_Event &event); -    void ProcessEventDuringResume(SDL_Event &event); +    void ProcessEventDuringPause(SDL_Event& event); +    void ProcessEventDuringResume(SDL_Event& event); + +    void Start(int32_t map_width, int32_t map_height);      void MaybeMoveSnake(float dt_in_seconds);      void SpawnFood();      void Draw(); -    void DoImgui(); -  private: -    static constexpr int32_t MAX_MAP_WIDTH = 16; -    static constexpr int32_t MAX_MAP_HEIGHT = 16; - -    bool m_IsPaused; -    bool m_IsRunning; - -    float m_DtInSecondsRemaining; -    uint64_t m_LastMillisecondsSinceT0; - -    float m_TilesPerSecond; -    Direction m_Direction; -    Direction m_LastAdvancedDirection; - -    int32_t m_MapWidth; -    int32_t m_MapHeight; -    int32_t m_Tail; -    int32_t m_Head; -    uint64_t m_BodyBitmap[MAX_MAP_HEIGHT]; -    V2I32 m_BodyPositions[MAX_MAP_WIDTH * MAX_MAP_HEIGHT]; -    V2I32 m_FoodPosition; - -    std::mt19937 m_Rng; -    std::uniform_int_distribution<int32_t> m_Dist; +    static constexpr int32_t max_map_width = 16; +    static constexpr int32_t max_map_height = 16; +    static constexpr float tiles_per_second = 4.0f; + +    static std::mt19937 s_rng; +    std::uniform_int_distribution<int32_t> m_dist; + +    Direction m_direction; +    Direction m_last_advanced_direction; + +    int32_t m_map_width; +    int32_t m_map_height; +    int32_t m_tail {0}; +    int32_t m_head {1}; +    uint64_t m_body_bitmap[max_map_height]; +    V2I32 m_body_positions[max_map_width * max_map_height]; +    V2I32 m_food_position;  };  | 
