Nimbin[12]?SDL & Graphics / mapcreator / commits / 2f2af02

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

small things?

Christian Immanuel · 2026-02-09 12:18 · 2f2af0229d3c0cc9204c95f1f945627853a3b4ac

 src/character/character.cpp |  5 +++
 src/character/enemy.cpp     | 86 ++++++++++++++++++++++++++++++---------------
 src/character/enemy.hpp     | 11 +++---
 src/character/message.cpp   |  1 +
 src/character/message.hpp   |  1 +
 src/defaults/ui.cpp         |  2 +-
 src/game/state_playing.cpp  | 13 ++++---
 7 files changed, 82 insertions(+), 37 deletions(-)

diff --git a/src/character/character.cpp b/src/character/character.cpp
index 3999d99..96f1b2a 100644
--- a/src/character/character.cpp
+++ b/src/character/character.cpp
@@ -781,6 +781,7 @@ Character::building_Stop() {
 void
 Character::drink_Start() {
     std::cout << "Drinking Start\n";
+    messages->Add(MessageKey::WATER_APPRECIATION);
     if (stats.thirst >= stats.thirst_max)
         return;
     set_Status(CharacterStatus::DRINK_RIVER);
@@ -1833,6 +1834,10 @@ void Character::Update() {
     //bird->set_Position({x,y});
     bird->Update(Default::delta_time, collider_world);
 
+    if (status == CharacterStatus::HIT && active_anim->current_frame == 3) {
+        set_Status(CharacterStatus::IDLE);
+    }
+
     if ( is_placing_build)
         BuildingData::update_ActiveBuildData(collider_world.x, collider_world.y - collider.h);
 
diff --git a/src/character/enemy.cpp b/src/character/enemy.cpp
index af36736..85b1e2f 100644
--- a/src/character/enemy.cpp
+++ b/src/character/enemy.cpp
@@ -11,14 +11,15 @@ std::vector<Enemy*> Enemy::enemies;
 std::vector<SpawnParams> Enemy::enemies_to_spawn;
 
 SDL_FPoint Enemy::colider_default = {7, 7};
+EnemyAnimation Enemy::animation_all;
+size_t Enemy::tile_size = 64;
 
 Enemy::Enemy(WeaponType weapon_type, WeaponMaterial weapon_material, SDL_FPoint position, EnemyStats status)
-    : weapon(weapon_type, weapon_material) {
+    : animation(animation_all), weapon(weapon_type, weapon_material) {
         x = position.x;
         y = position.y;
         stats = status;
 
-        tile_size = 64;
 
         speed = 40.0f;
         run = 1.4f;
@@ -51,28 +52,31 @@ Enemy::Enemy(WeaponType weapon_type, WeaponMaterial weapon_material, SDL_FPoint
     }
 
 void
-Enemy::Init(SDL_Renderer* renderer) {
-    animation.run[WalkDirection::DOWN] = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Run/Run_up.png", tile_size, tile_size, "None");
-    animation.run[WalkDirection::SIDE] = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Run/Run.png", tile_size, tile_size, "None");
-    animation.run[WalkDirection::UP]   = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Run/Run_up.png", tile_size, tile_size, "None");
-
-    animation.idle[WalkDirection::DOWN] = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Idle/Idle-Sheet_padded.png", tile_size, tile_size, "None");
-    animation.idle[WalkDirection::SIDE] = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Idle/Idle-Sheet_padded.png", tile_size, tile_size, "None");
-    animation.idle[WalkDirection::UP]   = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Idle/Idle-Sheet_padded.png", tile_size, tile_size, "None");
-
-    animation.attack[WalkDirection::DOWN] = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Attack/Attack_Down.png", tile_size, tile_size, "None");
-    animation.attack[WalkDirection::SIDE] = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Attack/Attack.png", tile_size, tile_size, "None");
-    animation.attack[WalkDirection::UP]   = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Attack/Attack_Up.png", tile_size, tile_size, "None");
-
-    animation.hit[WalkDirection::DOWN] = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Idle/Idle-Sheet_padded.png", tile_size, tile_size, "character.hit");
-    animation.hit[WalkDirection::SIDE] = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Idle/Idle-Sheet_padded.png", tile_size, tile_size, "character.hit");
-    animation.hit[WalkDirection::UP]   = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Idle/Idle-Sheet_padded.png", tile_size, tile_size, "character.hit");
-
-    animation.death[WalkDirection::DOWN] = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Death/Death-Sheet_processed.png", tile_size, tile_size, "None");
-    animation.death[WalkDirection::SIDE] = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Death/Death-Sheet_processed.png", tile_size, tile_size, "None");
-    animation.death[WalkDirection::UP]   = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Death/Death-Sheet_processed.png", tile_size, tile_size, "None");
+Enemy::init_All(SDL_Renderer* renderer) {
+    animation_all.run[WalkDirection::DOWN] = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Run/Run_up.png", tile_size, tile_size, "None");
+    animation_all.run[WalkDirection::SIDE] = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Run/Run.png", tile_size, tile_size, "None");
+    animation_all.run[WalkDirection::UP]   = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Run/Run_up.png", tile_size, tile_size, "None");
+
+    animation_all.idle[WalkDirection::DOWN] = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Idle/Idle-Sheet_padded.png", tile_size, tile_size, "None");
+    animation_all.idle[WalkDirection::SIDE] = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Idle/Idle-Sheet_padded.png", tile_size, tile_size, "None");
+    animation_all.idle[WalkDirection::UP]   = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Idle/Idle-Sheet_padded.png", tile_size, tile_size, "None");
+
+    animation_all.attack[WalkDirection::DOWN] = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Attack/Attack_Down.png", tile_size, tile_size, "None");
+    animation_all.attack[WalkDirection::SIDE] = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Attack/Attack.png", tile_size, tile_size, "None");
+    animation_all.attack[WalkDirection::UP]   = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Attack/Attack_Up.png", tile_size, tile_size, "None");
+
+    animation_all.hit[WalkDirection::DOWN] = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Idle/Idle-Sheet_padded.png", tile_size, tile_size, "character.hit");
+    animation_all.hit[WalkDirection::SIDE] = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Idle/Idle-Sheet_padded.png", tile_size, tile_size, "character.hit");
+    animation_all.hit[WalkDirection::UP]   = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Idle/Idle-Sheet_padded.png", tile_size, tile_size, "character.hit");
+
+    animation_all.death[WalkDirection::DOWN] = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Death/Death-Sheet_processed.png", tile_size, tile_size, "None");
+    animation_all.death[WalkDirection::SIDE] = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Death/Death-Sheet_processed.png", tile_size, tile_size, "None");
+    animation_all.death[WalkDirection::UP]   = Animation::load(renderer, "Pixel_Crawler/Entities/Mobs/Skeleton Crew/Skeleton - Base/Death/Death-Sheet_processed.png", tile_size, tile_size, "None");
+}
 
 
+void
+Enemy::Init() {
     handle_Animation();
 
     set_Status(EnemyStatus::IDLE);
@@ -295,25 +299,42 @@ struct WorkerData {
     const std::vector<bool>* grid;
 };
 
+/*
+static inline double ms_since(Uint64 start) {
+    static const double freq = static_cast<double>(SDL_GetPerformanceFrequency());
+    return (SDL_GetPerformanceCounter() - start) * 1000.0 / freq;
+}
+*/
+
 void Enemy::run_GetMovesThreads() {
+    //Uint64 t0 = SDL_GetPerformanceCounter();
+
     std::vector<bool> grid = Map::tile_collission_map;
+    //std::cout << "grid copy: " << ms_since(t0) << " ms\n";
 
-    std::set<int> checks = {0, 1, 2, 3, 4, 5, 6, 7,  8, 12, 16, 32, 64, 128, 256 };
+    //Uint64 t1 = SDL_GetPerformanceCounter();
+
+    std::set<int> checks = {0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 32, 64, 128, 256};
     for (Enemy* enemy : Enemy::enemies) {
-        if (!checks.count(enemy->next_moves.size()))
+        if (enemy->moving_logic.move_type != EnemyMovingType::WALK ||
+            !checks.count(enemy->next_moves.size()))
             continue;
+
         int tx = static_cast<int>(enemy->collider_world.x / Tile::tile_collider_size);
         int ty = static_cast<int>(enemy->collider_world.y / Tile::tile_collider_size);
 
         if (tx < 0 || ty < 0 ||
-                tx >= static_cast<int>(Map::size.x * Tile::tile_collider_size) ||
-                ty >= static_cast<int>(Map::size.y * Tile::tile_collider_size))
+            tx >= static_cast<int>(Map::size.x * Tile::tile_collider_size) ||
+            ty >= static_cast<int>(Map::size.y * Tile::tile_collider_size))
             continue;
 
         size_t id = static_cast<size_t>(ty * (Map::size.x * Tile::tile_collider_size) + tx);
         grid[id] = true;
     }
 
+    //std::cout << "grid marking: " << ms_since(t1) << " ms\n";
+    //Uint64 t2 = SDL_GetPerformanceCounter();
+
     std::vector<WorkerData> jobdata;
     jobdata.reserve(Enemy::enemies.size());
 
@@ -339,15 +360,23 @@ void Enemy::run_GetMovesThreads() {
         workers.push_back(th);
     }
 
+    //std::cout << "thread creation: " << ms_since(t2) << " ms\n";
+    //Uint64 t3 = SDL_GetPerformanceCounter();
+
     for (SDL_Thread* th : workers)
         SDL_WaitThread(th, nullptr);
+
+    //std::cout << "thread execution + join: " << ms_since(t3) << " ms\n";
+    //std::cout << "total: " << ms_since(t0) << " ms\n";
 }
 
 
 
 
 
+
 void Enemy::Decide(Character& player) {
+    std::cout << "DEC " << (int) status << std::endl;
 
     //float  d_x  = player.collider_world.x - collider_world.x;
     //float  d_y  = player.collider_world.y - collider_world.y;
@@ -356,6 +385,7 @@ void Enemy::Decide(Character& player) {
     EnemyMovingType r = (move_focus != EnemyMovingType::NONE) ? move_focus: static_cast<EnemyMovingType>(1 + (rand() % static_cast<int>(EnemyMovingType::LAST)-1));
 
     set_MoveLogic(r, player);
+    std::cout << "DEB " << (int) status << std::endl;
 }
 
 inline bool same_corner(const SDL_FPoint& a, const SDL_FPoint& b, float epsilon = 1.0f) {
@@ -738,12 +768,12 @@ Enemy::init_SpawnEnemy(double delay_to_spawn_in_sec, WeaponType weapon_type = We
 }
 
 bool
-Enemy::spawn_Enemy(SDL_Renderer* renderer, SpawnParams& params) {
+Enemy::spawn_Enemy(SpawnParams& params) {
     if (params.spawn_date > Default::get_TimeSinceStartInSec())
         return false;
 
     Enemy* enemy = new Enemy(params.type, params.material, params.pos, params.stats);
-    enemy->Init(renderer);
+    enemy->Init();
     Enemy::enemies.push_back(enemy);
     return true;
 }
diff --git a/src/character/enemy.hpp b/src/character/enemy.hpp
index b37b044..9e0bbdc 100644
--- a/src/character/enemy.hpp
+++ b/src/character/enemy.hpp
@@ -81,7 +81,7 @@ class Enemy {
     float  speed;
     float  run; // multiplier
     bool   flip;
-    size_t tile_size;
+    static size_t tile_size;
     float  arm_reach_radius;
 
     public:
@@ -117,7 +117,8 @@ class Enemy {
 
 
     AnimationData* active_anim;
-    EnemyAnimation animation;
+    static EnemyAnimation animation_all;
+    EnemyAnimation& animation;
     WalkDirection  direction;
     std::unordered_map<WalkDirection, bool>  direction_blocked;
     bool direction_tested_up;
@@ -146,7 +147,9 @@ class Enemy {
 
 
     void
-    Init(SDL_Renderer* renderer);
+    Init();
+    static void
+    init_All(SDL_Renderer*);
 
     void
     set_Status(const EnemyStatus&);
@@ -159,7 +162,7 @@ class Enemy {
     static void
     init_SpawnEnemy(double delay_to_spawn_in_sec, WeaponType weapon_type, WeaponMaterial weapon_material, SDL_FPoint position, EnemyStats status);
     static bool
-    spawn_Enemy(SDL_Renderer*, SpawnParams&);
+    spawn_Enemy(SpawnParams&);
 
     static Enemy*
     is_InEnemyReach(const SDL_FRect& rect);
diff --git a/src/character/message.cpp b/src/character/message.cpp
index e7510bf..888da34 100644
--- a/src/character/message.cpp
+++ b/src/character/message.cpp
@@ -19,6 +19,7 @@ Messages::Messages() {
         {MessageKey::DISCOVERED_BUILDING,    {5, MessageType::CHARACTER, "Maybe i can build something with it.."}},
         {MessageKey::THIRST_20,     {10, MessageType::CHARACTER, "I should drink something.."}},
         {MessageKey::THIRST_0,      {10, MessageType::CHARACTER, "No water no life.."}},
+        {MessageKey::WATER_APPRECIATION, {5, MessageType::CHARACTER, "Hmmm water"}},
         {MessageKey::CRAFTED_ITEM,  {10, MessageType::CHARACTER, "Whatever i can do with that.."}},
         {MessageKey::ADD_INVENTORY, {10, MessageType::INVENTORY, "Added item: "}},
         {MessageKey::ADD_RESOURCE,  {10, MessageType::RESOURCE,  "Resource "}},
diff --git a/src/character/message.hpp b/src/character/message.hpp
index f928b1c..6724ef8 100644
--- a/src/character/message.hpp
+++ b/src/character/message.hpp
@@ -31,6 +31,7 @@ enum class MessageKey {
     DISCOVERED_BUILDING,
     THIRST_20,
     THIRST_0,
+    WATER_APPRECIATION,
     CRAFTED_ITEM,
     ADD_INVENTORY,
     ADD_RESOURCE,
diff --git a/src/defaults/ui.cpp b/src/defaults/ui.cpp
index 8fbfc97..e590b5c 100644
--- a/src/defaults/ui.cpp
+++ b/src/defaults/ui.cpp
@@ -73,7 +73,7 @@ namespace Ui {
         font_tiny  = TTF_OpenFont("fonts/DejaVuSansMono.ttf", 12);
         font_menu  = TTF_OpenFont("fonts/DejaVuSansMono.ttf", 18);
         font_menu_bold = TTF_OpenFont("fonts/DejaVuSansMono-Bold.ttf", 18);
-        font_message   = TTF_OpenFont("fonts/DejaVuSansMono.ttf", 16);
+        font_message   = TTF_OpenFont("fonts/DejaVuSansMono.ttf", 22);
 
         if (!font_big || !font_small) {
             std::cerr << "Failed to load font: " << SDL_GetError() << std::endl;
diff --git a/src/game/state_playing.cpp b/src/game/state_playing.cpp
index 4886152..2bdb6d2 100644
--- a/src/game/state_playing.cpp
+++ b/src/game/state_playing.cpp
@@ -37,6 +37,9 @@ bool StatePlaying::Init(Game* game) {
     // INIT Bird
     Bird::Init(game->renderer);
 
+    // INIT Enemy
+    Enemy::init_All(game->renderer);
+
     Map::tile_map = Map::load_MapTiles(Map::save_path);
     if (Map::tile_map.size() == 0) Map::Init();
 
@@ -44,7 +47,7 @@ bool StatePlaying::Init(Game* game) {
     if (Map::tile_collission_map.size() == 0) Map::init_Collider();
 
     Map::offset = {0, 0};
-    Default::game_scale = 2.8;
+    Default::game_scale = 4.0;
 
 
     // START CHEAT
@@ -103,7 +106,7 @@ void StatePlaying::handle_Events(SDL_Event& event, Game* game) {
                      player->inventory->selected_hotbar_last = player->inventory->selected_hotbar;
                      player->inventory->selected_hotbar = (int)(event.key.scancode - SDL_SCANCODE_1) + 1;
                  } if (event.key.scancode == SDL_SCANCODE_0) {
-                     Default::game_scale = 2.8;
+                     Default::game_scale = 4.0;
                  }
                  break;
              }
@@ -216,7 +219,7 @@ void StatePlaying::Update(Game* game) {
     // spawn
     for (size_t i = 0; i < Enemy::enemies_to_spawn.size(); ) {
         SpawnParams &sp = Enemy::enemies_to_spawn[i];
-        if (Enemy::spawn_Enemy(game->renderer, sp))
+        if (Enemy::spawn_Enemy(sp))
             Enemy::enemies_to_spawn.erase(Enemy::enemies_to_spawn.begin() + static_cast<long>(i));
         else
             ++i;
@@ -271,12 +274,14 @@ void StatePlaying::Render(Game* game) {
 void StatePlaying::Load(SDL_Renderer* renderer, std::string path) {
     Map::tile_map = Map::load_MapTiles(path + "/map");
     Map::load_TileCollision(path + "/collisions");
+    if (!renderer)
+        std::cerr << "FUCK NO RENDERER..\n";
 
 
     Enemy::load_All(path+"/enemies");
     for (size_t i = 0; i < Enemy::enemies_to_spawn.size(); ) {
         SpawnParams &sp = Enemy::enemies_to_spawn[i];
-        if (Enemy::spawn_Enemy(renderer, sp))
+        if (Enemy::spawn_Enemy(sp))
             Enemy::enemies_to_spawn.erase(Enemy::enemies_to_spawn.begin() + static_cast<long>(i));
         else
             ++i;