Nimbin[12]?SDL & Graphics / mapcreator / commits / b60225d

mapcreator git · master

SDL3 2.5D game and engine using assets, with map editor

sdl3 c++ game engine map-editor cmake · first commit 2025-10-31 · last commit 2026-09-07 (1 month ago) · synced 3 days ago · upstream: git.ide3.de/hsnr/sdl-spieleentwicklung/map_creator

C++ 99.3%
git clone https://git.christianimmanuel.de/sdl-graphics/mapcreator.gitwget https://git.christianimmanuel.de/sdl-graphics/mapcreator/archive/mapcreator.tar.gz

..

Christian Immanuel · 2026-02-10 22:52 · b60225d9815d91e3088a91cede4667a004dd44ff

 src/game/game.cpp            | 24 ++++++++++++++++++++++++
 src/game/game_state.hpp      |  3 +++
 src/game/state_menu_main.cpp | 20 ++++++++++++++++++++
 src/game/state_playing.cpp   | 19 +++++++++++++++----
 4 files changed, 62 insertions(+), 4 deletions(-)

diff --git a/src/game/game.cpp b/src/game/game.cpp
index 3206ec4..71668e0 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -67,9 +67,12 @@ Game::Game() : running(true) {
     audio = new Audio();
     Animation::audio = audio;
 
+    /*
     audio->RegisterSound("character.walk", "music/character.walk.wav");
     audio->RegisterSound("character.hit",  "music/character.hit.wav");
+    */
     audio->RegisterSound("bird.sing",      "music/bird.sing.wav");
+    audio->RegisterSound("menu.hover",     "music/menu.hover.wav");
 
     // INIT Font
     Ui::init_Font();
@@ -107,8 +110,27 @@ Game::~Game() {
 void Game::set_State(GameState_e new_state, NewGameState_e game_state_e) {
     // STATE_PLAYING
 
+    // START CURSOR
+    bool ret = false;
+    switch (new_state) {
+        case GameState_e::STATE_MODIFY:
+            ret = SDL_ShowCursor();
+            break;
+        case GameState_e::STATE_MENU_MAIN:
+            ret = SDL_ShowCursor();
+            break;
+        case GameState_e::STATE_PLAYING:
+            ret = SDL_HideCursor();
+            break;
+    }
+    if (!ret) {
+        std::cout << "ERROR: " << SDL_GetError() << std::endl;
+    }
+    // END CURSOR
+
     state_changed = true;
     if (new_state == GameState_e::STATE_PLAYING) {
+
         if (Default::game_time_pause_start != 0) {
             Default::game_time_paused += (SDL_GetTicksNS() - Default::game_time_pause_start) * 1e-9;
             Default::game_time_pause_start = 0;
@@ -149,9 +171,11 @@ void Game::set_State(GameState_e new_state, NewGameState_e game_state_e) {
     // STATE MODIFY AND MENU
     switch (new_state) {
         case GameState_e::STATE_MODIFY:
+            SDL_ShowCursor();
             state_temp = std::make_unique<StateModify>();
             break;
         case GameState_e::STATE_MENU_MAIN:
+            SDL_ShowCursor();
             state_temp = std::make_unique<StateMenuMain>();
             break;
         default: break;
diff --git a/src/game/game_state.hpp b/src/game/game_state.hpp
index cd0552c..bdb127a 100644
--- a/src/game/game_state.hpp
+++ b/src/game/game_state.hpp
@@ -3,6 +3,8 @@
 #include <SDL3/SDL.h>
 #include <SDL3/SDL_mouse.h>
 
+#include "audio/audio.hpp"
+
 class Game;
 class Input;
 
@@ -21,5 +23,6 @@ public:
     virtual void Render(Game*) = 0;
     bool is_Finished() const { return finished; }
 protected:
+    Audio* audio = nullptr;
     bool finished = false;
 };
diff --git a/src/game/state_menu_main.cpp b/src/game/state_menu_main.cpp
index 7d842b8..f3f8855 100644
--- a/src/game/state_menu_main.cpp
+++ b/src/game/state_menu_main.cpp
@@ -12,6 +12,7 @@ StateMenuMain::~StateMenuMain() {}
 static SDL_FRect menu_rect{};
 
 bool StateMenuMain::Init(Game* game) {
+    audio = game->audio;
     game->running = game->running;
 
     // Set up buttons
@@ -84,13 +85,32 @@ void StateMenuMain::Update(Game* game) {
     size_t start_x = static_cast<size_t>(game->win_size.w) / 2 - button_width / 2;
     size_t start_y = static_cast<size_t>(game->win_size.h) / 2 - total_height / 2 + padding;
 
+    static int last_clicked = -1;
+    bool any_button_hovered = false;
     for(size_t i = 0; i < buttons.size(); ++i) {
+        if(buttons[i].hovered) {
+            any_button_hovered = true;
+            if ( (int)i != last_clicked ) {
+                if (audio->is_Playing("menu.hover") )
+                    audio->Stop("menu.hover");
+                audio->Play("menu.hover");
+                last_clicked = i;
+            }
+        }
+
         buttons[i].rect.x = start_x;
         buttons[i].rect.y = start_y + i * (button_height + button_gap);
         buttons[i].rect.w = button_width;
         buttons[i].rect.h = button_height;
     }
 
+    if (!any_button_hovered) {
+        last_clicked = -1;
+        if (audio->is_Playing("menu.hover") )
+            audio->Stop("menu.hover");
+    }
+
+
     // Store menu_rect for rendering
     menu_rect.x = start_x - 30;
     menu_rect.y = start_y - padding;
diff --git a/src/game/state_playing.cpp b/src/game/state_playing.cpp
index 4a50f47..df71b6a 100644
--- a/src/game/state_playing.cpp
+++ b/src/game/state_playing.cpp
@@ -92,6 +92,19 @@ bool StatePlaying::Init(Game* game) {
     return true;
 }
 
+inline void setActiveMenu(CharacterMenuType& active_menu, const CharacterMenuType& new_menu) {
+    switch (active_menu) {
+        case CharacterMenuType::NONE:
+            active_menu = new_menu;
+            SDL_ShowCursor();
+            break;
+        default:
+            active_menu = CharacterMenuType::NONE;
+            SDL_HideCursor();
+            break;
+    }
+}
+
 void StatePlaying::handle_Events(SDL_Event& event, Game* game) {
     if (game->input.cursor_over_tileset) {
         game->input.mouse_game_offset = {(int)Tile::tileset_offset.x,
@@ -118,8 +131,7 @@ void StatePlaying::handle_Events(SDL_Event& event, Game* game) {
                     if (player->selected_item->object_type == InventoryObjectType::ITEM) {
                         sel_item = static_cast<InventoryItem*>(player->selected_item);
                         if (sel_item->type == ItemType::BUILDING_TOOL)
-                            player->active_menu = player->active_menu == CharacterMenuType::NONE
-                                                ? CharacterMenuType::BUILDING : CharacterMenuType::NONE;
+                            setActiveMenu(player->active_menu, CharacterMenuType::BUILDING);
                         else
                             player->messages->Add(MessageKey::BUILDING_TOOL_REQUIRED);
                     } else
@@ -130,8 +142,7 @@ void StatePlaying::handle_Events(SDL_Event& event, Game* game) {
                     Inventory::selected_hotbar = !Inventory::selected_hotbar ? Inventory::selected_hotbar_last : 0;
                     break;
                 case SDL_SCANCODE_E:
-                    player->active_menu = player->active_menu == CharacterMenuType::NONE
-                                        ? CharacterMenuType::INVENTORY : CharacterMenuType::NONE;
+                    setActiveMenu(player->active_menu, CharacterMenuType::INVENTORY);
                     Inventory::draw_menu = !Inventory::draw_menu;
                     break;
                 case SDL_SCANCODE_K: {