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

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

STUFF and fix enemy attac focus AND music for death

Christian Immanuel · 2026-02-06 15:04 · a08f00a7433790d7153bc8d0cc057a12bde40c43

 music/character.die.wav     | Bin 0 -> 196686 bytes
 src/bird/bird.cpp           |  14 +++++------
 src/character/animation.cpp |   2 +-
 src/character/character.cpp |   8 +++---
 src/character/enemy.cpp     |  60 ++++++++++++++++++++++++++++----------------
 src/character/enemy.hpp     |  19 +++++++-------
 6 files changed, 60 insertions(+), 43 deletions(-)

diff --git a/music/character.die.wav b/music/character.die.wav
new file mode 100644
index 0000000..c4b2cd6
Binary files /dev/null and b/music/character.die.wav differ
diff --git a/src/bird/bird.cpp b/src/bird/bird.cpp
index 46f8bad..207d020 100644
--- a/src/bird/bird.cpp
+++ b/src/bird/bird.cpp
@@ -88,7 +88,7 @@ void Bird::Update(double delta_s, const SDL_FPoint& player_pos) {
             }
         } else {
             // Reached target - begin landing
-            std::cout << "BIRD INIT LANDING!\n";
+            //std::cout << "BIRD INIT LANDING!\n";
             is_landing = true;
             landing_progress = 0.0f;
             landing_start_x = pos_x;
@@ -131,7 +131,7 @@ void Bird::Update(double delta_s, const SDL_FPoint& player_pos) {
 
             if (fabsf(dx) > 0.01f) facing_left = (dx < 0.0f);
         } else {
-            std::cout << "BIRD WALK REACHED GOAL" << std::endl;
+            //std::cout << "BIRD WALK REACHED GOAL" << std::endl;
             set_State(BirdState::IDLE, 0.4);
         }
     }
@@ -266,7 +266,7 @@ void Bird::set_Position(SDL_FPoint point) {
 
 void Bird::set_State(BirdState new_state, double dec_timer) {
 
-    std::cout << "BIRD SET STATE " << (int)new_state << std::endl;
+    //std::cout << "BIRD SET STATE " << (int)new_state << std::endl;
     decision_timer = dec_timer;
 
     /*
@@ -353,13 +353,13 @@ void Bird::Decide(const SDL_FPoint& player_pos) {
     float dy = pos_y - player_pos.y;
     float dist_sq = dx * dx + dy * dy;
 
-    std::cout << "START DECIED\n";
+    //std::cout << "START DECIED\n";
     // If too far, fly closer
     if ( dist_sq > MAX_RADIUS * MAX_RADIUS &&
          state != BirdState::FLYING &&
          state != BirdState::STOP_FLYING &&
          state != BirdState::START_TO_FLY) {
-        std::cout << "BIRD TARGET TOO FAR\n";
+        //std::cout << "BIRD TARGET TOO FAR\n";
         set_State(BirdState::START_TO_FLY, 0.0);
         pick_FlyTarget(player_pos);
         return;
@@ -373,7 +373,7 @@ void Bird::Decide(const SDL_FPoint& player_pos) {
     int   choice   = rand() % 100;
     float duration = rand() %  70 * 0.1f + 1.1f;
 
-    std::cout << choice << std::endl;
+    // std::cout << "COC " << choice << std::endl;
 
     if (state == BirdState::STOP_FLYING) {
         set_State(BirdState::IDLE, duration);
@@ -396,7 +396,7 @@ void Bird::Decide(const SDL_FPoint& player_pos) {
         pick_FlyTarget(player_pos);
         std::cout << "PDECIDE PICK END\n";
     }
-    std::cout << "END\n";
+    //std::cout << "END\n";
 }
 
 void Bird::pick_FlyTarget(const SDL_FPoint& player_pos) {
diff --git a/src/character/animation.cpp b/src/character/animation.cpp
index 5d522ae..953abd0 100644
--- a/src/character/animation.cpp
+++ b/src/character/animation.cpp
@@ -62,7 +62,7 @@ namespace Animation {
             if (anim.has_audio) {
                 if ( !audio->is_Playing(anim.audio_name.c_str()) ) {
                     audio->Play(anim.audio_name.c_str());
-                    std::cout << "PLAY START\n";
+                    //std::cout << "PLAY START\n";
                 }
             }
         }
diff --git a/src/character/character.cpp b/src/character/character.cpp
index 727c7c3..29269bc 100644
--- a/src/character/character.cpp
+++ b/src/character/character.cpp
@@ -120,9 +120,9 @@ Character::Init(SDL_Renderer* renderer) {
     animation.hit_woodaxe_stone[WalkDirection::SIDE] = Animation::load(renderer, "Pixel_Crawler/Entities/Characters/Body_A/Animations/Slice_Base/Slice_Side.png", tile_size, tile_size, "None");
     animation.hit_woodaxe_stone[WalkDirection::UP]   = Animation::load(renderer, "Pixel_Crawler/Entities/Characters/Body_A/Animations/Slice_Base/Slice_Up.png",   tile_size, tile_size, "None");
 
-    animation.death[WalkDirection::DOWN] = Animation::load(renderer, "Pixel_Crawler/Entities/Characters/Body_A/Animations/Death_Base/Death_Down-Sheet.png", tile_size, tile_size, "None");
-    animation.death[WalkDirection::SIDE] = Animation::load(renderer, "Pixel_Crawler/Entities/Characters/Body_A/Animations/Death_Base/Death_Side-Sheet.png", tile_size, tile_size, "None");
-    animation.death[WalkDirection::UP]   = Animation::load(renderer, "Pixel_Crawler/Entities/Characters/Body_A/Animations/Death_Base/Death_Up-Sheet.png",   tile_size, tile_size, "None");
+    animation.death[WalkDirection::DOWN] = Animation::load(renderer, "Pixel_Crawler/Entities/Characters/Body_A/Animations/Death_Base/Death_Down-Sheet.png", tile_size, tile_size, "character.die");
+    animation.death[WalkDirection::SIDE] = Animation::load(renderer, "Pixel_Crawler/Entities/Characters/Body_A/Animations/Death_Base/Death_Side-Sheet.png", tile_size, tile_size, "character.die");
+    animation.death[WalkDirection::UP]   = Animation::load(renderer, "Pixel_Crawler/Entities/Characters/Body_A/Animations/Death_Base/Death_Up-Sheet.png",   tile_size, tile_size, "character.die");
 
     animation.block[WalkDirection::DOWN] = Animation::load(renderer, "Pixel_Crawler/Entities/Characters/Body_A/Animations/Pierce_Blocking/Down.png", tile_size, tile_size, "None");
     animation.block[WalkDirection::SIDE] = Animation::load(renderer, "Pixel_Crawler/Entities/Characters/Body_A/Animations/Pierce_Blocking/Side.png", tile_size, tile_size, "None");
@@ -142,7 +142,7 @@ Character::Init(SDL_Renderer* renderer) {
 }
 
 void Character::set_Status(const CharacterStatus& s) {
-    if (status != s && active_anim && active_anim->has_audio)
+    if (status != s && status != CharacterStatus::DYING && active_anim && active_anim->has_audio)
         Animation::audio->Stop(active_anim->audio_name.c_str());
     status = s;
     active_anim->timer = 0;
diff --git a/src/character/enemy.cpp b/src/character/enemy.cpp
index 853fb2a..af36736 100644
--- a/src/character/enemy.cpp
+++ b/src/character/enemy.cpp
@@ -353,7 +353,7 @@ void Enemy::Decide(Character& player) {
     //float  d_y  = player.collider_world.y - collider_world.y;
     //size_t dc_x = static_cast<size_t>(abs(d_x));
     //size_t dc_y = static_cast<size_t>(abs(d_y));
-    EnemyMovingType r = static_cast<EnemyMovingType>(1 + (rand() % static_cast<int>(EnemyMovingType::LAST)-1));
+    EnemyMovingType r = (move_focus != EnemyMovingType::NONE) ? move_focus: static_cast<EnemyMovingType>(1 + (rand() % static_cast<int>(EnemyMovingType::LAST)-1));
 
     set_MoveLogic(r, player);
 }
@@ -857,9 +857,11 @@ Enemy::set_MoveLogic(EnemyMovingType& type, Character& player) {
             }
             moving_logic.object   = static_cast<void*>(&player);
             moving_logic.position = player.collider_world;
+            moving_logic.duration =  0.8 + ((double)rand() / RAND_MAX) * (1.8 - 0.8);
             set_AlignPosition(moving_logic.position);
             sta = EnemyStatus::RUN;
             point_in_reach = false;
+            move_focus = EnemyMovingType::CHARACTER;
             break;
         }
         case EnemyMovingType::LAST:
@@ -904,20 +906,13 @@ Enemy::Update(Character& player) {
         return;
     } else
     if (moving_logic.move_type == EnemyMovingType::WALK) {
-        std::cout << "WLK " << moving_logic.moving_distance.x << " >= " << moving_logic.max_distance << " || " << moving_logic.moving_distance.y << " >= " << moving_logic.max_distance << std::endl; 
+        //std::cout << "WLK " << moving_logic.moving_distance.x << " >= " << moving_logic.max_distance << " || " << moving_logic.moving_distance.y << " >= " << moving_logic.max_distance << std::endl; 
         if ( moving_logic.moving_distance.x >= moving_logic.max_distance ||
              moving_logic.moving_distance.y >= moving_logic.max_distance ) {
             moving_logic.move_type = EnemyMovingType::NONE;
             handle_Animation();
             return;
         }
-    } else
-    if (moving_logic.move_type == EnemyMovingType::CHARACTER) {
-        if ( player.collider_world.x != moving_logic.position.x ||
-             player.collider_world.y != moving_logic.position.y ) {
-            set_MoveLogic(moving_logic.move_type, player);
-            return;
-        }
     }
 
 
@@ -937,23 +932,41 @@ Enemy::Update(Character& player) {
     float min_sq = dist_min * dist_min;
     float max_sq = dist_max * dist_max;
 
-    std::cout << "DSTQ " << (int)moving_logic.move_type << " " << next_moves.size()<< " "  << dist_sq << " " << min_sq << " " << max_sq << std::endl;
+    //std::cout << "DSTQ " << (int)moving_logic.move_type << " " << next_moves.size()<< " "  << dist_sq << " " << min_sq << " " << max_sq << std::endl;
+    bool point_moved = false;
+    if ( player.collider_world.x != moving_logic.position.x ||
+         player.collider_world.y != moving_logic.position.y ) {
+        point_moved = true;
+    }
     if (dist_sq >= min_sq && dist_sq <= max_sq) {
         point_in_reach = true;
         next_moves.clear();
-    } else if (next_moves.empty()) {
-        if (moving_logic.move_type == EnemyMovingType::WALK) {
+    }
+    if (next_moves.empty()) {
+        if (moving_logic.move_type == EnemyMovingType::WALK || (move_focus == EnemyMovingType::CHARACTER && point_moved && moving_logic.duration >= 0)) {
+            float mld = moving_logic.duration;
             set_Status(EnemyStatus::IDLE);
             moving_logic.move_type = EnemyMovingType::IDLE;
-            moving_logic.duration = (moving_logic.moving_distance.x + moving_logic.moving_distance.y) / 100 + 0.5;
+            if (moving_logic.move_type == EnemyMovingType::WALK)
+                moving_logic.duration = (moving_logic.moving_distance.x + moving_logic.moving_distance.y) / 100 + 0.5;
+            else
+                moving_logic.duration = mld;
             std::cout << "Walk DONE !!!!\n";
             return;
         }
     }
+    if (move_focus == EnemyMovingType::CHARACTER) {
+        moving_logic.duration -= Default::delta_time;
+        // std::cout << moving_logic.duration << std::endl;
+        if ((point_moved && moving_logic.duration <= 0) || moving_logic.move_type != EnemyMovingType::CHARACTER) {
+            set_MoveLogic(moving_logic.move_type, player);
+            return;
+        }
+    }
 
     if (moving_logic.move_type == EnemyMovingType::CHARACTER) {
         if (stats.is_attacking) {
-            attack_Character(player, point_in_reach);
+            Attack(point_in_reach);
             handle_Animation();
             return;
         }
@@ -1005,20 +1018,23 @@ Enemy::attack_Start() {
 }
 
 void 
-Enemy::attack_Character(Character& player, bool in_reach) {
+Enemy::Attack( bool in_reach) {
     // i should fic the frame_time to attack_duration
     //  so the animation finishes with the attack end.
     stats.attack_duration += Default::delta_time;
-    if (stats.attack_duration >= stats.attack_duration_max/2) {
-        if (in_reach && !stats.has_attacked) {
+    if (stats.attack_duration < stats.attack_duration_max/2)
+        return;
+
+    if (in_reach && !stats.has_attacked) {
 #ifdef DEBUG_BUILD
-            std::cout << "Enemy: Attack character!\n";
+        std::cout << "Enemy: Attack character!\n";
 #endif
-            stats.has_attacked = true;
-            player.getting_Hit(stats.demage);
-        }
-        attack_Stop();
+        stats.has_attacked = true;
+        if (moving_logic.move_type == EnemyMovingType::CHARACTER)
+            static_cast<Character*>(moving_logic.object)->getting_Hit(stats.demage);
+        //player.getting_Hit(stats.demage);
     }
+    attack_Stop();
 }
 
 void 
diff --git a/src/character/enemy.hpp b/src/character/enemy.hpp
index e238381..b37b044 100644
--- a/src/character/enemy.hpp
+++ b/src/character/enemy.hpp
@@ -68,12 +68,12 @@ enum class EnemyMovingType : uint32_t {
 };
 struct EnemyMovingLogic {
     EnemyMovingType move_type = EnemyMovingType::NONE;
-    void* object = nullptr;
+    void*      object = nullptr;
     SDL_FPoint position = {0,0};
-    bool position_changed = true;
-    float duration = 0.0f;
-    int max_distance = 0;
-    int min_distance = 0;
+    bool       position_changed = true;
+    float      duration = 0.0f;
+    int        max_distance = 0;
+    int        min_distance = 0;
     SDL_FPoint moving_distance = {0,0};
 };
 
@@ -92,13 +92,14 @@ class Enemy {
 
     EnemyMovingLogic moving_logic = {EnemyMovingType::NONE, nullptr};
 
-    bool moving;
+    bool            moving;
+    EnemyMovingType move_focus = EnemyMovingType::NONE;
     float x, y;
     SDL_FPoint next_position = {0,0};
-    SDL_FRect collider;
+    SDL_FRect  collider;
 
     CollisionInterval last_object_collision = {0,0,0,0,false};
-    bool avoiding_object = false;
+    bool       avoiding_object  = false;
     SDL_FPoint avoidance_target = {0,0};
     std::vector<SDL_FPoint> avoidance_targets;
 
@@ -213,7 +214,7 @@ class Enemy {
     attack_Start();
 
     void
-    attack_Character(Character& player, bool in_reach);
+    Attack(bool in_reach);
 
     void
     attack_Stop();