diff --git a/CMakeLists.txt b/CMakeLists.txt
index a4d8044499cc44dc13a6d31a7b8e896efd83b633..baeb663ddaa480176590e70954fa8905899727ed 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -25,7 +25,7 @@ FetchContent_MakeAvailable(highfive)
 FetchContent_Declare(
     box2d
     GIT_REPOSITORY https://github.com/erincatto/box2d.git
-    GIT_TAG v3.0.0
+    GIT_TAG v2.4.2
 )
 
 set(BOX2D_BUILD_TESTBED OFF CACHE BOOL "" FORCE)
diff --git a/res/map_split_island.hdf5 b/res/map_split_island.h5
similarity index 100%
rename from res/map_split_island.hdf5
rename to res/map_split_island.h5
diff --git a/src/editor/main.cpp b/src/editor/main.cpp
index 2688bf6695125425ed12c87436be38998b8ebeab..9831c25bcc06721b76d3faee2bd240a8f22378f2 100644
--- a/src/editor/main.cpp
+++ b/src/editor/main.cpp
@@ -1,23 +1,23 @@
 /**
-* main.cpp
-*
-* @date 27.01.2025
-* @author Jonathan Dueck (jonathan.dueck@informatik.hs-fulda.de)
-*/
+ * main.cpp
+ *
+ * @date 27.01.2025
+ * @author Jonathan Dueck (jonathan.dueck@informatik.hs-fulda.de)
+ */
 
 #include <QApplication>
 
-#include "SpriteProvider.hpp"
-#include "MainWindow.hpp"
 #include "LevelScene.hpp"
+#include "MainWindow.hpp"
+#include "SpriteProvider.hpp"
 
 using namespace editor;
 
 /**
  * The main function starts the program.
  * It checks if any command line arguments were provided.
- * If not it terminates. 
- * Otherwise if a path to a hdf5 level file was provided it 
+ * If not it terminates.
+ * Otherwise if a path to a hdf5 level file was provided it
  * starts the level editor and loads the level from the file for editing.
  * If a width and height was provided, it create a blank level with the given dimensions.
  */
@@ -28,12 +28,12 @@ int main(int argc, char* argv[])
     { // no arguments provided
         std::cerr << "Bitte uebergben Sie den Pfad zu dem Level, das sie bearbeiten wollen oder "
                      "die Breite und Hoehe des Levels, das sie neu erstellen wollen."
-                  << std::endl;
+                  << "\n";
         return 1;
     }
     if (argc > 3)
     { // more than 2 arguments provided
-        std::cerr << "Zuviele Kommandozeilenargumente." << std::endl;
+        std::cerr << "Zuviele Kommandozeilenargumente." << "\n";
         return 1;
     }
 
@@ -44,7 +44,6 @@ int main(int argc, char* argv[])
     // to get the QGraphicsPixmap for a specific tile.
     SpriteProvider::initialize("../res/spritesheet.h5");
 
-
     LevelScene* level;
     if (argc == 2)
     { // 1 argument provided => create Level from file
@@ -59,4 +58,4 @@ int main(int argc, char* argv[])
     window.resize(1300, 800);
     window.show();
     return app.exec();
-}
\ No newline at end of file
+}
diff --git a/src/game/combat/CombatEngine.cpp b/src/game/combat/CombatEngine.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8f5323b6319562d4a61e5af762ee950f3eaa7ed2
--- /dev/null
+++ b/src/game/combat/CombatEngine.cpp
@@ -0,0 +1,225 @@
+#include "CombatEngine.hpp"
+#include "../level/Level.hpp"
+
+#include <iostream>
+#include <memory>
+#include <unordered_map>
+
+namespace advanced_wars
+{
+
+CombatEngine::CombatEngine() {}
+
+void CombatEngine::attack(Unit& attacker, Unit& target)
+{
+    int attackerDamageValue = calculateDamage(attacker, target);
+
+    if (attackerDamageValue > 0)
+    {
+        takeDamage(attacker, target, attackerDamageValue);
+        std::cout << "target health after attack: " << target.getHealth() << "\n";
+
+        // Check if the target is still alive for counter-attack
+        if (target.getHealth() > 0)
+        {
+            // Check if the target is within attack range
+            int distanceX = std::abs(target.getXPosition() - attacker.getXPosition());
+            int distanceY = std::abs(target.getYPosition() - attacker.getYPosition());
+            int distance = distanceX + distanceY;
+
+            if (distance >= target.getMinRange() && distance <= target.getMaxRange())
+            {
+                // Now, they are reversed for the counter-attack
+                int defenderDamageValue = calculateDamage(target, attacker);
+                if (defenderDamageValue > 0)
+                {
+                    takeDamage(target, attacker, defenderDamageValue);
+                    std::cout << "Ally health after retaliation: " << attacker.getHealth() << "\n";
+                }
+            }
+            else
+            {
+                std::cout << "target out of range for counter-attack." << "\n";
+            }
+        }
+    }
+    else
+    {
+        std::cout << "No damage value found for attack from unit "
+                  << static_cast<int>(attacker.getUnitTypeId()) << " against unit "
+                  << static_cast<int>(target.getUnitTypeId()) << "\n";
+    }
+}
+
+int CombatEngine::calculateDamage(Unit& attacker, Unit& target)
+{
+    // Reference to Weapon objects
+    Weapon& primaryWeapon = attacker.getPrimaryWeapon();
+    Weapon& secondaryWeapon = attacker.getSecondaryWeapon();
+
+    // Find the corresponding damage values
+    auto primaryDamageIt = primaryWeapon.getDamage().find(target.getUnitTypeId());
+    auto secondaryDamageIt = secondaryWeapon.getDamage().find(target.getUnitTypeId());
+
+    int damageValue = 0;
+
+    // Calculate damage using secondary weapon if available
+    if (secondaryDamageIt != secondaryWeapon.getDamage().end())
+    {
+        damageValue = secondaryDamageIt->second;
+    }
+
+    // Calculate damage using primary weapon if higher and ammo is available
+    if (primaryDamageIt != primaryWeapon.getDamage().end())
+    {
+        if (attacker.getAmmo() > 0 && primaryDamageIt->second > damageValue)
+        {
+            damageValue = primaryDamageIt->second;
+            // Munition wird erst nach Bestätigung des Angriffs reduziert
+        }
+    }
+
+    return damageValue;
+}
+
+void CombatEngine::takeDamage(Unit& attacker, Unit& target, int damage)
+{
+    int health = attacker.getHealth();
+    int maxHealth = attacker.getMaxHealth();
+    // int effectiveDamage = damage * (static_cast<float>(health) / maxHealth);
+    int effectiveDamage = (damage * health) / maxHealth;
+    target.setHealth(std::clamp(target.getHealth() - effectiveDamage, 0, target.getMaxHealth()));
+}
+
+std::vector<Unit*>
+CombatEngine::getUnitsInRangeWithDamagePotential(Unit& attacker, std::vector<Unit*>& allUnits)
+{
+    std::vector<Unit*> unitsInRangeWithDamage;
+
+    for (const auto& unitPtr : allUnits)
+    {
+        Unit* unit = unitPtr; // Zugriff auf das rohe Unit-Pointer-Objekt
+        if (unit->getFaction() == attacker.getFaction())
+        {
+            continue; // Sich selbst nicht angreifen
+        }
+
+        int distanceX = std::abs(unit->getXPosition() - attacker.getXPosition());
+        int distanceY = std::abs(unit->getYPosition() - attacker.getYPosition());
+        int distance = distanceX + distanceY;
+
+        if (distance >= attacker.getMinRange() && distance <= attacker.getMaxRange())
+        {
+            auto primaryDamageIt =
+                attacker.getPrimaryWeapon().getDamage().find(unit->getUnitTypeId());
+            auto secondaryDamageIt =
+                attacker.getSecondaryWeapon().getDamage().find(unit->getUnitTypeId());
+
+            bool canDealDamage = false;
+
+            if (primaryDamageIt != attacker.getPrimaryWeapon().getDamage().end() &&
+                attacker.getAmmo() > 0)
+            {
+                canDealDamage = true;
+            }
+            if (secondaryDamageIt != attacker.getSecondaryWeapon().getDamage().end())
+            {
+                canDealDamage = true;
+            }
+
+            if (canDealDamage)
+            {
+                unitsInRangeWithDamage.push_back(unit);
+            }
+        }
+    }
+
+    return unitsInRangeWithDamage;
+}
+
+void CombatEngine::handleAttackingEvents(Engine& engine, SDL_Event& event, Level& m_level)
+{
+    if (m_level.getAttackableUnitIds().empty())
+    {
+        std::cout << "No units are within attack range." << "\n";
+        m_level.setState(LevelState::MENUACTIVE_STATE);
+        return; // Early exit if no units to attack
+    }
+    switch (event.type)
+    {
+    case SDL_KEYDOWN:
+        m_level.handlePositionMarker(engine, event);
+        if (event.key.keysym.sym == SDLK_ESCAPE)
+        {
+            m_level.setState(LevelState::MENUACTIVE_STATE);
+        }
+        if (event.key.keysym.sym == SDLK_RETURN)
+        {
+            handleAttack(m_level.getTilemarker().getPosition(), m_level);
+        }
+        break;
+    default:
+        break;
+    }
+}
+
+void CombatEngine::handleAttack(std::pair<int, int> tilePos, Level& m_level)
+{
+    std::unordered_map<int, std::unique_ptr<Unit>>& units = m_level.getUnits();
+    int                                             selectedUnit = m_level.getSelectedUnit();
+    int targetedUnit = m_level.selectUnit(tilePos.first, tilePos.second);
+    if (targetedUnit >= 0)
+    {
+        if (units.at(m_level.getSelectedUnit())->getFaction() ==
+            units.at(targetedUnit)->getFaction())
+        {
+            std::cout << "You cannot attack your allies!" << "\n";
+            return;
+        }
+
+        auto itAttacker = units.find(selectedUnit);
+        auto itDefender = units.find(targetedUnit);
+
+        if (itAttacker == units.end() || itDefender == units.end())
+        {
+            std::cout << "Unit not found!" << "\n";
+            return;
+        }
+
+        std::unique_ptr<Unit>&   attacking = itAttacker->second;
+        std::unique_ptr<Unit>&   defending = itDefender->second;
+        std::unordered_set<int>& attackableUnitIds = m_level.getAttackableUnitIds();
+        if (attackableUnitIds.find(targetedUnit) != attackableUnitIds.end())
+        {
+            attack(*attacking, *defending);
+            // m_level.spawnBullet(*attacking, *defending);
+            // attacking->attack(defending);
+            if (attacking->getHealth() <= 0)
+            {
+                m_level.removeUnit(selectedUnit);
+            }
+            else
+            {
+                attacking->setState(UnitState::UNAVAILABLE);
+            }
+            if (defending->getHealth() <= 0)
+            {
+                m_level.removeUnit(targetedUnit);
+            }
+            m_level.setSelectedUnit(-1);
+            m_level.setShowAttackableTiles(false);
+            m_level.setShowReachableTiles(false);
+            m_level.setState(LevelState::SELECTING_STATE);
+        }
+        else
+        {
+            std::cout << "No target in range clicked!" << "\n";
+        }
+    }
+    else
+    {
+        std::cout << "No valid target clicked" << "\n";
+    }
+}
+
+} // namespace advanced_wars
diff --git a/src/game/combat/CombatEngine.hpp b/src/game/combat/CombatEngine.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..4b26f1a0c6ccc4e1cbc9b93164f5ef57e1599774
--- /dev/null
+++ b/src/game/combat/CombatEngine.hpp
@@ -0,0 +1,29 @@
+#pragma once
+
+#include "../core/Engine.hpp"
+#include "../entities/Unit.hpp"
+
+namespace advanced_wars
+{
+
+class Level;
+
+class CombatEngine
+{
+    public:
+        CombatEngine();
+        ~CombatEngine() = default;
+
+        void        handleAttackingEvents(Engine& engine, SDL_Event& event, Level& m_level);
+        void        handleAttack(std::pair<int, int> tilePos, Level& m_level);
+        static void attack(Unit& attacker, Unit& target);
+        static int  calculateDamage(Unit& attacker, Unit& target);
+        static void takeDamage(Unit& attacker, Unit& target, int damage);
+        void        update();
+        void        render(Engine& engine, int scale);
+        std::vector<Unit*>
+        getUnitsInRangeWithDamagePotential(Unit& attacker, std::vector<Unit*>& allUnits);
+
+    private:
+};
+} // namespace advanced_wars
diff --git a/src/game/combat/Weapon.cpp b/src/game/combat/Weapon.cpp
index 2e5035aa1708cd0b7c0558e86e8eebb587026cfc..ce89ef11dd42f230dc5c55a3239e311a7994c052 100644
--- a/src/game/combat/Weapon.cpp
+++ b/src/game/combat/Weapon.cpp
@@ -4,19 +4,20 @@ namespace advanced_wars
 {
 Weapon::Weapon() : m_name(""), m_damage() {}
 
-Weapon::Weapon(const std::string& weaponName, const std::unordered_map<UnitId, int>& damageValues)
+Weapon::Weapon(
+    const std::string& weaponName, const std::unordered_map<UnitTypeId, int>& damageValues)
     : m_name(weaponName), m_damage(damageValues)
 {
 }
 
 // Funktion zum Hinzufügen von Schadenswerten
-void Weapon::addDamageValue(UnitId unitId, int value)
+void Weapon::addDamageValue(UnitTypeId unitId, int value)
 {
     m_damage[unitId] = value;
 }
 
 // Funktion zum Abrufen eines Schadenswertes
-int Weapon::getDamageValue(UnitId unitId) const
+int Weapon::getDamageValue(UnitTypeId unitId) const
 {
     auto it = m_damage.find(unitId);
     if (it != m_damage.end())
@@ -26,9 +27,9 @@ int Weapon::getDamageValue(UnitId unitId) const
     return 0; // oder ein Fehlerwert
 }
 
-std::unordered_map<UnitId, int>& Weapon::getDamage()
+std::unordered_map<UnitTypeId, int>& Weapon::getDamage()
 {
     return m_damage;
 }
 
-} // namespace advanced_wars
\ No newline at end of file
+} // namespace advanced_wars
diff --git a/src/game/combat/Weapon.hpp b/src/game/combat/Weapon.hpp
index c14cdd21c520345a3db871dec385c994e0e28483..90733feedfad5fa1e1fe056a44aa0580ec0d605b 100644
--- a/src/game/combat/Weapon.hpp
+++ b/src/game/combat/Weapon.hpp
@@ -6,29 +6,30 @@
 namespace advanced_wars
 {
 
-enum class UnitId;
+enum class UnitTypeId;
 
 class Weapon
 {
     public:
         // Konstruktoren
         Weapon();
-        Weapon(const std::string& weaponName, const std::unordered_map<UnitId, int>& damageValues);
+        Weapon(
+            const std::string& weaponName, const std::unordered_map<UnitTypeId, int>& damageValues);
 
         // Methode, um einen Schadenswert hinzuzufügen
-        void addDamageValue(UnitId unitId, int value);
+        void addDamageValue(UnitTypeId unitId, int value);
 
         // Methode, um einen Schadenswert abzurufen
-        int getDamageValue(UnitId unitId) const;
+        int getDamageValue(UnitTypeId unitId) const;
 
-        std::unordered_map<UnitId, int>& getDamage();
+        std::unordered_map<UnitTypeId, int>& getDamage();
 
     private:
         // Name der Waffe
         std::string m_name;
 
         // Schadenstabelle
-        std::unordered_map<UnitId, int> m_damage;
+        std::unordered_map<UnitTypeId, int> m_damage;
 };
 
 } // namespace advanced_wars
diff --git a/src/game/core/Config.cpp b/src/game/core/Config.cpp
index 5d3b240eabde87ada58747b831d7ddb9ab499bba..8c5f23c1050ada6d24a90682cf52805e967f8c5e 100644
--- a/src/game/core/Config.cpp
+++ b/src/game/core/Config.cpp
@@ -27,7 +27,7 @@ Config::Config(std::string filename)
         std::string unit_key = unitData.get<std::string>("<xmlattr>.key");
         try
         {
-            UnitId unitId = mapUnitKeyToID(unit_key);
+            UnitTypeId unitId = mapUnitKeyToID(unit_key);
 
             m_unitCosts[unitId] = unitData.get<int>("Cost");
             m_unitMovementPoints[unitId] = unitData.get<int>("MovementPoints");
@@ -43,7 +43,7 @@ Config::Config(std::string filename)
             catch (const std::out_of_range& e)
             {
                 std::cerr << "Unknown movement type: " << movement_type_str
-                          << " for unit key: " << unit_key << std::endl;
+                          << " for unit key: " << unit_key << "\n";
                 continue;
             }
 
@@ -59,7 +59,7 @@ Config::Config(std::string filename)
                             continue;
 
                         std::string target_key = damage.second.get<std::string>("<xmlattr>.unitId");
-                        UnitId      targetId = mapUnitKeyToID(target_key);
+                        UnitTypeId  targetId = mapUnitKeyToID(target_key);
                         m_primaryWeaponDamage[unitId][targetId] =
                             damage.second.get<int>("<xmlattr>.value");
                     }
@@ -75,7 +75,7 @@ Config::Config(std::string filename)
                             continue;
 
                         std::string target_key = damage.second.get<std::string>("<xmlattr>.unitId");
-                        UnitId      targetId = mapUnitKeyToID(target_key);
+                        UnitTypeId  targetId = mapUnitKeyToID(target_key);
                         m_secondaryWeaponDamage[unitId][targetId] =
                             damage.second.get<int>("<xmlattr>.value");
                     }
@@ -84,34 +84,34 @@ Config::Config(std::string filename)
         }
         catch (const std::out_of_range& e)
         {
-            // std::cerr << "Unknown unit key: " << unit_key << std::endl;
+            // std::cerr << "Unknown unit key: " << unit_key << "\n";
             continue;
         }
     }
 }
 
-UnitId Config::mapUnitKeyToID(const std::string& unit_key) const
+UnitTypeId Config::mapUnitKeyToID(const std::string& unit_key) const
 {
-    static const std::unordered_map<std::string, UnitId> unit_map = {
-        {                 "infantry",                 UnitId::INFANTERY},
-        {      "mechanized_infantry",      UnitId::MECHANIZED_INFANTERY},
-        {                    "recon",                     UnitId::RECON},
-        {                      "apc",                       UnitId::APC},
-        {            "anti_air_tank",             UnitId::ANTI_AIR_TANK},
-        {              "medium_tank",               UnitId::MEDIUM_TANK},
-        {               "heavy_tank",                UnitId::HEAVY_TANK},
-        {                  "neotank",                  UnitId::NEO_TANK},
-        {                "artillery",                 UnitId::ARTILLERY},
-        {         "rocket_artillery",          UnitId::ROCKET_ARTILLERY},
-        {"anti_air_missile_launcher", UnitId::ANTI_AIR_MISSILE_LAUNCHER},
-        {                   "lander",                    UnitId::LANDER},
-        {                  "cruiser",                   UnitId::CRUISER},
-        {                "submarine",                 UnitId::SUBMARINE},
-        {               "battleship",                UnitId::BATTLESHIP},
-        {     "transport_helicopter",      UnitId::TRANSPORT_HELICOPTER},
-        {        "battle_helicopter",         UnitId::BATTLE_HELICOPTER},
-        {                  "fighter",                   UnitId::FIGHTER},
-        {                   "bomber",                    UnitId::BOMBER}
+    static const std::unordered_map<std::string, UnitTypeId> unit_map = {
+        {                 "infantry",                 UnitTypeId::INFANTERY},
+        {      "mechanized_infantry",      UnitTypeId::MECHANIZED_INFANTERY},
+        {                    "recon",                     UnitTypeId::RECON},
+        {                      "apc",                       UnitTypeId::APC},
+        {            "anti_air_tank",             UnitTypeId::ANTI_AIR_TANK},
+        {              "medium_tank",               UnitTypeId::MEDIUM_TANK},
+        {               "heavy_tank",                UnitTypeId::HEAVY_TANK},
+        {                  "neotank",                  UnitTypeId::NEO_TANK},
+        {                "artillery",                 UnitTypeId::ARTILLERY},
+        {         "rocket_artillery",          UnitTypeId::ROCKET_ARTILLERY},
+        {"anti_air_missile_launcher", UnitTypeId::ANTI_AIR_MISSILE_LAUNCHER},
+        {                   "lander",                    UnitTypeId::LANDER},
+        {                  "cruiser",                   UnitTypeId::CRUISER},
+        {                "submarine",                 UnitTypeId::SUBMARINE},
+        {               "battleship",                UnitTypeId::BATTLESHIP},
+        {     "transport_helicopter",      UnitTypeId::TRANSPORT_HELICOPTER},
+        {        "battle_helicopter",         UnitTypeId::BATTLE_HELICOPTER},
+        {                  "fighter",                   UnitTypeId::FIGHTER},
+        {                   "bomber",                    UnitTypeId::BOMBER}
     };
 
     auto it = unit_map.find(unit_key);
@@ -141,7 +141,7 @@ MovementType Config::mapMovementType(const std::string& movementTypeStr) const
     throw std::out_of_range("Unknown movement type: " + movementTypeStr);
 }
 
-int Config::getUnitCost(UnitId id) const
+int Config::getUnitCost(UnitTypeId id) const
 {
     auto it = m_unitCosts.find(id);
     if (it != m_unitCosts.end())
@@ -151,7 +151,7 @@ int Config::getUnitCost(UnitId id) const
     throw std::runtime_error("Cost for unit ID not found");
 }
 
-int Config::getUnitMovementPoints(UnitId id) const
+int Config::getUnitMovementPoints(UnitTypeId id) const
 {
     auto it = m_unitMovementPoints.find(id);
     if (it != m_unitMovementPoints.end())
@@ -161,7 +161,7 @@ int Config::getUnitMovementPoints(UnitId id) const
     throw std::runtime_error("Movement points for unit ID not found");
 }
 
-MovementType Config::getUnitMovementType(UnitId id) const
+MovementType Config::getUnitMovementType(UnitTypeId id) const
 {
     auto it = m_unitMovementType.find(id);
     if (it != m_unitMovementType.end())
@@ -171,7 +171,7 @@ MovementType Config::getUnitMovementType(UnitId id) const
     throw std::runtime_error("Movement type for unit ID not found");
 }
 
-int Config::getUnitAmmo(UnitId id) const
+int Config::getUnitAmmo(UnitTypeId id) const
 {
     auto it = m_unitAmmo.find(id);
     if (it != m_unitAmmo.end())
@@ -181,7 +181,7 @@ int Config::getUnitAmmo(UnitId id) const
     throw std::runtime_error("Ammo for unit ID not found");
 }
 
-int Config::getUnitMinRange(UnitId id) const
+int Config::getUnitMinRange(UnitTypeId id) const
 {
     auto it = m_unitMinRange.find(id);
     if (it != m_unitMinRange.end())
@@ -191,7 +191,7 @@ int Config::getUnitMinRange(UnitId id) const
     throw std::runtime_error("Min range for unit ID not found");
 }
 
-int Config::getUnitMaxRange(UnitId id) const
+int Config::getUnitMaxRange(UnitTypeId id) const
 {
     auto it = m_unitMaxRange.find(id);
     if (it != m_unitMaxRange.end())
@@ -201,7 +201,7 @@ int Config::getUnitMaxRange(UnitId id) const
     throw std::runtime_error("Max range for unit ID not found");
 }
 
-std::string Config::getUnitPrimaryWeapon(UnitId id) const
+std::string Config::getUnitPrimaryWeapon(UnitTypeId id) const
 {
     auto it = m_unitPrimaryWeapon.find(id);
     if (it != m_unitPrimaryWeapon.end())
@@ -211,7 +211,7 @@ std::string Config::getUnitPrimaryWeapon(UnitId id) const
     return "";
 }
 
-std::string Config::getUnitSecondaryWeapon(UnitId id) const
+std::string Config::getUnitSecondaryWeapon(UnitTypeId id) const
 {
     auto it = m_unitSecondaryWeapon.find(id);
     if (it != m_unitSecondaryWeapon.end())
@@ -221,7 +221,8 @@ std::string Config::getUnitSecondaryWeapon(UnitId id) const
     return "";
 }
 
-std::optional<int> Config::getUnitPrimaryWeaponDamage(UnitId attackerId, UnitId targetId) const
+std::optional<int>
+Config::getUnitPrimaryWeaponDamage(UnitTypeId attackerId, UnitTypeId targetId) const
 {
     auto attackerMapIt = m_primaryWeaponDamage.find(attackerId);
     if (attackerMapIt != m_primaryWeaponDamage.end())
@@ -236,7 +237,8 @@ std::optional<int> Config::getUnitPrimaryWeaponDamage(UnitId attackerId, UnitId
     return std::nullopt;
 }
 
-std::optional<int> Config::getUnitSecondaryWeaponDamage(UnitId attackerId, UnitId targetId) const
+std::optional<int>
+Config::getUnitSecondaryWeaponDamage(UnitTypeId attackerId, UnitTypeId targetId) const
 {
     auto attackerMapIt = m_secondaryWeaponDamage.find(attackerId);
     if (attackerMapIt != m_secondaryWeaponDamage.end())
diff --git a/src/game/core/Config.hpp b/src/game/core/Config.hpp
index 136b068dde28115278965126880888aec3afee71..f9ba4897f75a26c8d1ab983bd56fb19412ee1b8f 100644
--- a/src/game/core/Config.hpp
+++ b/src/game/core/Config.hpp
@@ -9,7 +9,7 @@
 namespace advanced_wars
 {
 /* ENUMS FOR GLOBAL USE*/
-enum class BuildingFaction
+enum class Faction
 {
     URED = 0,
     UBLUE = 1,
@@ -27,16 +27,7 @@ enum class BuildingId
     PORT = 4,
 };
 
-enum class UnitFaction
-{
-    URED = 0,
-    UBLUE = 1,
-    UGREEN = 2,
-    UYELLOW = 3,
-    UPURPLE = 4,
-};
-
-enum class UnitId
+enum class UnitTypeId
 {
     INFANTERY = 0,
     MECHANIZED_INFANTERY = 1,
@@ -140,77 +131,79 @@ class Config
         Config(std::string filename);
 
         /** @brief Retrieves the cost of a given unit type. */
-        int getUnitCost(UnitId id) const;
+        int getUnitCost(UnitTypeId id) const;
 
         /** @brief Retrieves the movement points of a given unit type. */
-        int getUnitMovementPoints(UnitId id) const;
+        int getUnitMovementPoints(UnitTypeId id) const;
 
         /** @brief Retrieves the maximum ammunition capacity of a given unit type. */
-        int getUnitAmmo(UnitId id) const;
+        int getUnitAmmo(UnitTypeId id) const;
 
         /** @brief Retrieves the minimum attack range of a given unit type. */
-        int getUnitMinRange(UnitId id) const;
+        int getUnitMinRange(UnitTypeId id) const;
 
         /** @brief Retrieves the maximum attack range of a given unit type. */
-        int getUnitMaxRange(UnitId id) const;
+        int getUnitMaxRange(UnitTypeId id) const;
 
         /** @brief Retrieves the name of the primary weapon of a given unit type. */
-        std::string getUnitPrimaryWeapon(UnitId id) const;
+        std::string getUnitPrimaryWeapon(UnitTypeId id) const;
 
         /** @brief Retrieves the name of the secondary weapon of a given unit type. */
-        std::string getUnitSecondaryWeapon(UnitId id) const;
+        std::string getUnitSecondaryWeapon(UnitTypeId id) const;
 
         /** @brief Retrieves the damage value of a unit's primary weapon against a target unit type.
          */
-        std::optional<int> getUnitPrimaryWeaponDamage(UnitId attackerid, UnitId defenderid) const;
+        std::optional<int>
+        getUnitPrimaryWeaponDamage(UnitTypeId attackerid, UnitTypeId defenderid) const;
 
         /** @brief Retrieves the damage value of a unit's secondary weapon against a target unit
          * type. */
-        std::optional<int> getUnitSecondaryWeaponDamage(UnitId attackerid, UnitId defenderid) const;
+        std::optional<int>
+        getUnitSecondaryWeaponDamage(UnitTypeId attackerid, UnitTypeId defenderid) const;
 
         /** @brief Retrieves the movement type of a given unit type. */
-        MovementType getUnitMovementType(UnitId id) const;
+        MovementType getUnitMovementType(UnitTypeId id) const;
 
     private:
         /** @brief Maps unit IDs to their cost values. */
-        std::unordered_map<UnitId, int> m_unitCosts;
+        std::unordered_map<UnitTypeId, int> m_unitCosts;
 
         /** @brief Maps unit IDs to their movement points. */
-        std::unordered_map<UnitId, int> m_unitMovementPoints;
+        std::unordered_map<UnitTypeId, int> m_unitMovementPoints;
 
         /** @brief Maps unit IDs to their maximum ammunition capacity. */
-        std::unordered_map<UnitId, int> m_unitAmmo;
+        std::unordered_map<UnitTypeId, int> m_unitAmmo;
 
         /** @brief Maps unit IDs to their minimum attack range. */
-        std::unordered_map<UnitId, int> m_unitMinRange;
+        std::unordered_map<UnitTypeId, int> m_unitMinRange;
 
         /** @brief Maps unit IDs to their maximum attack range. */
-        std::unordered_map<UnitId, int> m_unitMaxRange;
+        std::unordered_map<UnitTypeId, int> m_unitMaxRange;
 
         /** @brief Maps unit IDs to their primary weapon names. */
-        std::unordered_map<UnitId, std::string> m_unitPrimaryWeapon;
+        std::unordered_map<UnitTypeId, std::string> m_unitPrimaryWeapon;
 
         /** @brief Maps unit IDs to their secondary weapon names. */
-        std::unordered_map<UnitId, std::string> m_unitSecondaryWeapon;
+        std::unordered_map<UnitTypeId, std::string> m_unitSecondaryWeapon;
 
         /** @brief Stores primary weapon damage values for attacker-defender unit combinations. */
-        std::unordered_map<UnitId, std::unordered_map<UnitId, int>> m_primaryWeaponDamage;
+        std::unordered_map<UnitTypeId, std::unordered_map<UnitTypeId, int>> m_primaryWeaponDamage;
 
         /** @brief Stores secondary weapon damage values for attacker-defender unit combinations. */
-        std::unordered_map<UnitId, std::unordered_map<UnitId, int>> m_secondaryWeaponDamage;
+        std::unordered_map<UnitTypeId, std::unordered_map<UnitTypeId, int>> m_secondaryWeaponDamage;
 
         /** @brief Maps unit IDs to their movement types. */
-        std::unordered_map<UnitId, MovementType> m_unitMovementType;
+        std::unordered_map<UnitTypeId, MovementType> m_unitMovementType;
 
         /**
-         * @brief Converts a unit key string from the XML file to its corresponding UnitId.
+         * @brief Converts a unit key string from the XML file to its corresponding UnitTypeId.
          *
-         * If the key is unknown, it returns UnitId::UNKNOWN.
+         * If the key is unknown, it returns UnitTypeId::UNKNOWN.
          *
          * @param unit_key The string key representing a unit type.
-         * @return The corresponding UnitId.
+         * @return The corresponding UnitTypeId.
          */
-        UnitId mapUnitKeyToID(const std::string& unit_key) const;
+        UnitTypeId mapUnitKeyToID(const std::string& unit_key) const;
 
         /**
          * @brief Converts a movement type string from the XML file to its corresponding
diff --git a/src/game/core/Engine.cpp b/src/game/core/Engine.cpp
index 6a5f74abcfa3a7b4fdbf3a59f4d6bc1fa224b2bf..8f8ab437c50f100084fd1effe2235d1102d35982 100644
--- a/src/game/core/Engine.cpp
+++ b/src/game/core/Engine.cpp
@@ -1,7 +1,9 @@
 #include "Engine.hpp"
+#include "GameManager.hpp"
 #include "Scene.hpp"
 #include "Spritesheet.hpp"
 #include "Window.hpp"
+#include <iostream>
 
 #include <SDL.h>
 #include <SDL_events.h>
@@ -16,7 +18,9 @@
 namespace advanced_wars
 {
 
-Engine::Engine(Window& window) : m_window(window), m_quit(false), m_unitConfig("../config.xml")
+Engine::Engine(Window& window)
+    : m_window(window), m_quit(false), m_unitConfig("../config.xml"),
+      m_gameManager(std::make_unique<GameManager>())
 {
 
     this->m_SDLRenderer = SDL_CreateRenderer(
@@ -132,6 +136,16 @@ SDL_Renderer* Engine::renderer()
     return this->m_SDLRenderer;
 }
 
+void Engine::startGame(const std::string& levelPath)
+{
+    m_gameManager->startGame(*this, levelPath);
+}
+
+Window& Engine::getWindow()
+{
+    return this->m_window;
+}
+
 Engine::~Engine()
 {
     SDL_DestroyRenderer(m_SDLRenderer);
diff --git a/src/game/core/Engine.hpp b/src/game/core/Engine.hpp
index 0325473153ca3ec6ee1dd757f3be6d14831b36df..370e495e885de42b5d6d98ed773b8ed87af3d2ae 100644
--- a/src/game/core/Engine.hpp
+++ b/src/game/core/Engine.hpp
@@ -16,6 +16,7 @@ namespace advanced_wars
 {
 
 // Forward declaration
+class GameManager;
 class Scene;
 class Config;
 
@@ -56,6 +57,10 @@ class Engine
 
         SDL_Renderer* renderer();
 
+        void startGame(const std::string& levelPath);
+
+        Window& getWindow();
+
         ~Engine();
 
     private:
@@ -68,7 +73,8 @@ class Engine
         bool m_quit;
         int  m_stage;
 
-        Config m_unitConfig;
+        Config                       m_unitConfig;
+        std::unique_ptr<GameManager> m_gameManager;
 };
 
 } // namespace advanced_wars
diff --git a/src/game/core/GameManager.cpp b/src/game/core/GameManager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dda9b65d76bfcb78b9adcd3887061649181a5f3c
--- /dev/null
+++ b/src/game/core/GameManager.cpp
@@ -0,0 +1,22 @@
+#include "GameManager.hpp"
+#include <iostream>
+#include <memory>
+
+namespace advanced_wars
+{
+
+void GameManager::startGame(Engine& engine, const std::string& levelFilePath)
+{
+    std::cout << "Starting game with level file: " << levelFilePath << "\n";
+    std::unique_ptr<Level> level = std::make_unique<Level>(levelFilePath, engine);
+    m_currentLevel = std::move(level);
+    engine.pushScene(m_currentLevel);
+}
+
+void GameManager::returnToMenu(Engine& engine)
+{
+    m_currentLevel.reset();
+    engine.returnToMenu();
+}
+
+} // namespace advanced_wars
diff --git a/src/game/core/GameManager.hpp b/src/game/core/GameManager.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..c27334523740933e603dd85d83f9e97542d58300
--- /dev/null
+++ b/src/game/core/GameManager.hpp
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "../level/Level.hpp"
+#include "Engine.hpp"
+
+#include <memory>
+#include <string>
+
+namespace advanced_wars
+{
+
+class GameManager
+{
+    public:
+        GameManager() = default;
+        ~GameManager() = default;
+
+        void startGame(Engine& engine, const std::string& levelFilePath);
+        void returnToMenu(Engine& engine);
+
+    private:
+        std::shared_ptr<Level> m_currentLevel;
+};
+
+} // namespace advanced_wars
diff --git a/src/game/core/Spritesheet.cpp b/src/game/core/Spritesheet.cpp
index 70c8edb01ce5526545454b8e3cca0ddb364a285b..997b7766e8ab83f31ccf8fa7312a0bfb96f0d7e1 100644
--- a/src/game/core/Spritesheet.cpp
+++ b/src/game/core/Spritesheet.cpp
@@ -396,6 +396,47 @@ Spritesheet::Spritesheet(std::string path, Engine& engine)
     this->m_numberTextures = tmp;
     this->m_numberWidth = 8;
     this->m_numberHeight = 8;
+
+    // Bullet
+    HighFive::DataSet bulletDs = file.getDataSet("/misc/bullet");
+
+    std::vector<std::vector<uint32_t>> bulletFrames;
+    bulletDs.read(bulletFrames);
+
+    std::vector<uint32_t> bulletBuffer(8 * 8, 0);
+
+    // every animation frame
+
+    for (size_t y = 0; y < 8; y++)
+    {
+        for (size_t x = 0; x < 8; x++)
+        {
+            size_t index = (y * 8) + x;
+
+            number_buffer.at(index) = bulletFrames.at(8 - y - 1).at(x);
+        }
+    }
+
+    SDL_Texture* bulletTmp = SDL_CreateTexture(
+        engine.renderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC, 8, 8);
+
+    SDL_SetTextureBlendMode(bulletTmp, SDL_BLENDMODE_BLEND);
+
+    if (bulletTmp == nullptr)
+    {
+        throw std::runtime_error(
+            "Fehler beim Erstellen der Textur für die Effects: " + std::string(SDL_GetError()));
+    }
+
+    if (SDL_UpdateTexture(bulletTmp, NULL, number_buffer.data(), 8 * sizeof(int32_t)) != 0)
+    {
+        throw std::runtime_error(
+            "Fehler beim updaten der Textur für die Tiles: " + std::string(SDL_GetError()));
+    }
+
+    this->m_bulletTexture = bulletTmp;
+    this->m_bulletWidth = 8;
+    this->m_bulletHeight = 8;
 }
 
 // Tiles
@@ -489,6 +530,22 @@ SDL_Texture* Spritesheet::getNumberTexture()
     return this->m_numberTextures;
 }
 
+// Bullet
+SDL_Texture* Spritesheet::getBulletTexture()
+{
+    return this->m_bulletTexture;
+}
+
+int Spritesheet::getBulletWidth()
+{
+    return this->m_bulletWidth;
+}
+
+int Spritesheet::getBulletHeight()
+{
+    return this->m_bulletHeight;
+}
+
 Spritesheet::~Spritesheet()
 {
     for (std::pair<SDL_Texture*, int> tile_texture : m_tileTextures)
@@ -518,6 +575,8 @@ Spritesheet::~Spritesheet()
     }
 
     SDL_DestroyTexture(m_numberTextures);
+
+    SDL_DestroyTexture(m_bulletTexture);
 }
 
 } // namespace advanced_wars
diff --git a/src/game/core/Spritesheet.hpp b/src/game/core/Spritesheet.hpp
index 00c84a2a6e60b596b412269e755e694242337270..e3c5e870f1067371bb3019ee8bf0afe1d2d9d6f4 100644
--- a/src/game/core/Spritesheet.hpp
+++ b/src/game/core/Spritesheet.hpp
@@ -116,7 +116,7 @@ class Spritesheet
         /**
          * Gets the hierarchical vector of all unit textures.
          *
-         * The vector groups the faction, the UnitId and the state for each unit.
+         * The vector groups the faction, the UnitTypeId and the state for each unit.
          * The pair consist of the texture for that combination and the number of animation steps.
          *
          * E.g. A red faction(0) Recon(2) Unit that's unavailable(1) would be at [0][2][1].
@@ -173,6 +173,25 @@ class Spritesheet
          */
         SDL_Texture* getNumberTexture();
 
+        // Bullet
+        /**
+         * @return The width of a bullet in pixels
+         */
+        int getBulletWidth();
+
+        /**
+         * @return The height of an bullet in pixels
+         */
+        int getBulletHeight();
+
+        /**
+         * The texture represents the bullet texture.
+         *
+         * @return Bullet texture
+         */
+
+        SDL_Texture* getBulletTexture();
+
     private:
         // Tiles
         std::vector<std::pair<SDL_Texture*, int>> m_tileTextures;
@@ -205,5 +224,11 @@ class Spritesheet
 
         int m_numberWidth;
         int m_numberHeight;
+
+        // Bullet
+        SDL_Texture* m_bulletTexture;
+
+        int m_bulletWidth;
+        int m_bulletHeight;
 };
 } // namespace advanced_wars
diff --git a/src/game/entities/Building.cpp b/src/game/entities/Building.cpp
index 3052460396dd5495cd1173234d88d59aab094814..cfe72cb65c8f4f7be1de0188ab13b482ac82de8a 100644
--- a/src/game/entities/Building.cpp
+++ b/src/game/entities/Building.cpp
@@ -1,12 +1,13 @@
 #include "Building.hpp"
 #include "../core/Spritesheet.hpp"
 
+#include <algorithm>
 #include <iostream>
 
 namespace advanced_wars
 {
 
-Building::Building(int x, int y, BuildingId id, BuildingFaction faction)
+Building::Building(int x, int y, BuildingId id, Faction faction)
     : m_x(x), m_y(y), m_id(id), m_faction(faction) {};
 
 void Building::render(Engine& engine, int scale)
@@ -30,12 +31,12 @@ void Building::render(Engine& engine, int scale)
         &dst, 0, NULL, SDL_FLIP_NONE);
 }
 
-BuildingFaction Building::getFaction()
+Faction Building::getFaction()
 {
     return this->m_faction;
 }
 
-bool Building::switch_faction(BuildingFaction faction)
+bool Building::switch_faction(Faction faction)
 {
 
     this->m_faction = faction;
@@ -50,16 +51,16 @@ bool Building::switch_faction(BuildingFaction faction)
 // implement call to UI to show available units
 void Building::on_click()
 {
-    std::cout << "A building is selected!" << std::endl;
+    std::cout << "A building is selected!" << "\n";
 };
 
-bool Building::check_spawn(std::unordered_map<int, advanced_wars::Unit>& units)
+bool Building::check_spawn(std::unordered_map<int, std::unique_ptr<Unit>>& units)
 {
-
     for (auto& [id, unit] : units)
     {
-        if (unit.getXPosition() == this->getXPosition() &&
-            unit.getYPosition() == this->getYPosition())
+        Unit& unitRef = *unit;
+        if (unitRef.getXPosition() == this->getXPosition() &&
+            unitRef.getYPosition() == this->getYPosition())
         {
             return false;
         }
@@ -74,35 +75,36 @@ bool Building::check_money(int price, int playerMoney)
     return (playerMoney >= price);
 }
 
-std::vector<UnitId> Building::recruitableUnits()
+std::vector<UnitTypeId> Building::recruitableUnits()
 {
 
     if (this->m_id == BuildingId::FACTORY)
     {
         return {
-            UnitId::INFANTERY,
-            UnitId::MECHANIZED_INFANTERY,
-            UnitId::RECON,
-            UnitId::APC,
-            UnitId::ARTILLERY,
-            UnitId::ANTI_AIR_TANK,
-            UnitId::ANTI_AIR_MISSILE_LAUNCHER,
-            UnitId::ROCKET_ARTILLERY,
-            UnitId::MEDIUM_TANK,
-            UnitId::NEO_TANK,
-            UnitId::HEAVY_TANK};
+            UnitTypeId::INFANTERY,
+            UnitTypeId::MECHANIZED_INFANTERY,
+            UnitTypeId::RECON,
+            UnitTypeId::APC,
+            UnitTypeId::ARTILLERY,
+            UnitTypeId::ANTI_AIR_TANK,
+            UnitTypeId::ANTI_AIR_MISSILE_LAUNCHER,
+            UnitTypeId::ROCKET_ARTILLERY,
+            UnitTypeId::MEDIUM_TANK,
+            UnitTypeId::NEO_TANK,
+            UnitTypeId::HEAVY_TANK};
     }
 
     if (this->m_id == BuildingId::PORT)
     {
-        return {UnitId::LANDER, UnitId::CRUISER, UnitId::SUBMARINE, UnitId::BATTLESHIP};
+        return {
+            UnitTypeId::LANDER, UnitTypeId::CRUISER, UnitTypeId::SUBMARINE, UnitTypeId::BATTLESHIP};
     }
 
     if (this->m_id == BuildingId::AIRPORT)
     {
         return {
-            UnitId::TRANSPORT_HELICOPTER, UnitId::BATTLE_HELICOPTER, UnitId::FIGHTER,
-            UnitId::BOMBER};
+            UnitTypeId::TRANSPORT_HELICOPTER, UnitTypeId::BATTLE_HELICOPTER, UnitTypeId::FIGHTER,
+            UnitTypeId::BOMBER};
     }
 
     return {};
diff --git a/src/game/entities/Building.hpp b/src/game/entities/Building.hpp
index e7608a43a9f893b08c6eb25357d3c9e3549cd8e0..68f2cb5249268e2f1a9f3a8f0035ae976649fef2 100644
--- a/src/game/entities/Building.hpp
+++ b/src/game/entities/Building.hpp
@@ -12,7 +12,7 @@ namespace advanced_wars
 class Building
 {
     public:
-        Building(int x, int y, BuildingId id, BuildingFaction faction);
+        Building(int x, int y, BuildingId id, Faction faction);
 
         void render(Engine& engine, int scale);
 
@@ -20,7 +20,7 @@ class Building
 
         int getYPosition();
 
-        BuildingFaction getFaction();
+        Faction getFaction();
 
         BuildingId getId();
 
@@ -31,12 +31,12 @@ class Building
 
         @return true if building was a headquarter
         */
-        bool switch_faction(BuildingFaction faction);
+        bool switch_faction(Faction faction);
 
         /*
         checks if the tile ontop of the building is free
         */
-        bool check_spawn(std::unordered_map<int, advanced_wars::Unit>& units);
+        bool check_spawn(std::unordered_map<int, std::unique_ptr<Unit>>& units);
 
         /*
         checks if the player has enough money for the unit to be recruited
@@ -53,13 +53,13 @@ class Building
          * Provides a vector of recruitable units, depending on the building id
          *
          */
-        std::vector<UnitId> recruitableUnits();
+        std::vector<UnitTypeId> recruitableUnits();
 
     private:
-        int             m_x;
-        int             m_y;
-        BuildingId      m_id;
-        BuildingFaction m_faction;
+        int        m_x;
+        int        m_y;
+        BuildingId m_id;
+        Faction    m_faction;
 };
 
 } // namespace advanced_wars
diff --git a/src/game/entities/Bullet.cpp b/src/game/entities/Bullet.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..737ac546c77f830f3a20b6bccad5b0b43dad9b66
--- /dev/null
+++ b/src/game/entities/Bullet.cpp
@@ -0,0 +1,108 @@
+#include "Bullet.hpp"
+#include "../core/Engine.hpp"
+#include "../physics/PhysicsBody.hpp"
+#include "../physics/PhysicsEngine.hpp"
+#include "box2d/b2_settings.h"
+#include <iostream>
+#include <stdexcept>
+
+namespace advanced_wars
+{
+
+Bullet::Bullet(
+    b2World* world, float startX, float startY, float velocityX, float velocityY, Unit& target)
+    : m_renderX(0), m_renderY(0), m_target(target)
+{
+    // Erstelle einen PhysicsBody für die Bullet
+    m_physicsBody = std::make_unique<PhysicsBody>(
+        world, startX, startY, 4.0F, 4.0F, 1.0, 0.3, true, BodyType::PROJECTILE);
+
+    if (m_physicsBody && m_physicsBody->getBody())
+    {
+        BodyUserData* bud = new BodyUserData();
+        bud->type = BodyUserData::Type::Bullet;
+        bud->id = target.getUnitId();
+        bud->data = this;
+
+        m_physicsBody->getBody()->GetUserData().pointer = reinterpret_cast<uintptr_t>(bud);
+    }
+    m_physicsBody->setVelocity({velocityX, velocityY});
+}
+
+Bullet::~Bullet()
+{
+    // Der PhysicsBody wird automatisch durch `unique_ptr` zerstört.
+}
+
+void Bullet::update()
+{
+    if (!m_physicsBody)
+    {
+        return;
+    }
+
+    // if (m_destroyFlag)
+    // {
+    //     destroy();
+    //     return;
+    // }
+
+    b2Vec2 velocity = m_physicsBody->getVelocity();
+    b2Vec2 pos = m_physicsBody->getPosition();
+
+    if (pos.x == 0 && pos.y == 0)
+    {
+        std::cerr << "❌ WARNUNG: Bullet-Position ist (0,0)!\n";
+    }
+
+    m_renderX = pos.x * 16 + (8 / 2);
+    m_renderY = pos.y * 16 + (8 / 2);
+
+    m_rotation = std::atan2(velocity.y, velocity.x) * 180.0F / M_PI;
+}
+
+void Bullet::render(Engine& engine, int scale)
+{
+    // Falls die Textur noch nicht gesetzt wurde, laden wir sie jetzt
+    if (!m_texture)
+    {
+        Spritesheet* spritesheet = engine.getSpritesheet();
+        m_texture = spritesheet->getBulletTexture(); // Textur aus HDF5-File laden
+        m_width = spritesheet->getBulletWidth();
+        m_height = spritesheet->getBulletHeight();
+    }
+
+    // Ziel-Rect setzen (angepasst für Skalierung)
+    SDL_Rect destRect = {
+        static_cast<int>(m_renderX * scale), static_cast<int>(m_renderY * scale), m_width * scale,
+        m_height * scale};
+
+    SDL_Point center = {m_width * scale / 2, m_height * scale / 2};
+
+    // Textur rendern
+    SDL_RenderCopyEx(
+        engine.renderer(), m_texture, nullptr, &destRect, m_rotation, &center, SDL_FLIP_NONE);
+}
+
+void Bullet::destroy()
+{
+    if (m_physicsBody)
+    {
+        m_physicsBody->getBody()->GetUserData().pointer = 0;
+        m_physicsBody->destroy();
+        m_physicsBody.reset();
+    }
+    m_destroyFlag = true;
+}
+
+PhysicsBody& Bullet::getBody() const
+{
+    return *m_physicsBody;
+}
+
+void Bullet::setDestroyFlag(bool flag)
+{
+    m_destroyFlag = flag;
+}
+
+} // namespace advanced_wars
diff --git a/src/game/entities/Bullet.hpp b/src/game/entities/Bullet.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..41a8de96cc1d91ccb13ab5b5e757412e2ad9116c
--- /dev/null
+++ b/src/game/entities/Bullet.hpp
@@ -0,0 +1,60 @@
+#pragma once
+
+#include "../core/Engine.hpp"
+#include "../entities/Unit.hpp"
+#include "../physics/PhysicsBody.hpp"
+#include <SDL.h>
+#include <box2d/box2d.h>
+
+namespace advanced_wars
+{
+
+class Bullet
+{
+    public:
+        /**
+         * Erzeugt eine neue Bullet.
+         *
+         * @param world     Pointer auf die Box2D-Welt, in der der Body angelegt wird.
+         * @param startX    Startposition X in Pixeln.
+         * @param startY    Startposition Y in Pixeln.
+         * @param velocityX Anfangsgeschwindigkeit X (in m/s, Box2D-Einheiten).
+         * @param velocityY Anfangsgeschwindigkeit Y (in m/s, Box2D-Einheiten).
+         */
+        Bullet(
+            b2World* world, float startX, float startY, float velocityX, float velocityY,
+            Unit& target);
+
+        ~Bullet();
+
+        /// Update: Liest die Position des Box2D-Bodies und bereitet die Renderkoordinaten vor.
+        void update();
+
+        /// Rendert die Bullet mit SDL.
+        void render(Engine& engine, int scale);
+
+        /// Gibt den Box2D-Body zurück (nützlich z.B. für Kollisionsbehandlung)
+        PhysicsBody& getBody() const;
+
+        void destroy();
+
+        void setDestroyFlag(bool flag);
+
+        bool shouldDestroy() const { return m_destroyFlag; }
+
+        Unit& getTarget() { return m_target; }
+
+    private:
+        std::unique_ptr<PhysicsBody> m_physicsBody;
+        SDL_Texture*                 m_texture = nullptr;
+        int                          m_width = 0;
+        int                          m_height = 0;
+        double                       m_rotation = 0;
+        bool                         m_destroyFlag = false;
+        Unit&                        m_target;
+
+        // Gerenderte Position in Pixeln (berechnet aus der Box2D-Position)
+        float m_renderX = 0;
+        float m_renderY = 0;
+};
+} // namespace advanced_wars
diff --git a/src/game/entities/Unit.cpp b/src/game/entities/Unit.cpp
index 580e1819a8f634550254fa6cff0761669e403b22..3977ae8a926b234f02b776678d9c34f62b0276fc 100644
--- a/src/game/entities/Unit.cpp
+++ b/src/game/entities/Unit.cpp
@@ -1,284 +1,161 @@
 #include "Unit.hpp"
 #include "../core/Config.hpp"
+#include "../physics/PhysicsBody.hpp"
+#include "../physics/PhysicsEngine.hpp"
+#include "box2d/box2d.h"
 
 #include <iostream>
+#include <memory>
 
 namespace advanced_wars
 {
 
-Unit::Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state, Config& config)
-    : m_x(x), m_y(y), m_faction(faction), m_id(id), m_state(state), m_maxHealth(100)
+Unit::Unit(
+    int unitId, b2World* world, int tileX, int tileY, Faction faction, UnitTypeId unitTypeId,
+    UnitState state, Config& config)
+    : m_unitId(unitId), m_tileX(tileX), m_tileY(tileY), m_health(100),
+      m_cost(config.getUnitCost(unitTypeId)), m_ammo(config.getUnitAmmo(unitTypeId)),
+      m_minRange(config.getUnitMinRange(unitTypeId)),
+      m_maxRange(config.getUnitMaxRange(unitTypeId)), m_maxHealth(100),
+      m_movementPoints(config.getUnitMovementPoints(unitTypeId)),
+      m_movementType(config.getUnitMovementType(unitTypeId)), m_faction(faction),
+      m_unitTypeId(unitTypeId), m_state(state), m_world(world), m_animX(tileX), m_animY(tileY)
 {
-    // Allgemeine Einheiteneinstellungen aus Konfiguration holen
-    m_cost = config.getUnitCost(id);
-    m_movementPoints = config.getUnitMovementPoints(id);
-    m_ammo = config.getUnitAmmo(id);
-    m_minRange = config.getUnitMinRange(id);
-    m_maxRange = config.getUnitMaxRange(id);
-    m_health = m_maxHealth;
+    m_physicsBody = std::make_unique<PhysicsBody>(
+        m_world, tileX, tileY, 8.0F, 8.0F, 1.0, 0.3, true, BodyType::UNIT);
 
-    m_movementType = config.getUnitMovementType(id);
+    if (m_physicsBody && m_physicsBody->getBody())
+    {
+        BodyUserData* bud = new BodyUserData();
+        bud->type = BodyUserData::Type::Unit;
+        bud->id = m_unitId;
+        bud->data = this;
+
+        m_physicsBody->getBody()->GetUserData().pointer = reinterpret_cast<uintptr_t>(bud);
+    }
 
     // Initialisieren der Primär- und Sekundärwaffe
-    std::unordered_map<UnitId, int> primaryDamage;
-    std::unordered_map<UnitId, int> secondaryDamage;
+    std::unordered_map<UnitTypeId, int> primaryDamage;
+    std::unordered_map<UnitTypeId, int> secondaryDamage;
 
-    for (int targetIt = static_cast<int>(UnitId::FIRST); targetIt <= static_cast<int>(UnitId::LAST);
-         ++targetIt)
+    for (int targetIt = static_cast<int>(UnitTypeId::FIRST);
+         targetIt <= static_cast<int>(UnitTypeId::LAST); ++targetIt)
     {
-        UnitId targetId = static_cast<UnitId>(targetIt);
+        auto targetId = static_cast<UnitTypeId>(targetIt);
 
-        // Prüfen, ob ein gültiger Schadenswert vorhanden ist, und nur dann hinzufügen
-        if (auto damage = config.getUnitPrimaryWeaponDamage(id, targetId))
+        if (auto damage = config.getUnitPrimaryWeaponDamage(m_unitTypeId, targetId))
         {
             primaryDamage[targetId] = *damage;
         }
-        if (auto damage = config.getUnitSecondaryWeaponDamage(id, targetId))
+        if (auto damage = config.getUnitSecondaryWeaponDamage(m_unitTypeId, targetId))
         {
             secondaryDamage[targetId] = *damage;
         }
     }
 
-    m_primaryWeapon = Weapon(config.getUnitPrimaryWeapon(id), primaryDamage);
-    m_secondaryWeapon = Weapon(config.getUnitSecondaryWeapon(id), secondaryDamage);
+    m_primaryWeapon =
+        std::make_unique<Weapon>(Weapon(config.getUnitPrimaryWeapon(m_unitTypeId), primaryDamage));
+    m_secondaryWeapon = std::make_unique<Weapon>(
+        Weapon(config.getUnitSecondaryWeapon(m_unitTypeId), secondaryDamage));
 }
 
-void Unit::render(Engine& engine, int scale)
+void Unit::update(float deltaTime)
 {
-    Spritesheet* spritesheet = engine.getSpritesheet();
-
-    int step = engine.getStage() % spritesheet->getUnitTextures()
-                                       .at(static_cast<int>(m_faction))
-                                       .at(static_cast<int>(m_id))
-                                       .at(static_cast<int>(m_state))
-                                       .second;
-
-    if (m_state == UnitState::IDLE || m_state == UnitState::UNAVAILABLE)
-    {
-
-        SDL_Rect src;
-        src.x = step * spritesheet->getUnitWidth();
-        src.y = 0;
-        src.w = spritesheet->getUnitWidth();
-        src.h = spritesheet->getUnitHeight();
-
-        SDL_Rect dst;
-        dst.x = m_x * spritesheet->getUnitWidth() * scale;
-        dst.y = m_y * spritesheet->getUnitHeight() * scale;
-        dst.w = spritesheet->getUnitWidth() * scale;
-        dst.h = spritesheet->getUnitHeight() * scale;
-
-        SDL_RenderCopyEx(
-            engine.renderer(),
-            spritesheet->getUnitTextures()
-                .at(static_cast<int>(m_faction))
-                .at(static_cast<int>(m_id))
-                .at(static_cast<int>(m_state))
-                .first,
-            &src, &dst, 0, NULL, SDL_FLIP_NONE);
-    }
-    else
+    if (!m_physicsBody)
     {
-        // The moving states have a resolution of 24x24 instead of 16x16 and need to
-        // be handled separately
-        SDL_Rect src;
-        src.x = step * spritesheet->getUnitMovingWidth();
-        src.y = 0;
-        src.w = spritesheet->getUnitMovingWidth();
-        src.h = spritesheet->getUnitMovingHeight();
-
-        SDL_Rect dst;
-        dst.x = ((m_x * spritesheet->getUnitWidth()) - 4) * scale;
-        dst.y = ((m_y * spritesheet->getUnitHeight()) - 8) * scale;
-        dst.w = spritesheet->getUnitMovingWidth() * scale;
-        dst.h = spritesheet->getUnitMovingHeight() * scale;
-
-        SDL_RenderCopyEx(
-            engine.renderer(),
-            spritesheet->getUnitTextures()
-                .at(static_cast<int>(m_faction))
-                .at(static_cast<int>(m_id))
-                .at(static_cast<int>(m_state))
-                .first,
-            &src, &dst, 0, NULL, SDL_FLIP_NONE);
+        return;
     }
-    renderHP(engine, scale);
-}
-
-void Unit::attack(Unit& enemy)
-{
-    int attacker_damage_value = calculateDamage(enemy);
 
-    if (attacker_damage_value > 0)
-    {
-        performAttack(enemy, attacker_damage_value);
-        std::cout << "Enemy health after attack: " << enemy.m_health << std::endl;
+    m_physicsBody->update(deltaTime);
 
-        // Check if the enemy is still alive for counter-attack
-        if (enemy.m_health > 0)
-        {
-            // Check if the enemy is within attack range
-            int distanceX = std::abs(enemy.m_x - m_x);
-            int distanceY = std::abs(enemy.m_y - m_y);
-            int distance = distanceX + distanceY;
-
-            if (distance >= enemy.m_minRange && distance <= enemy.m_maxRange)
-            {
-                // Now, they are reversed for the counter-attack
-                int defender_damage_value = enemy.calculateDamage(*this);
-                if (defender_damage_value > 0)
-                {
-                    enemy.performAttack(*this, defender_damage_value);
-                    std::cout << "Ally health after retaliation: " << this->m_health << std::endl;
-                }
-            }
-            else
-            {
-                std::cout << "Enemy out of range for counter-attack." << std::endl;
-            }
-        }
-    }
-    else
-    {
-        std::cout << "No damage value found for attack from unit " << static_cast<int>(m_id)
-                  << " against unit " << static_cast<int>(enemy.m_id) << std::endl;
-    }
+    b2Vec2 pos = m_physicsBody->getPosition();
+    calcState(static_cast<int>(pos.x), static_cast<int>(pos.y));
+    m_animX = static_cast<int>(pos.x);
+    m_animY = static_cast<int>(pos.y);
 }
 
-int Unit::calculateDamage(Unit& target)
+void Unit::moveTo(int posX, int posY)
 {
-    // Pointers to Weapon objects
-    Weapon* primaryWeapon = &m_primaryWeapon;
-    Weapon* secondaryWeapon = &m_secondaryWeapon;
-
-    // Find the corresponding damage values
-    auto primary_damage_it = primaryWeapon->getDamage().find(target.m_id);
-    auto secondary_damage_it = secondaryWeapon->getDamage().find(target.m_id);
-
-    int damage_value = 0;
-
-    // Calculate damage using secondary weapon if available
-    if (secondary_damage_it != secondaryWeapon->getDamage().end())
+    if (!m_physicsBody)
     {
-        damage_value = secondary_damage_it->second;
-    }
-
-    // Calculate damage using primary weapon if higher and ammo is available
-    if (primary_damage_it != primaryWeapon->getDamage().end())
-    {
-        // Check ammo correctly
-        int& ammo = m_ammo;
-
-        if (primary_damage_it->second > damage_value && ammo > 0)
-        {
-            ammo -= 1;
-            damage_value = primary_damage_it->second;
-            std::cout << " ammo = " << ammo << std::endl;
-        }
+        return;
     }
 
-    return damage_value;
-}
-
-void Unit::performAttack(Unit& target, int damage)
-{
-    int effective_damage = damage * (static_cast<float>(m_health) / m_maxHealth);
-    target.m_health -= effective_damage;
-    target.m_health = std::max(0, target.m_health);
-}
-
-void Unit::updatePosition(int posX, int posY)
-{
+    m_physicsBody->setTargetPosition(posX, posY);
     calcState(posX, posY);
-
-    this->m_x = posX;
-    this->m_y = posY;
+    m_tileX = posX;
+    m_tileY = posY;
 }
 
 void Unit::calcState(int posX, int posY)
 {
-    int deltaX = this->m_x - posX;
-    int deltaY = this->m_y - posY;
+    int deltaX = this->m_animX - posX;
+    int deltaY = this->m_animY - posY;
 
     if (deltaX == 0 && deltaY == 0)
     {
-        // Unit is already at the target position
+        if (m_hasMoved)
+        {
+            m_state = UnitState::UNAVAILABLE;
+        }
         return;
     }
 
     if (abs(deltaX) >= abs(deltaY))
     {
-        if (deltaX > 0)
-        {
-            this->m_state = advanced_wars::UnitState::MOVEMENTLEFT;
-        }
-        else
-        {
-            this->m_state = advanced_wars::UnitState::MOVEMENTRIGHT;
-        }
+        this->m_state = (deltaX > 0) ? UnitState::MOVEMENTLEFT : UnitState::MOVEMENTRIGHT;
     }
     else
     {
-        if (deltaY > 0)
-        {
-            this->m_state = advanced_wars::UnitState::MOVEMENTUP;
-        }
-        else
-        {
-            this->m_state = advanced_wars::UnitState::MOVEMENTDOWN;
-        }
+        this->m_state = (deltaY > 0) ? UnitState::MOVEMENTUP : UnitState::MOVEMENTDOWN;
     }
 }
 
-void Unit::on_left_click(SDL_Event event)
+void Unit::render(Engine& engine, int scale)
 {
+    Spritesheet* spritesheet = engine.getSpritesheet();
 
-    std::cout << "Left-button pressed on unit: " << this->m_health << std::endl;
-}
-
-std::vector<Unit*> Unit::getUnitsInRangeWithDamagePotential(const std::vector<Unit*>& allUnits)
-{
-    std::vector<Unit*> unitsInRangeWithDamage;
+    int step = engine.getStage() % spritesheet->getUnitTextures()
+                                       .at(static_cast<int>(m_faction))
+                                       .at(static_cast<int>(m_unitTypeId))
+                                       .at(static_cast<int>(m_state))
+                                       .second;
 
-    for (Unit* unit : allUnits)
-    { // Iterate over all units
-        // except itself
-        if (unit->getFaction() == this->m_faction)
-        {
-            continue;
-        }
+    SDL_Rect src, dst;
+    if (m_state == UnitState::IDLE || m_state == UnitState::UNAVAILABLE)
+    {
+        src.x = step * spritesheet->getUnitWidth();
+        src.y = 0;
+        src.w = spritesheet->getUnitWidth();
+        src.h = spritesheet->getUnitHeight();
 
-        int distanceX = std::abs(unit->m_x - m_x);
-        int distanceY = std::abs(unit->m_y - m_y);
+        dst.x = m_animX * spritesheet->getUnitWidth() * scale;
+        dst.y = m_animY * spritesheet->getUnitHeight() * scale;
+        dst.w = spritesheet->getUnitWidth() * scale;
+        dst.h = spritesheet->getUnitHeight() * scale;
+    }
+    else
+    {
+        src.x = step * spritesheet->getUnitMovingWidth();
+        src.y = 0;
+        src.w = spritesheet->getUnitMovingWidth();
+        src.h = spritesheet->getUnitMovingHeight();
 
-        int distance = distanceX + distanceY;
-        if (distance >= m_minRange && distance <= m_maxRange)
-        {
-            // Prüfen ob Schaden möglich ist
-            auto primaryDamageIt = m_primaryWeapon.getDamage().find(unit->m_id);
-            auto secondaryDamageIt = m_secondaryWeapon.getDamage().find(unit->m_id);
-
-            bool canDealDamage = false;
-
-            // Prüfen, ob Primärwaffe Schaden machen kann
-            if (primaryDamageIt != m_primaryWeapon.getDamage().end() && m_ammo > 0)
-            {
-                canDealDamage = true;
-            }
-            // Prüfen, ob Sekundärwaffe Schaden machen kann
-            if (secondaryDamageIt != m_secondaryWeapon.getDamage().end())
-            {
-                canDealDamage = true;
-            }
-
-            if (canDealDamage)
-            {
-                unitsInRangeWithDamage.push_back(unit);
-            }
-        }
+        dst.x = ((m_animX * spritesheet->getUnitWidth()) - 4) * scale;
+        dst.y = ((m_animY * spritesheet->getUnitHeight()) - 8) * scale;
+        dst.w = spritesheet->getUnitMovingWidth() * scale;
+        dst.h = spritesheet->getUnitMovingHeight() * scale;
     }
+    SDL_RenderCopyEx(
+        engine.renderer(),
+        spritesheet->getUnitTextures()
+            .at(static_cast<int>(m_faction))
+            .at(static_cast<int>(m_unitTypeId))
+            .at(static_cast<int>(m_state))
+            .first,
+        &src, &dst, 0, nullptr, SDL_FLIP_NONE);
 
-    return unitsInRangeWithDamage;
+    renderHP(engine, scale);
 }
 
 void Unit::renderHP(Engine& engine, int scale)
@@ -289,69 +166,39 @@ void Unit::renderHP(Engine& engine, int scale)
     int          numberWidth = spritesheet->getNumberWidth();
     int          numberHeight = spritesheet->getNumberHeight();
 
-    int hp = ceil((double)m_health / 10);
+    int unitHp = ceil((double)m_health / 10);
 
-    SDL_Rect src;
-    src.x = hp % 10 * numberWidth;
+    SDL_Rect src, dest;
+    src.x = unitHp % 10 * numberWidth;
     src.y = 0;
     src.w = numberWidth;
     src.h = numberHeight;
 
-    SDL_Rect dest;
-    dest.x = (m_x * spritesheet->getTileWidth() + 8) * scale;
-    dest.y = (m_y * spritesheet->getTileHeight() + 12) * scale;
+    dest.x = (m_animX * spritesheet->getTileWidth() + 8) * scale;
+    dest.y = (m_animY * spritesheet->getTileHeight() + 12) * scale;
     dest.w = numberWidth * scale;
     dest.h = numberHeight * scale;
 
     SDL_RenderCopy(engine.renderer(), numbers, &src, &dest);
 
-    if (hp == 10)
+    if (unitHp == 10)
     {
         src.x = 8;
-
-        dest.x = (m_x * spritesheet->getTileWidth() + 1) * scale;
-
+        dest.x = (m_animX * spritesheet->getTileWidth() + 1) * scale;
         SDL_RenderCopy(engine.renderer(), numbers, &src, &dest);
     }
 }
 
-UnitFaction Unit::getFaction()
-{
-    return this->m_faction;
-}
-
-void Unit::setState(UnitState state)
-{
-    this->m_state = state;
-}
-
-bool Unit::hasAttacked()
+void Unit::destroyBody()
 {
-    return this->m_hasAttacked;
-}
-
-bool Unit::hasMoved()
-{
-    return this->m_hasMoved;
-}
-
-int Unit::getXPosition()
-{
-    return m_x;
-}
-
-int Unit::getYPosition()
-{
-    return m_y;
+    if (m_physicsBody)
+    {
+        m_physicsBody->getBody()->GetUserData().pointer = 0;
+        m_physicsBody->destroy();
+        m_physicsBody.reset();
+    }
 }
 
-int Unit::getMovementPoints()
-{
-    return m_movementPoints;
-}
-MovementType Unit::getMovementType()
-{
-    return m_movementType;
-}
+Unit::~Unit() {}
 
 } // namespace advanced_wars
diff --git a/src/game/entities/Unit.hpp b/src/game/entities/Unit.hpp
index 9d2adad61cbb6e2265440be2ecbaf949d5927392..73e74bb66716a449093b154872593d3eb98a523b 100644
--- a/src/game/entities/Unit.hpp
+++ b/src/game/entities/Unit.hpp
@@ -3,8 +3,10 @@
 #include "../combat/Weapon.hpp"
 #include "../core/Config.hpp"
 #include "../core/Engine.hpp"
+#include "../physics/PhysicsBody.hpp"
 
 #include <SDL_events.h>
+#include <memory>
 #include <unordered_map>
 #include <vector>
 
@@ -14,165 +16,91 @@ namespace advanced_wars
 class Engine;
 class Config;
 
-using MatchupTable = std::unordered_map<UnitId, std::unordered_map<UnitId, int>>;
-
 class Unit
 {
     public:
         /**
-         * Constructor for Unit.
-         * Initializes the unit's position, faction, identifier, state, and configuration settings.
+         * Konstruktor für eine Einheit.
+         * Initialisiert die Position, Fraktion, Einheitentyp, Zustand und Konfigurationswerte.
          */
-        Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state, Config& config);
-
-        int getXPosition();
-
-        int getYPosition();
+        Unit(
+            int unitId, b2World* world, int tileX, int tileY, Faction faction,
+            UnitTypeId unitTypeId, UnitState state, Config& config);
 
-        /**
-         * Destructor for Unit.
-         * Handles any cleanup necessary when a unit is destroyed.
-         * (Currently assumes this triggers certain game events, though not explicitly detailed
-         * here.)
-         */
-        ~Unit() {};
+        ~Unit();
 
-        /**
-         * Renders the unit on the game screen.
-         * Uses the engine's rendering capabilities to draw the unit based on its state and faction.
-         *
-         * @param engine The game engine responsible for rendering.
-         * @param scale Scaling factor for rendering the unit.
-         */
-        void render(Engine& engine, int scale);
+        /// Aktualisiert die Einheit (Bewegung, Physik, etc.).
+        void update(float deltaTime);
 
-        /**
-         * Determines if another unit (enemy) is within attack range.
-         * Checks for the range based on the unit's weapon capabilities.
-         *
-         * @param enemy The enemy unit to check range against.
-         * @return true if the enemy is in range, false otherwise.
-         */
-        bool inRange(Unit& enemy);
+        /// Bewegt die Einheit zu einer neuen Position.
+        void moveTo(int posX, int posY);
 
-        /**
-         * Initiates an attack on a specified enemy unit.
-         * Calculates damage and updates health values for both the attacker and defender.
-         * Attacker damages the enemy first; if the enemy survives, a counter-attack may occur.
-         *
-         * @param enemy The unit being attacked.
-         */
-        void attack(Unit& enemy);
-
-        /**
-         * Performs the calculated damage on a target unit, adjusting its health accordingly.
-         * Considers this unit's current health for scaling damage.
-         *
-         * @param target The target unit receiving damage.
-         * @param damage The amount of damage calculated to be applied.
-         */
-        void performAttack(Unit& target, int damage);
-
-        /**
-         * Calculates the potential damage this unit can inflict on a target.
-         * Considers primary and secondary weapons' damage tables, and checks ammunition
-         * availability.
-         *
-         * @param target The unit to calculate damage against.
-         * @return The calculated damage value.
-         */
-        int calculateDamage(Unit& target);
-
-        /**
-         * Updates this unit's position on the game field.
-         * Changes the internal position and recalculates the unit's state (e.g., direction it's
-         * facing) based on movement to a new position.
-         *
-         * @param posX The new x-coordinate for the unit.
-         * @param posY The new y-coordinate for the unit.
-         */
-        void updatePosition(int posX, int posY);
-
-        /**
-         * Determines potential movement paths based on the unit's movement type and current
-         * terrain. (Intended to use Dijkstra's algorithm, though implementation details are omitted
-         * here.)
-         */
-        void calculateMovement();
-
-        /**
-         * Recalculates and updates the unit's state based on movement direction.
-         * Ensures that the unit faces the correct direction after a move.
-         *
-         * @param posX The x-coordinate of the desired position.
-         * @param posY The y-coordinate of the desired position.
-         */
+        /// Berechnet den neuen Zustand basierend auf der Bewegungsrichtung.
         void calcState(int posX, int posY);
 
-        /**
-         * Processes a left-click event on this unit.
-         * Typically triggers display of unit information (e.g., UI and movement range).
-         *
-         * @param event SDL event captured, specifically mouse click event.
-         */
-        void on_left_click(SDL_Event event);
+        /// Zerstört den Physics-Body der Einheit.
+        void destroyBody();
 
-        UnitFaction getFaction();
-
-        int    getAmmo() const { return m_ammo; }
-        int    getHealth() const { return m_health; }
-        int    getCost() const { return m_cost; }
-        UnitId getId() const { return m_id; }
-
-        int          getMovementPoints();
-        MovementType getMovementType();
-
-        void setState(UnitState state);
-
-        inline UnitState getState() const { return m_state; }
+        /// Rendert die Einheit auf dem Bildschirm.
+        void render(Engine& engine, int scale);
 
-        /**
-         * Retrieves units within range that this unit can deal damage to.
-         * Considers all units provided in 'allUnits', excluding itself, and checks movement and
-         * weapon range.
-         *
-         * @param allUnits Vector of pointers to all units on the field to check against.
-         * @return Vector of pointers to units in range that can be engaged.
-         */
-        std::vector<Unit*> getUnitsInRangeWithDamagePotential(const std::vector<Unit*>& allUnits);
+        /// Rendert die HP-Anzeige über der Einheit.
+        void renderHP(Engine& engine, int scale);
 
-        bool hasMoved();
-        bool hasAttacked();
+        // Getter-Methoden
+        int     getXPosition() const { return m_tileX; };
+        int     getYPosition() const { return m_tileY; };
+        Faction getFaction() { return this->m_faction; }
+
+        void         setState(UnitState state) { this->m_state = state; }
+        int          getAmmo() const { return m_ammo; }
+        int          getHealth() const { return m_health; }
+        int          getCost() const { return m_cost; }
+        UnitTypeId   getUnitTypeId() const { return m_unitTypeId; }
+        int          getMovementPoints() const { return m_movementPoints; }
+        MovementType getMovementType() const { return m_movementType; }
+        UnitState    getState() const { return m_state; }
+        bool         hasMoved() const { return this->m_hasMoved; }
+        void         setMoved(bool moved) { m_hasMoved = moved; }
+        bool         hasAttacked() const { return this->m_hasAttacked; }
+        int          getMaxHealth() const { return m_maxHealth; }
+        int          getMinRange() const { return m_minRange; }
+        int          getMaxRange() const { return m_maxRange; }
+        Weapon&      getPrimaryWeapon() { return *m_primaryWeapon; }
+        Weapon&      getSecondaryWeapon() { return *m_secondaryWeapon; }
+
+        int getUnitId() { return m_unitId; }
+
+        void setHealth(int health) { m_health = health; }
 
     private:
-        int m_x;
-        int m_y;
-        int m_health; // Current health of the unit, initialized to max health at construction.
-        int m_price;
-
-        int          m_movementPoints; // The number of tiles this unit can move per turn.
-        MovementType m_movementType;   // The type of movement this unit has (e.g., foot, wheeled).
-
-        UnitFaction m_faction; // The faction to which this unit belongs.
-        UnitId      m_id;      // The identifier for the unit type.
-        UnitState   m_state;   // The current state of the unit (idle, moving, etc.).
-
-        int m_maxHealth; // The maximum health of the unit.
-        int m_range;     // Possible range for future use, depending on specific unit abilities.
-
-        bool m_hasMoved;    // Indicates whether the unit has moved this turn.
-        bool m_hasAttacked; // Indicates whether the unit has attacked this turn.
-        bool m_isSelected;  // Indicates whether the unit is currently selected.
-        bool m_isTargeted;  // Indicates whether the unit is currently targeted by an enemy.
-
-        Weapon m_secondaryWeapon; // The unit's secondary weapon.
-        Weapon m_primaryWeapon;   // The unit's primary weapon.
-
-        int m_cost;     // The cost associated with deploying this unit.
-        int m_ammo;     // The amount of available ammo for attacks.
-        int m_minRange; // The minimum range of the unit's attack capability.
-        int m_maxRange; // The maximum range of the unit's attack capability.
-
-        void renderHP(Engine& engine, int scale);
+        int          m_unitId;
+        int          m_tileX;
+        int          m_tileY;
+        int          m_health;
+        int          m_cost;
+        int          m_ammo;
+        int          m_minRange;
+        int          m_maxRange;
+        int          m_maxHealth;
+        int          m_movementPoints;
+        MovementType m_movementType;
+        Faction      m_faction;
+        UnitTypeId   m_unitTypeId;
+        UnitState    m_state;
+
+        bool m_hasMoved = false;
+        bool m_hasAttacked = false;
+        bool m_isSelected = false;
+        bool m_isTargeted = false;
+
+        std::unique_ptr<Weapon> m_primaryWeapon;
+        std::unique_ptr<Weapon> m_secondaryWeapon;
+
+        std::unique_ptr<PhysicsBody> m_physicsBody;
+        b2World*                     m_world;
+
+        int m_animX;
+        int m_animY;
 };
 } // namespace advanced_wars
diff --git a/src/game/level/Level.cpp b/src/game/level/Level.cpp
index 0527b9374367217627ae511e1ccb2efa46bb3093..d38ba277b81d284fbe5e050915b37c26112f372c 100644
--- a/src/game/level/Level.cpp
+++ b/src/game/level/Level.cpp
@@ -5,16 +5,20 @@
 #include "../effect/Effect.hpp"
 #include "../entities/Building.hpp"
 #include "../entities/Unit.hpp"
+#include "../physics/PhysicsEngine.hpp"
 #include "../ui/context/ContextMenu.hpp"
 #include "../ui/menu/EndScreen.hpp"
 #include "../ui/menu/PauseMenu.hpp"
 #include "../ui/modals/HelpMenu.hpp"
+#include "SDL_timer.h"
+#include "box2d/box2d.h"
 
 #include <SDL.h>
 #include <boost/property_tree/ptree.hpp>
 #include <boost/property_tree/xml_parser.hpp>
 #include <highfive/H5File.hpp>
 #include <iostream>
+#include <memory>
 #include <string>
 
 namespace advanced_wars
@@ -22,45 +26,15 @@ namespace advanced_wars
 
 const int RENDERING_SCALE = 3;
 
-Level::Level(
-    std::string name, int width, int height, std::vector<Tile> tiles,
-    std::vector<Building> buildings, std::vector<Unit> units, std::vector<Effect> effects,
-    std::queue<Player> turnQ)
-    : m_name(name), m_width(width), m_height(height), m_tiles(tiles), m_selectedUnit(-1),
-      m_selectedBuilding(-1), m_contextMenu(ContextMenu()), m_id(0),
-      m_state(LevelState::SELECTING_STATE),
-      m_currentPos(TileMarker(RENDERING_SCALE, 1, 1, m_width, m_height)), m_turnQ(turnQ),
-      m_gameOver(false)
+Level::Level(const std::string& path, Engine& engine)
+    : m_selectedUnit(-1), m_selectedBuilding(-1), m_contextMenu(ContextMenu()), m_id(0),
+      m_state(LevelState::SELECTING_STATE)
 {
 
     m_contextMenu.setOptions({"Move", "Info", "Wait"});
 
-    for (Building building : buildings)
-    {
-        this->addBuilding(building);
-    }
-
-    for (Unit unit : units)
-    {
-        this->addUnit(unit);
-    }
-
-    for (Effect effect : effects)
-    {
-        this->addEffect(effect);
-    }
-
-    if ((size_t)(m_width * m_height) != tiles.size())
-    {
-        throw std::runtime_error("level tile mismatch");
-    }
-
-    m_selectedBuilding = -1;
-    m_selectedUnit = -1;
-};
-
-std::shared_ptr<Level> Level::loadLevel(const std::string& path, Engine& engine)
-{
+    m_physicsEngine = std::make_unique<PhysicsEngine>();
+    m_combatEngine = std::make_unique<CombatEngine>();
     HighFive::File file(path, HighFive::File::ReadOnly);
 
     // read level metadata
@@ -70,92 +44,109 @@ std::shared_ptr<Level> Level::loadLevel(const std::string& path, Engine& engine)
     // read tilesarray
     std::vector<uint8_t> level_tilesarray;
     file.getDataSet("tilesarray").read(level_tilesarray);
-
+    std::cout << "tilesarray size: " << level_tilesarray.size() << "\n";
     // extract metadata from xml
     std::istringstream          xmlStream(level_metadata);
     boost::property_tree::ptree pt;
     boost::property_tree::read_xml(xmlStream, pt);
-    int         width = pt.get<int>("level.width");
-    int         height = pt.get<int>("level.height");
+    m_width = pt.get<int>("level.width");
+    m_height = pt.get<int>("level.height");
     std::string name = pt.get<std::string>("level.name");
 
     // if level is smaler than 20x20 surround with water tiles
-    if (width < 20 || height < 20)
+    if (m_width < 20 || m_height < 20)
     {
-        int                  x_start = (20 - width) / 2;
-        int                  y_start = (20 - height) / 2;
+        int                  x_start = (20 - m_width) / 2;
+        int                  y_start = (20 - m_height) / 2;
         std::vector<uint8_t> transformed_tiles_array;
         transformed_tiles_array.reserve(20 * 20);
         for (int y = 0; y < 20; y++)
         {
             for (int x = 0; x < 20; x++)
             {
-                if (x < x_start || y < y_start || x >= x_start + width || y >= y_start + height)
+                if (x < x_start || y < y_start || x >= x_start + m_width || y >= y_start + m_height)
                 {
                     transformed_tiles_array.push_back(1);
                 }
                 else
                 {
                     transformed_tiles_array.push_back(
-                        level_tilesarray[x - x_start + (y - y_start) * width]);
+                        level_tilesarray[x - x_start + (y - y_start) * m_width]);
                 }
             }
         }
         level_tilesarray = std::move(transformed_tiles_array);
-        width = 20;
-        height = 20;
+        m_width = 20;
+        m_height = 20;
     }
 
+    m_currentPos = TileMarker(RENDERING_SCALE, 1, 1, m_width, m_height);
+
     // create tiles, buildings and units vector from tiles array
     std::vector<Tile>     tiles;
     std::vector<Building> buildings;
-    std::vector<Unit>     units;
-    tiles.reserve(width * height);
+    tiles.reserve(m_width * m_height);
     bool has_factions[] = {false, false, false, false, false};
     for (size_t i = 0; i < level_tilesarray.size(); i++)
     {
-        int x = i % width;
-        int y = i / width;
+        int tileX = i % m_width;
+        int tileY = i / m_width;
         if (level_tilesarray[i] >= 50)
         {
             // tile id >= 50 -> building -> have to add Plain Tile and Building
-            tiles.push_back(Tile(TileId(TileId::PLAIN), x, y));
-            BuildingId      building_id = static_cast<BuildingId>((level_tilesarray[i] - 50) % 5);
-            BuildingFaction faction_id =
-                static_cast<BuildingFaction>((level_tilesarray[i] - 50) / 5);
+            tiles.push_back(Tile(TileId(TileId::PLAIN), tileX, tileY));
+            BuildingId building_id = static_cast<BuildingId>((level_tilesarray[i] - 50) % 5);
+            Faction    faction_id = static_cast<Faction>((level_tilesarray[i] - 50) / 5);
             if (building_id == BuildingId::HEADQUARTER)
             {
                 // an infantery unit should be added onto every HQ
-                units.push_back(Unit(
-                    x, y, static_cast<UnitFaction>(faction_id), UnitId::INFANTERY,
-                    UnitState::UNAVAILABLE, engine.getUnitConfig()));
+                int index = static_cast<int>(faction_id);
+                if (!has_factions[index])
+                {
+                    addUnit(
+                        tileX, tileY, faction_id, UnitTypeId::INFANTERY, UnitState::UNAVAILABLE,
+                        engine.getUnitConfig());
+                }
+
                 has_factions[static_cast<int>(faction_id)] = true; // collect existing factions
                                                                    // for later building turnQ
             }
-            buildings.push_back(Building(x, y, building_id, faction_id));
+            buildings.push_back(Building(tileX, tileY, building_id, faction_id));
         }
         else
         {
             // if tile id belongs to terrain tile, just a tile needs to added
             TileId tile_id = static_cast<TileId>(level_tilesarray[i]);
-            tiles.push_back(Tile(tile_id, x, y));
+            tiles.push_back(Tile(tile_id, tileX, tileY));
         }
     }
 
+    m_tiles = std::move(tiles);
+
+    for (Building building : buildings)
+    {
+        this->addBuilding(building);
+    }
+
+    if ((size_t)(m_width * m_height) != m_tiles.size())
+    {
+        throw std::runtime_error("level tile mismatch");
+    }
+
     // create turnQ from has_factions array
     std::queue<Player> turnQ;
     for (int i = 0; i < 5; i++)
     {
         if (has_factions[i])
         {
-            turnQ.push(Player(2000, static_cast<UnitFaction>(i)));
+            std::cout << "Faction: " << i << "\n";
+            turnQ.push(Player(2000, static_cast<Faction>(i)));
         }
     }
 
-    Level level(name, width, height, tiles, buildings, units, std::vector<Effect>{}, turnQ);
+    m_turnQ = turnQ;
 
-    level.m_turnQ.front().startTurn(level.m_units, level.m_buildings);
-    return std::make_shared<Level>(level);
+    m_turnQ.front().startTurn(m_units, m_buildings);
 }
 
 std::pair<int, int> Level::calcTilePos(int mouseX, int mouseY)
@@ -176,7 +167,7 @@ void Level::selectEntity(int x, int y)
         auto it = m_units.find(m_selectedUnit);
         if (it != m_units.end())
         {
-            Unit& unit = it->second;
+            Unit& unit = *it->second;
             m_unitInfoMenu.setUnit(unit);
             // Position das Menu rechts neben der ausgewählten Einheit
             m_unitInfoMenu.update(
@@ -197,7 +188,8 @@ int Level::selectUnit(int tileX, int tileY)
 {
     for (auto& [id, unit] : m_units)
     {
-        if (unit.getXPosition() == tileX && unit.getYPosition() == tileY)
+        Unit& unitRef = *unit;
+        if (unitRef.getXPosition() == tileX && unitRef.getYPosition() == tileY)
         {
             return id;
         }
@@ -247,7 +239,8 @@ void Level::handleEvent(Engine& engine, SDL_Event& event)
         handleMovementEvents(engine, event);
         break;
     case LevelState::ATTACKING_STATE:
-        handleAttackingEvents(engine, event);
+        m_combatEngine->handleAttackingEvents(engine, event, *this);
+        // handleAttackingEvents(engine, event);
         break;
     case LevelState::RECRUITING_STATE:
         handleRecruitingEvent(engine, event);
@@ -280,8 +273,8 @@ std::vector<std::pair<int, int>> Level::calculateMovementRange(Unit& unit)
         bool isOccupied = false;
         for (auto& [id, otherUnit] : m_units)
         {
-            if (otherUnit.getXPosition() == x && otherUnit.getYPosition() == y &&
-                id != m_selectedUnit)
+            Unit& unitRef = *otherUnit;
+            if (unitRef.getXPosition() == x && unitRef.getYPosition() == y && id != m_selectedUnit)
             {
                 isOccupied = true;
                 break;
@@ -326,6 +319,8 @@ int Level::getMoveCost(TileId tileId, MovementType movementType)
 
 void Level::render(Engine& engine)
 {
+
+    float deltaTime = 1.0F / 60.0F;
     // Tiles
     for (Tile& tile : m_tiles)
     {
@@ -371,7 +366,10 @@ void Level::render(Engine& engine)
     // Units
     for (auto& [id, unit] : m_units)
     {
-        unit.render(engine, RENDERING_SCALE);
+        Unit& unitRef = *unit;
+        m_physicsEngine->step(deltaTime);
+        unitRef.update(deltaTime);
+        unitRef.render(engine, RENDERING_SCALE);
     }
 
     // Effects
@@ -388,6 +386,20 @@ void Level::render(Engine& engine)
         }
     }
 
+    if (m_bullet)
+    {
+        m_bullet->update();
+
+        if (m_bullet->shouldDestroy())
+        {
+            m_bullet.reset();
+        }
+        else
+        {
+            m_bullet->render(engine, RENDERING_SCALE);
+        }
+    }
+
     // Remove finished effects after iteration
     for (int id : effects_to_remove)
     {
@@ -433,20 +445,29 @@ Building Level::removeBuilding(int id)
     return value;
 }
 
-int Level::addUnit(Unit unit)
+void Level::addUnit(
+    int tileX, int tileY, Faction factionId, UnitTypeId unitTypeId, UnitState unitState,
+    Config& config)
 {
-    m_units.insert({m_id, unit});
-    m_id += 1;
+    auto unit = std::make_unique<Unit>(
+        m_unitIdIterator, m_physicsEngine->getWorld(), tileX, tileY, factionId, unitTypeId,
+        unitState, config);
 
-    return m_id - 1;
+    m_units.insert({m_unitIdIterator, std::move(unit)});
+    m_unitIdIterator += 1;
 }
 
-Unit Level::removeUnit(int id)
+void Level::removeUnit(int id)
 {
-    Unit value = m_units.at(id);
-    m_units.erase(id);
+    auto it = m_units.find(id);
+    if (it != m_units.end())
+    {
+        // Erst das PhysicsBody explizit zerstören
+        it->second->destroyBody();
 
-    return value;
+        // Danach die Unit aus der Map entfernen (Unique_ptr wird freigegeben)
+        m_units.erase(it);
+    }
 }
 
 int Level::addEffect(Effect effect)
@@ -465,8 +486,35 @@ Effect Level::removeEffect(int id)
     return value;
 }
 
+void Level::spawnBullet(Unit& attacker, Unit& target)
+{
+    float startX = attacker.getXPosition() + 0.5F; // Mitte des Tiles
+    float startY = attacker.getYPosition() + 0.5F;
+    float targetX = target.getXPosition() + 0.5F;
+    float targetY = target.getYPosition() + 0.5F;
+
+    float deltaX = targetX - startX;
+    float deltaY = targetY - startY;
+    float distance = std::sqrt(deltaX * deltaX + deltaY * deltaY);
+
+    if (distance == 0.0F)
+    {
+        return; // Keine Bullet spawnen, wenn Attacker und Ziel gleiche Position haben
+    }
+
+    // Richtung normalisieren
+    float velocityX = (deltaX / distance) * .2F; // Geschwindigkeit anpassen
+    float velocityY = (deltaY / distance) * .2F;
+
+    // Erstelle ein neues Bullet-Objekt mit der neuen `b2World*`-Referenz
+    m_bullet = std::make_unique<Bullet>(
+        m_physicsEngine->getWorld(), startX, startY, velocityX, velocityY, target);
+}
+
 void Level::changeTurn()
 {
+    std::cout << "First player: " << static_cast<int>(m_turnQ.front().getFaction())
+              << "Last player: " << static_cast<int>(m_turnQ.back().getFaction()) << "\n";
     Player temp = m_turnQ.front();
 
     temp.endTurn(m_units);
@@ -477,6 +525,8 @@ void Level::changeTurn()
 
     m_turnQ.front().startTurn(m_units, m_buildings);
     m_currentPos.setMarkerColor(m_turnQ.front().getFaction());
+
+    // print all  players from queue
 }
 
 void Level::handleRecruitingEvent(Engine& engine, SDL_Event& event)
@@ -495,18 +545,18 @@ void Level::handleRecruitingEvent(Engine& engine, SDL_Event& event)
         }
         if (event.key.keysym.sym == SDLK_RETURN)
         {
-            Building&   b = m_buildings.at(m_selectedBuilding);
-            UnitFaction u_faction = static_cast<UnitFaction>(b.getFaction());
-            UnitId      unit_id = m_recruitingMenu.getSelectedOption();
-            int         cost = engine.getUnitConfig().getUnitCost(unit_id);
+            Building&  b = m_buildings.at(m_selectedBuilding);
+            Faction    factionId = static_cast<Faction>(b.getFaction());
+            UnitTypeId unit_id = m_recruitingMenu.getSelectedOption();
+            int        cost = engine.getUnitConfig().getUnitCost(unit_id);
 
             if (b.check_money(cost, m_turnQ.front().getMoney()))
             {
                 if (b.check_spawn(m_units))
                 {
-                    addUnit(Unit(
-                        b.getXPosition(), b.getYPosition(), u_faction, unit_id, UnitState::IDLE,
-                        engine.getUnitConfig()));
+                    addUnit(
+                        b.getXPosition(), b.getYPosition(), factionId, unit_id, UnitState::IDLE,
+                        engine.getUnitConfig());
                     m_state = LevelState::SELECTING_STATE;
                     m_turnQ.front().spendMoney(cost);
                     m_selectedBuilding = -1;
@@ -515,8 +565,7 @@ void Level::handleRecruitingEvent(Engine& engine, SDL_Event& event)
             else
             {
                 std::cout << "You dont have enough money, current money: "
-                          << m_turnQ.front().getMoney() << " || needed money: " << cost
-                          << std::endl;
+                          << m_turnQ.front().getMoney() << " || needed money: " << cost << "\n";
             }
         }
     }
@@ -524,59 +573,15 @@ void Level::handleRecruitingEvent(Engine& engine, SDL_Event& event)
 
 //*******************helper functions for event Handling*************************************
 
-void Level::handleAttack(std::pair<int, int> tilePos)
-{
-    int targetedUnit = selectUnit(tilePos.first, tilePos.second);
-    if (targetedUnit >= 0)
-    {
-        if (m_units.at(m_selectedUnit).getFaction() == m_units.at(targetedUnit).getFaction())
-        {
-            std::cout << "You cannot attack your allies!" << std::endl;
-            return;
-        }
-
-        Unit& attacking = m_units.at(m_selectedUnit);
-        Unit& defending = m_units.at(targetedUnit);
-
-        if (m_attackableUnitIds.find(targetedUnit) != m_attackableUnitIds.end())
-        {
-            attacking.attack(defending);
-            if (attacking.getHealth() <= 0)
-            {
-                removeUnit(m_selectedUnit);
-            }
-            else
-            {
-                attacking.setState(UnitState::UNAVAILABLE);
-            }
-            if (defending.getHealth() <= 0)
-            {
-                removeUnit(targetedUnit);
-            }
-            m_selectedUnit = -1;
-            m_showAttackableTiles = false;
-            m_showReachableTiles = false;
-            m_state = LevelState::SELECTING_STATE;
-        }
-        else
-        {
-            std::cout << "No target in range clicked!" << std::endl;
-        }
-    }
-    else
-    {
-        std::cout << "No valid target clicked" << std::endl;
-    }
-}
-
 void Level::handleMovement(std::pair<int, int> tilePos)
 {
     for (auto& [id, unit] : m_units)
     {
-        if (unit.getXPosition() == tilePos.first && unit.getYPosition() == tilePos.second)
+        Unit& unitRef = *unit;
+        if (unitRef.getXPosition() == tilePos.first && unitRef.getYPosition() == tilePos.second)
         {
             // unit already at clicked position (maybe even selected unit)
-            std::cout << "Unit already at clicked position" << std::endl;
+            std::cout << "Unit already at clicked position" << "\n";
             return;
         }
     }
@@ -594,7 +599,7 @@ void Level::handleMovement(std::pair<int, int> tilePos)
 
     if (isReachable)
     {
-        m_units.at(m_selectedUnit).updatePosition(tilePos.first, tilePos.second);
+        m_units.at(m_selectedUnit)->moveTo(tilePos.first, tilePos.second);
 
         m_contextMenu.update(
             (tilePos.first * 16 + 15) * RENDERING_SCALE,
@@ -604,11 +609,11 @@ void Level::handleMovement(std::pair<int, int> tilePos)
 
         for (auto& [id, unit] : m_units)
         {
-            allUnits.push_back(&unit);
+            allUnits.push_back(unit.get());
         }
 
-        std::vector<Unit*> attackableTargets =
-            m_units.at(m_selectedUnit).getUnitsInRangeWithDamagePotential(allUnits);
+        std::vector<Unit*> attackableTargets = m_combatEngine->getUnitsInRangeWithDamagePotential(
+            *m_units.at(m_selectedUnit), allUnits);
 
         m_attackableTiles.clear();
         m_showAttackableTiles = true;
@@ -622,7 +627,7 @@ void Level::handleMovement(std::pair<int, int> tilePos)
             // Angreifbaren Einheits-ID setzen
             for (auto& [id, unit] : m_units)
             {
-                if (&unit == target)
+                if (unit.get() == target)
                 {
                     m_attackableUnitIds.insert(id);
                     break;
@@ -638,7 +643,7 @@ void Level::handleMovement(std::pair<int, int> tilePos)
     }
     else
     {
-        std::cout << "Unglültige Bewegunsposition!" << std::endl;
+        std::cout << "Unglültige Bewegunsposition!" << "\n";
     }
 }
 
@@ -671,26 +676,37 @@ void Level::handleSelectingEvents(Engine& engine, SDL_Event& event)
             std::pair<int, int> tilePos = m_currentPos.getPosition();
             selectEntity(
                 tilePos.first * 16 * RENDERING_SCALE, tilePos.second * 16 * RENDERING_SCALE);
+
             if (m_selectedUnit >= 0 || m_selectedBuilding >= 0)
             {
                 m_contextMenu.update(
                     (tilePos.first * 16 + 15) * RENDERING_SCALE,
                     (tilePos.second * 16 + 15) * RENDERING_SCALE);
+
                 if (m_selectedUnit >= 0)
                 {
-                    m_reachableTiles = calculateMovementRange(m_units.at(m_selectedUnit));
-                    m_units.at(m_selectedUnit).on_left_click(event);
-                    m_showReachableTiles = true;
+                    Unit& selectedUnit = *m_units.at(m_selectedUnit);
 
+                    if (selectedUnit.getFaction() == m_turnQ.front().getFaction())
+                    {
+                        m_reachableTiles = calculateMovementRange(selectedUnit);
+                        m_showReachableTiles = true;
+                    }
+                    else
+                    {
+                        m_showReachableTiles =
+                            false; // Falls es eine gegnerische Unit ist, deaktiviere es
+                    }
+                    m_reachableTiles = calculateMovementRange(*m_units.at(m_selectedUnit));
                     std::vector<Unit*> allUnits;
-
                     for (auto& [id, unit] : m_units)
                     {
-                        allUnits.push_back(&unit);
+                        allUnits.push_back(unit.get());
                     }
 
                     std::vector<Unit*> attackableTargets =
-                        m_units.at(m_selectedUnit).getUnitsInRangeWithDamagePotential(allUnits);
+                        m_combatEngine->getUnitsInRangeWithDamagePotential(
+                            *m_units.at(m_selectedUnit), allUnits);
 
                     m_attackableTiles.clear();
                     m_showAttackableTiles = true;
@@ -698,8 +714,8 @@ void Level::handleSelectingEvents(Engine& engine, SDL_Event& event)
 
                     // Set Fallback_position if movement will be canceled
                     unit_fallback_position = std::make_pair(
-                        m_units.at(m_selectedUnit).getXPosition(),
-                        m_units.at(m_selectedUnit).getYPosition());
+                        m_units.at(m_selectedUnit)->getXPosition(),
+                        m_units.at(m_selectedUnit)->getYPosition());
 
                     for (Unit* target : attackableTargets)
                     {
@@ -710,7 +726,7 @@ void Level::handleSelectingEvents(Engine& engine, SDL_Event& event)
                         // Angreifbaren Einheits-ID setzen
                         for (auto& [id, unit] : m_units)
                         {
-                            if (&unit == target)
+                            if (unit.get() == target)
                             {
                                 m_attackableUnitIds.insert(id);
                                 break;
@@ -718,10 +734,9 @@ void Level::handleSelectingEvents(Engine& engine, SDL_Event& event)
                         }
                     }
 
-                    Unit& u = m_units.at(m_selectedUnit);
-
-                    if (m_units.at(m_selectedUnit).getFaction() == m_turnQ.front().getFaction() &&
-                        m_units.at(m_selectedUnit).getState() != UnitState::UNAVAILABLE)
+                    Unit& u = *m_units.at(m_selectedUnit);
+                    if (u.getFaction() == m_turnQ.front().getFaction() &&
+                        u.getState() != UnitState::UNAVAILABLE)
                     {
                         m_captureBuilding = -1;
                         for (auto& [id, building] : m_buildings)
@@ -729,8 +744,7 @@ void Level::handleSelectingEvents(Engine& engine, SDL_Event& event)
                             if (building.getXPosition() == u.getXPosition() &&
                                 building.getYPosition() == u.getYPosition())
                             {
-                                if (building.getFaction() !=
-                                    static_cast<BuildingFaction>(u.getFaction()))
+                                if (static_cast<Faction>(building.getFaction()) != u.getFaction())
                                 {
                                     m_captureBuilding = id;
                                     m_contextMenu.setOptions(
@@ -754,10 +768,12 @@ void Level::handleSelectingEvents(Engine& engine, SDL_Event& event)
                 }
                 else
                 {
-                    BuildingId      b_id = m_buildings.at(m_selectedBuilding).getId();
-                    BuildingFaction b_faction = m_buildings.at(m_selectedBuilding).getFaction();
+                    BuildingId b_id = m_buildings.at(m_selectedBuilding).getId();
+                    Faction    b_faction =
+                        static_cast<Faction>(m_buildings.at(m_selectedBuilding).getFaction());
+
                     if (b_id == BuildingId::CITY || b_id == BuildingId::HEADQUARTER ||
-                        b_faction == static_cast<BuildingFaction>(5))
+                        b_faction == static_cast<Faction>(5))
                     {
                         m_contextMenu.setOptions({"Info", "End Turn"});
                     }
@@ -765,8 +781,7 @@ void Level::handleSelectingEvents(Engine& engine, SDL_Event& event)
                     {
                         // Show according menu options if building has same/different faction than
                         // current player
-                        if (m_buildings.at(m_selectedBuilding).getFaction() ==
-                            static_cast<BuildingFaction>(m_turnQ.front().getFaction()))
+                        if (b_faction == m_turnQ.front().getFaction())
                         {
                             m_contextMenu.setOptions({"Train", "Info", "End Turn"});
                         }
@@ -794,11 +809,11 @@ void Level::handleMenuActiveEvents(Engine& engine, SDL_Event& event)
         {
             if (m_selectedUnit > -1 &&
                 unit_fallback_position != std::make_pair(
-                                              m_units.at(m_selectedUnit).getXPosition(),
-                                              m_units.at(m_selectedUnit).getYPosition()))
+                                              m_units.at(m_selectedUnit)->getXPosition(),
+                                              m_units.at(m_selectedUnit)->getYPosition()))
             {
                 m_units.at(m_selectedUnit)
-                    .updatePosition(unit_fallback_position.first, unit_fallback_position.second);
+                    ->moveTo(unit_fallback_position.first, unit_fallback_position.second);
             }
             m_selectedUnit = -1;
             m_selectedBuilding = -1;
@@ -824,8 +839,9 @@ void Level::handleMenuActiveEvents(Engine& engine, SDL_Event& event)
                 auto it = m_units.find(m_selectedUnit);
                 if (it != m_units.end())
                 {
-                    it->second.setState(UnitState::UNAVAILABLE);
-                    std::cout << "Unit state set to UNAVAILABLE." << std::endl;
+                    it->second->setState(UnitState::UNAVAILABLE);
+                    it->second->setMoved(true);
+                    std::cout << "Unit state set to UNAVAILABLE." << "\n";
                     m_state = LevelState::SELECTING_STATE;
                     m_selectedUnit = -1;
                     m_selectedBuilding = -1;
@@ -834,7 +850,7 @@ void Level::handleMenuActiveEvents(Engine& engine, SDL_Event& event)
                 }
                 else
                 {
-                    std::cerr << "Selected unit id is invalid: " << m_selectedUnit << std::endl;
+                    std::cerr << "Selected unit id is invalid: " << m_selectedUnit << "\n";
                 }
             }
             if (cmd == "Move")
@@ -853,16 +869,15 @@ void Level::handleMenuActiveEvents(Engine& engine, SDL_Event& event)
                 // TODO: Hier Informationen zur Einheit darstellen
                 if (m_selectedUnit > -1)
                 {
-                    Unit& u = m_units.at(m_selectedUnit);
-                    std::cout << "Health: " << u.getHealth() << std::endl;
+                    Unit* u = m_units.at(m_selectedUnit).get();
+                    std::cout << "Health: " << u->getHealth() << "\n";
                     m_showUnitInfoMenu = !m_showUnitInfoMenu;
                 }
                 if (m_selectedBuilding > -1)
                 {
                     Building b = m_buildings.at(m_selectedBuilding);
                     std::cout << "Building ID: " << static_cast<int>(b.getId()) << " || "
-                              << "Building Faction: " << static_cast<int>(b.getFaction())
-                              << std::endl;
+                              << "Building Faction: " << static_cast<int>(b.getFaction()) << "\n";
                 }
             }
             if (cmd == "Train")
@@ -873,18 +888,18 @@ void Level::handleMenuActiveEvents(Engine& engine, SDL_Event& event)
                     (tilePos.first * 16 + 15) * RENDERING_SCALE,
                     (tilePos.second * 16 + 15) * RENDERING_SCALE);
                 m_recruitingMenu.setOptions(m_buildings.at(m_selectedBuilding).recruitableUnits());
-                std::cout << "no training here" << std::endl;
+                std::cout << "no training here" << "\n";
             }
 
             if (cmd == "Capture")
             {
-                Building&   b = m_buildings.at(m_captureBuilding);
-                UnitFaction u_f = m_units.at(m_selectedUnit).getFaction();
+                Building& b = m_buildings.at(m_captureBuilding);
+                Faction   u_f = m_units.at(m_selectedUnit)->getFaction();
 
-                BuildingFaction b_f = static_cast<BuildingFaction>(u_f);
+                auto b_f = static_cast<Faction>(u_f);
                 m_gameOver = b.switch_faction(b_f);
 
-                m_units.at(m_selectedUnit).setState(UnitState::UNAVAILABLE);
+                m_units.at(m_selectedUnit)->setState(UnitState::UNAVAILABLE);
                 m_state = LevelState::SELECTING_STATE;
                 m_selectedBuilding = -1;
                 m_selectedUnit = -1;
@@ -925,32 +940,6 @@ void Level::handleMovementEvents(Engine& engine, SDL_Event& event)
         break;
     }
 }
-
-void Level::handleAttackingEvents(Engine& engine, SDL_Event& event)
-{
-    if (m_attackableUnitIds.empty())
-    {
-        std::cout << "No units are within attack range." << std::endl;
-        m_state = LevelState::MENUACTIVE_STATE;
-        return; // Early exit if no units to attack
-    }
-    switch (event.type)
-    {
-    case SDL_KEYDOWN:
-        handlePositionMarker(engine, event);
-        if (event.key.keysym.sym == SDLK_ESCAPE)
-        {
-            m_state = LevelState::MENUACTIVE_STATE;
-        }
-        if (event.key.keysym.sym == SDLK_RETURN)
-        {
-            handleAttack(m_currentPos.getPosition());
-        }
-        break;
-    default:
-        break;
-    }
-}
 //************end event handler delegates for different level
 // states*****************************
 
diff --git a/src/game/level/Level.hpp b/src/game/level/Level.hpp
index 2462564546f2c9e6fba7c1bff423bc2a1d8f7170..ddca6329d4cf5a952b3fec0f1ccf0ce77d0933f6 100644
--- a/src/game/level/Level.hpp
+++ b/src/game/level/Level.hpp
@@ -1,11 +1,14 @@
 #pragma once
 
+#include "../combat/CombatEngine.hpp"
 #include "../core/Engine.hpp"
 #include "../core/Scene.hpp"
 #include "../core/Tile.hpp"
 #include "../effect/Effect.hpp"
 #include "../entities/Building.hpp"
+#include "../entities/Bullet.hpp"
 #include "../entities/Unit.hpp"
+#include "../physics/PhysicsEngine.hpp"
 #include "../player/Player.hpp"
 #include "../ui/TileMarker.hpp"
 #include "../ui/context/ContextMenu.hpp"
@@ -15,6 +18,7 @@
 
 #include <SDL.h>
 #include <array>
+#include <memory>
 #include <queue>
 #include <string>
 #include <unordered_map>
@@ -79,12 +83,12 @@ enum class LevelState
 class Level : public Scene
 {
     public:
-        Level(
-            std::string name, int width, int height, std::vector<Tile> tiles,
-            std::vector<Building> buildings, std::vector<Unit> units, std::vector<Effect> effects,
-            std::queue<Player> turnQ);
+        Level(const std::string& path, Engine& engine);
 
-        static std::shared_ptr<Level> loadLevel(const std::string& path, Engine& engine);
+        // std::shared_ptr<Level> loadLevel(
+        //     std::string name, int width, int height, std::vector<Tile> tiles,
+        //     std::vector<Building> buildings, std::vector<Effect> effects, std::queue<Player>
+        //     turnQ);
 
         void render(Engine& engine);
 
@@ -109,9 +113,11 @@ class Level : public Scene
 
         Building removeBuilding(int id);
 
-        int addUnit(Unit unit);
+        void addUnit(
+            int tileX, int tileY, Faction factionId, UnitTypeId unitTypeId, UnitState unitState,
+            Config& config);
 
-        Unit removeUnit(int id);
+        void removeUnit(int id);
 
         int addEffect(Effect effect);
 
@@ -125,34 +131,11 @@ class Level : public Scene
 
         std::vector<std::pair<int, int>> m_attackableTiles;
 
-    private:
-        bool                              m_gameOver;
-        std::string                       m_name;
-        int                               m_width;
-        int                               m_height;
-        std::vector<Tile>                 m_tiles;
-        std::unordered_map<int, Building> m_buildings;
-        std::unordered_map<int, Unit>     m_units;
-        std::unordered_map<int, Effect>   m_effects;
-        std::queue<Player>                m_turnQ;
-
-        int            m_selectedUnit;
-        int            m_selectedBuilding;
-        int            m_captureBuilding;
-        ContextMenu    m_contextMenu;
-        RecruitingMenu m_recruitingMenu;
-        bool           toggle_Helpmenu = false;
-        HelpMenu       m_helpMenu;
-        int            m_id;
-        LevelState     m_state;
-
         std::pair<int, int> calcTilePos(int mouseX, int mouseY);
         void                selectEntity(int x, int y);
         int                 selectUnit(int tileX, int tileY);
         int                 selectBuilding(int tileX, int tileY);
 
-        TileMarker m_currentPos;
-
         void handleSelectingEvents(Engine& engine, SDL_Event& event);
         void handleMenuActiveEvents(Engine& engine, SDL_Event& event);
         void handleMovementEvents(Engine& engine, SDL_Event& event);
@@ -164,20 +147,58 @@ class Level : public Scene
 
         void changeTurn();
 
-        bool m_showReachableTiles;
-        bool m_showAttackableTiles;
-
-        std::unordered_set<int> m_attackableUnitIds;
-
         void handleAttack(std::pair<int, int> tilePos);
         void handleMovement(std::pair<int, int> tilePos);
         void handlePositionMarker(Engine& engine, SDL_Event& event);
 
-        UnitInfoMenu m_unitInfoMenu;
+        std::unordered_map<int, std::unique_ptr<Unit>>& getUnits() { return m_units; }
+        int  getSelectedUnit() const { return m_selectedUnit; }
+        void setSelectedUnit(int id) { m_selectedUnit = id; }
+        void setShowAttackableTiles(bool show) { m_showAttackableTiles = show; }
+        void setShowReachableTiles(bool show) { m_showReachableTiles = show; }
+        void setState(LevelState state) { m_state = state; }
 
-        bool m_showUnitInfoMenu = false;
+        std::unordered_set<int>& getAttackableUnitIds() { return m_attackableUnitIds; }
 
-        std::pair<int, int> unit_fallback_position;
+        LevelState getState() { return m_state; }
+
+        TileMarker getTilemarker() { return m_currentPos; }
+
+        void spawnBullet(Unit& attacker, Unit& target);
+
+    private:
+        bool                                           m_gameOver = false;
+        std::string                                    m_name;
+        int                                            m_width = 0;
+        int                                            m_height = 0;
+        std::vector<Tile>                              m_tiles;
+        std::unordered_map<int, Building>              m_buildings;
+        std::unordered_map<int, std::unique_ptr<Unit>> m_units;
+        int                                            m_unitIdIterator = 5;
+        // std::unordered_map<int, Unit>     m_units;
+        std::unordered_map<int, Effect> m_effects;
+        std::unique_ptr<Bullet>         m_bullet;
+        std::queue<Player>              m_turnQ;
+
+        int                            m_selectedUnit;
+        int                            m_selectedBuilding;
+        int                            m_captureBuilding;
+        ContextMenu                    m_contextMenu;
+        RecruitingMenu                 m_recruitingMenu;
+        bool                           toggle_Helpmenu = false;
+        HelpMenu                       m_helpMenu;
+        int                            m_id;
+        LevelState                     m_state;
+        TileMarker                     m_currentPos;
+        bool                           m_showReachableTiles = false;
+        bool                           m_showAttackableTiles = false;
+        std::unordered_set<int>        m_attackableUnitIds;
+        UnitInfoMenu                   m_unitInfoMenu;
+        bool                           m_showUnitInfoMenu = false;
+        std::pair<int, int>            unit_fallback_position;
+        std::unique_ptr<PhysicsEngine> m_physicsEngine;
+        std::unique_ptr<CombatEngine>  m_combatEngine;
+        Uint32                         m_lastFrameTime = 0;
 };
 
 } // namespace advanced_wars
diff --git a/src/game/physics/PhysicsBody.cpp b/src/game/physics/PhysicsBody.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c7b31c34276ee9f3395afd3e129f40656283ba7b
--- /dev/null
+++ b/src/game/physics/PhysicsBody.cpp
@@ -0,0 +1,108 @@
+#include "PhysicsBody.hpp"
+#include "../../util/Dimensions.hpp"
+#include <box2d/box2d.h>
+
+namespace advanced_wars
+{
+
+PhysicsBody::PhysicsBody(
+    b2World* world, int x, int y, float width, float height, float density, float friction,
+    bool isSensor, BodyType type)
+    : m_world(world), m_xMeter(tileToWorld(x)), m_yMeter(tileToWorld(y)), m_targetX(tileToWorld(x)),
+      m_targetY(tileToWorld(y)), m_width(width), m_height(height), m_density(density),
+      m_friction(friction), m_isSensor(isSensor), m_type(type)
+{
+    b2BodyDef bodyDef;
+    bodyDef.type = b2_dynamicBody;
+    bodyDef.position.Set(m_xMeter, m_yMeter);
+
+    m_body = m_world->CreateBody(&bodyDef);
+    b2PolygonShape hitbox;
+    hitbox.SetAsBox(pixelToWorld(width), pixelToWorld(height));
+
+    b2FixtureDef fixtureDef;
+    fixtureDef.shape = &hitbox;
+    fixtureDef.density = density;
+    fixtureDef.friction = friction;
+    fixtureDef.isSensor = isSensor;
+
+    m_fixture = m_body->CreateFixture(&fixtureDef);
+}
+
+void PhysicsBody::update(float deltaTime)
+{
+    if (!m_body)
+    {
+        return;
+    }
+
+    // Korrekte Mitte des Tiles als Ziel setzen
+    float worldTargetX = m_targetX + 0.5F;
+    float worldTargetY = m_targetY + 0.5F;
+
+    b2Vec2 currentPos = getPosition();
+    float  deltaX = worldTargetX - currentPos.x;
+    float  deltaY = worldTargetY - currentPos.y;
+    float  distance = std::sqrt(deltaX * deltaX + deltaY * deltaY);
+
+    if (distance < 0.01F) // Exakte Prüfung auf Tile-Zentrum
+    {
+        // Direkt zentrieren, falls sehr nahe am Ziel
+        m_body->SetTransform({worldTargetX, worldTargetY}, 0);
+        m_body->SetLinearVelocity({0, 0});
+        return;
+    }
+
+    // Richtung berechnen (normieren)
+    float directionX = deltaX / distance;
+    float directionY = deltaY / distance;
+
+    // Geschwindigkeit setzen
+    float  speed = 1.2F;
+    b2Vec2 velocity = {directionX * speed, directionY * speed};
+
+    m_body->SetLinearVelocity(velocity);
+}
+
+void PhysicsBody::setTargetPosition(int targetTileX, int targetTileY)
+{
+    m_targetX = tileToWorld(targetTileX);
+    m_targetY = tileToWorld(targetTileY);
+}
+
+b2Vec2 PhysicsBody::getPosition() const
+{
+    if (m_body)
+    {
+        return m_body->GetPosition();
+    }
+    return {0.0F, 0.0F};
+}
+
+b2Vec2 PhysicsBody::getVelocity() const
+{
+    if (m_body)
+    {
+        return m_body->GetLinearVelocity();
+    }
+    return {0.0F, 0.0F};
+}
+
+void PhysicsBody::destroy()
+{
+    if (m_body && m_world)
+    {
+        m_world->DestroyBody(m_body);
+        m_body = nullptr;
+    }
+}
+
+void PhysicsBody::setVelocity(b2Vec2 velocity)
+{
+    if (m_body)
+    {
+        m_body->SetLinearVelocity(velocity);
+    }
+}
+
+} // namespace advanced_wars
diff --git a/src/game/physics/PhysicsBody.hpp b/src/game/physics/PhysicsBody.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..5bb6d69bfa3c47ff22f66de87d23015b6fa6c746
--- /dev/null
+++ b/src/game/physics/PhysicsBody.hpp
@@ -0,0 +1,41 @@
+#pragma once
+
+#include "box2d/b2_body.h"
+
+namespace advanced_wars
+{
+
+enum class BodyType
+{
+    UNIT,
+    PROJECTILE
+};
+
+class PhysicsBody
+{
+    public:
+        PhysicsBody(
+            b2World* world, int x, int y, float width, float height, float density, float friction,
+            bool isSensor, BodyType type);
+        void    update(float deltaTime);
+        void    setTargetPosition(int targetTileX, int targetTileY);
+        b2Vec2  getPosition() const;
+        b2Vec2  getVelocity() const;
+        void    destroy();
+        void    setVelocity(b2Vec2 velocity);
+        bool    isProjectile() const { return m_type == BodyType::PROJECTILE; }
+        b2Body* getBody() const { return m_body; }
+
+    private:
+        b2World*   m_world;
+        b2Body*    m_body;
+        b2Fixture* m_fixture;
+        float      m_xMeter, m_yMeter;
+        float      m_targetX, m_targetY;
+        float      m_width, m_height;
+        float      m_density, m_friction;
+        bool       m_isSensor;
+        BodyType   m_type;
+};
+
+} // namespace advanced_wars
diff --git a/src/game/physics/PhysicsEngine.cpp b/src/game/physics/PhysicsEngine.cpp
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..da8bdb2bed20fb3711af73dcb8df35c9a24bfc19 100644
--- a/src/game/physics/PhysicsEngine.cpp
+++ b/src/game/physics/PhysicsEngine.cpp
@@ -0,0 +1,83 @@
+#include "PhysicsEngine.hpp"
+#include "../entities/Bullet.hpp"
+#include "../entities/Unit.hpp"
+
+namespace advanced_wars
+{
+
+PhysicsEngine::PhysicsEngine()
+{
+    b2Vec2 gravity(0.0f, 0.0f);
+    m_world = new b2World(gravity);
+    m_world->SetContactListener(this);
+}
+
+PhysicsEngine::~PhysicsEngine()
+{
+    delete m_world;
+}
+
+void PhysicsEngine::step(float deltaTime)
+{
+    m_world->Step(deltaTime, 6, 2);
+}
+
+void PhysicsEngine::BeginContact(b2Contact* contact)
+{
+
+    b2Fixture* fixtureA = contact->GetFixtureA();
+    b2Fixture* fixtureB = contact->GetFixtureB();
+
+    void* bodyUserDataA = reinterpret_cast<void*>(fixtureA->GetBody()->GetUserData().pointer);
+    void* bodyUserDataB = reinterpret_cast<void*>(fixtureB->GetBody()->GetUserData().pointer);
+
+    BodyUserData* budA = reinterpret_cast<BodyUserData*>(bodyUserDataA);
+    BodyUserData* budB = reinterpret_cast<BodyUserData*>(bodyUserDataB);
+
+    if (!budA || !budB)
+    {
+        return;
+    }
+
+    // **Bullet- und Unit-Identifizierung**
+    Bullet* bullet = nullptr;
+    Unit*   unit = nullptr;
+
+    if (budA->type == BodyUserData::Type::Bullet)
+    {
+        bullet = static_cast<Bullet*>(budA->data);
+    }
+    else if (budA->type == BodyUserData::Type::Unit)
+    {
+        unit = static_cast<Unit*>(budA->data);
+    }
+
+    if (budB->type == BodyUserData::Type::Bullet)
+    {
+        bullet = static_cast<Bullet*>(budB->data);
+    }
+    else if (budB->type == BodyUserData::Type::Unit)
+    {
+        unit = static_cast<Unit*>(budB->data);
+    }
+
+    if (!bullet || !unit)
+    {
+        return;
+    }
+    int bulletTargetId = bullet->getTarget().getUnitId();
+    int unitId = unit->getUnitId();
+
+    if (unitId != bulletTargetId)
+    {
+        return;
+    }
+
+    // **Bullet soll zerstört werden**
+    if (bullet)
+    {
+        bullet->setDestroyFlag(true);
+    }
+}
+
+} // namespace advanced_wars
diff --git a/src/game/physics/PhysicsEngine.hpp b/src/game/physics/PhysicsEngine.hpp
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1183f738021761ea04d468b32a7af707dfe2cfc1 100644
--- a/src/game/physics/PhysicsEngine.hpp
+++ b/src/game/physics/PhysicsEngine.hpp
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "PhysicsBody.hpp"
+#include "box2d/box2d.h"
+
+#include <vector>
+
+namespace advanced_wars
+{
+
+struct BodyUserData
+{
+        enum class Type
+        {
+            Unit = 0,
+            Bullet = 1,
+        };
+        Type  type;
+        int   id;
+        void* data;
+};
+
+class PhysicsEngine : public b2ContactListener
+{
+    public:
+        PhysicsEngine();
+        ~PhysicsEngine();
+        void     step(float deltaTime);
+        b2World* getWorld() { return m_world; }
+
+        void BeginContact(b2Contact* contact) override;
+
+    private:
+        b2World* m_world;
+};
+
+} // namespace advanced_wars
diff --git a/src/game/player/Player.cpp b/src/game/player/Player.cpp
index 4c8c718696f4c2a656c4f7e27f615381f5fdb2b3..84a081edfc0e1eab3a9ac8035d792c67238dce67 100644
--- a/src/game/player/Player.cpp
+++ b/src/game/player/Player.cpp
@@ -4,7 +4,7 @@
 namespace advanced_wars
 {
 
-Player::Player(int money, UnitFaction faction)
+Player::Player(int money, Faction faction)
     : m_money(money), m_alive(true), m_activeTurn(false), m_faction(faction)
 {
 }
@@ -12,13 +12,16 @@ Player::Player(int money, UnitFaction faction)
 Player::~Player() {}
 
 void Player::startTurn(
-    std::unordered_map<int, Unit>& lvUnits, std::unordered_map<int, Building>& lvBuildings)
+    std::unordered_map<int, std::unique_ptr<Unit>>& lvUnits,
+    std::unordered_map<int, Building>&              lvBuildings)
 {
     for (auto& [id, unit] : lvUnits)
     {
-        if (unit.getFaction() == m_faction)
+        Unit& unitRef = *unit;
+        if (unitRef.getFaction() == m_faction)
         {
-            unit.setState(UnitState::IDLE);
+            unitRef.setState(UnitState::IDLE);
+            unitRef.setMoved(false);
         }
     }
 
@@ -28,32 +31,32 @@ void Player::startTurn(
     {
         switch (m_faction)
         {
-        case UnitFaction::URED:
-            if (building.getFaction() == BuildingFaction::URED)
+        case Faction::URED:
+            if (building.getFaction() == Faction::URED)
             {
                 underControl++;
             }
             break;
-        case UnitFaction::UBLUE:
-            if (building.getFaction() == BuildingFaction::UBLUE)
+        case Faction::UBLUE:
+            if (building.getFaction() == Faction::UBLUE)
             {
                 underControl++;
             }
             break;
-        case UnitFaction::UYELLOW:
-            if (building.getFaction() == BuildingFaction::UYELLOW)
+        case Faction::UYELLOW:
+            if (building.getFaction() == Faction::UYELLOW)
             {
                 underControl++;
             }
             break;
-        case UnitFaction::UGREEN:
-            if (building.getFaction() == BuildingFaction::UGREEN)
+        case Faction::UGREEN:
+            if (building.getFaction() == Faction::UGREEN)
             {
                 underControl++;
             }
             break;
-        case UnitFaction::UPURPLE:
-            if (building.getFaction() == BuildingFaction::UPURPLE)
+        case Faction::UPURPLE:
+            if (building.getFaction() == Faction::UPURPLE)
             {
                 underControl++;
             }
@@ -69,19 +72,22 @@ void Player::startTurn(
     m_activeTurn = true;
 }
 
-void Player::endTurn(std::unordered_map<int, Unit>& lvUnits)
+void Player::endTurn(std::unordered_map<int, std::unique_ptr<Unit>>& lvUnits)
 {
+    std::cout << "Ending turn for player with faction: " << static_cast<int>(m_faction) << "\n";
     for (auto& [id, unit] : lvUnits)
     {
-        if (unit.getFaction() == m_faction)
+        Unit& unitRef = *unit;
+        if (unitRef.getFaction() == m_faction)
         {
-            unit.setState(UnitState::UNAVAILABLE);
+            unitRef.setState(UnitState::UNAVAILABLE);
+            unitRef.setMoved(true);
         }
     }
     m_activeTurn = false;
 }
 
-UnitFaction Player::getFaction()
+Faction Player::getFaction()
 {
     return m_faction;
 }
@@ -95,4 +101,4 @@ void Player::spendMoney(int toSpend)
 {
     m_money -= toSpend;
 }
-} // namespace advanced_wars
\ No newline at end of file
+} // namespace advanced_wars
diff --git a/src/game/player/Player.hpp b/src/game/player/Player.hpp
index 9a99b5ba688a9d4d65bdeba374b91d1821c0d820..83b0d27aa034d9253ec9ffb833994906c8853a00 100644
--- a/src/game/player/Player.hpp
+++ b/src/game/player/Player.hpp
@@ -12,7 +12,7 @@ class Player
 {
 
     public:
-        Player(int money, UnitFaction faction);
+        Player(int money, Faction faction);
         ~Player();
 
         /**
@@ -23,7 +23,8 @@ class Player
          * @param lvBuildings All buildings of a level
          */
         void startTurn(
-            std::unordered_map<int, Unit>& lvUnits, std::unordered_map<int, Building>& lvBuildings);
+            std::unordered_map<int, std::unique_ptr<Unit>>& lvUnits,
+            std::unordered_map<int, Building>&              lvBuildings);
 
         /**
          * Sets all units of the players faction to unavailable and sets them as no longer being the
@@ -31,19 +32,19 @@ class Player
          *
          * @param lvUnits All current units of a level
          */
-        void endTurn(std::unordered_map<int, Unit>& lvUnits);
+        void endTurn(std::unordered_map<int, std::unique_ptr<Unit>>& lvUnits);
 
-        UnitFaction getFaction();
+        Faction getFaction();
 
         int getMoney();
 
         void spendMoney(int toSpend);
 
     private:
-        int         m_money;
-        bool        m_alive;
-        bool        m_activeTurn;
-        UnitFaction m_faction;
+        int     m_money;
+        bool    m_alive;
+        bool    m_activeTurn;
+        Faction m_faction;
 };
 
 } // namespace advanced_wars
diff --git a/src/game/ui/TileMarker.cpp b/src/game/ui/TileMarker.cpp
index 755b78166cdc3d0b73d3aac2ceb3ee39536ccaf7..e6e6122a75c4b25ec137a85dc34a8f5c3741cb1a 100644
--- a/src/game/ui/TileMarker.cpp
+++ b/src/game/ui/TileMarker.cpp
@@ -22,6 +22,12 @@ void TileMarker::render(Engine& engine)
     SDL_RenderFillRect(engine.renderer(), &box);
 }
 
+void TileMarker::setBounds(int width, int height)
+{
+    m_levelWidth = width;
+    m_levelHeight = height;
+}
+
 void TileMarker::handleEvent(Engine& engine, SDL_Event& event)
 {
     if (event.type == SDL_KEYDOWN)
@@ -32,7 +38,7 @@ void TileMarker::handleEvent(Engine& engine, SDL_Event& event)
         {
         case SDLK_UP:
             newY = m_y - 16 * m_renderingScale;
-            std::cout << "New Y: " << newY << std::endl;
+            std::cout << "New Y: " << newY << "\n";
             if (newY <= 0)
             {
                 break;
@@ -41,7 +47,7 @@ void TileMarker::handleEvent(Engine& engine, SDL_Event& event)
             break;
         case SDLK_DOWN:
             newY = m_y + 16 * m_renderingScale;
-            std::cout << "New Y: " << newY << std::endl;
+            std::cout << "New Y: " << newY << "\n";
 
             if (newY >= m_levelHeight)
 
@@ -52,7 +58,7 @@ void TileMarker::handleEvent(Engine& engine, SDL_Event& event)
             break;
         case SDLK_RIGHT:
             newX = m_x + 16 * m_renderingScale;
-            std::cout << "New X: " << newX << std::endl;
+            std::cout << "New X: " << newX << "\n";
 
             if (newX >= m_levelWidth)
             {
@@ -62,7 +68,7 @@ void TileMarker::handleEvent(Engine& engine, SDL_Event& event)
             break;
         case SDLK_LEFT:
             newX = m_x - 16 * m_renderingScale;
-            std::cout << "New X: " << newX << std::endl;
+            std::cout << "New X: " << newX << "\n";
 
             if (newX < 0)
             {
@@ -90,23 +96,23 @@ void TileMarker::setPosition(int tileX, int tileY)
     m_y = tileY * 16 * m_renderingScale + (16 * m_renderingScale - m_height);
 }
 
-void TileMarker::setMarkerColor(UnitFaction faction)
+void TileMarker::setMarkerColor(Faction faction)
 {
     switch (faction)
     {
-    case UnitFaction::URED:
+    case Faction::URED:
         m_markerColor = {255, 0, 0, 255};
         break;
-    case UnitFaction::UBLUE:
+    case Faction::UBLUE:
         m_markerColor = {0, 0, 255, 255};
         break;
-    case UnitFaction::UGREEN:
+    case Faction::UGREEN:
         m_markerColor = {0, 255, 0, 255};
         break;
-    case UnitFaction::UYELLOW:
+    case Faction::UYELLOW:
         m_markerColor = {255, 255, 0, 255};
         break;
-    case UnitFaction::UPURPLE:
+    case Faction::UPURPLE:
         m_markerColor = {255, 0, 255, 255};
         break;
     default:
diff --git a/src/game/ui/TileMarker.hpp b/src/game/ui/TileMarker.hpp
index d394c64739bc51f29bc0e5efc353c0b71f6f1ef6..0c06fb54aecce239698f48a800b2651317652f0e 100644
--- a/src/game/ui/TileMarker.hpp
+++ b/src/game/ui/TileMarker.hpp
@@ -13,6 +13,7 @@ class TileMarker : public Scene
 {
     public:
         TileMarker(int renderingScale, int tileX, int tileY, int levelWidth, int levelHeight);
+        TileMarker() = default;
 
         void render(Engine& engine) override;
 
@@ -22,7 +23,9 @@ class TileMarker : public Scene
 
         void setPosition(int x, int y);
 
-        void setMarkerColor(UnitFaction faction);
+        void setMarkerColor(Faction faction);
+
+        void setBounds(int width, int height);
 
     private:
         int       m_x;
diff --git a/src/game/ui/context/ContextMenu.cpp b/src/game/ui/context/ContextMenu.cpp
index fce89e85375e816d68f90af38e0132bd8bf21356..7d350d0e27528cf165eb8a5009b7422b564a8b72 100644
--- a/src/game/ui/context/ContextMenu.cpp
+++ b/src/game/ui/context/ContextMenu.cpp
@@ -21,7 +21,7 @@ void ContextMenu::render(Engine& engine)
 
     if (TTF_Init() == -1)
     {
-        std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl;
+        std::cerr << "Failed to initialize TTF: " << TTF_GetError() << "\n";
         return;
     }
 
@@ -37,7 +37,7 @@ void ContextMenu::render(Engine& engine)
     TTF_Font*   font = TTF_OpenFont(fullPath.c_str(), 16);
     if (!font)
     {
-        std::cerr << "Failed to load font: " << TTF_GetError() << std::endl;
+        std::cerr << "Failed to load font: " << TTF_GetError() << "\n";
         return;
     }
 
diff --git a/src/game/ui/context/RecruitingMenu.cpp b/src/game/ui/context/RecruitingMenu.cpp
index b69feaaf9a07adf2993b980e901f9badfd09bca1..6172c4f5f8ededa2659b244ab70f4e201534b7ba 100644
--- a/src/game/ui/context/RecruitingMenu.cpp
+++ b/src/game/ui/context/RecruitingMenu.cpp
@@ -7,30 +7,30 @@ namespace advanced_wars
 {
 RecruitingMenu::RecruitingMenu()
     : m_selectedOption(0), unitNames({
-                               {                UnitId::INFANTERY,    "Infantry"},
-                               {     UnitId::MECHANIZED_INFANTERY,     "Bazooka"},
-                               {                    UnitId::RECON,       "Recon"},
-                               {                      UnitId::APC,         "APC"},
-                               {                UnitId::ARTILLERY,   "Artillery"},
-                               {            UnitId::ANTI_AIR_TANK,     "AA Tank"},
-                               {UnitId::ANTI_AIR_MISSILE_LAUNCHER,   "Rocket AA"},
-                               {         UnitId::ROCKET_ARTILLERY,        "MLRS"},
-                               {              UnitId::MEDIUM_TANK, "Medium Tank"},
-                               {                 UnitId::NEO_TANK,    "Neo Tank"},
-                               {               UnitId::HEAVY_TANK,  "Heavy Tank"},
-                               {                   UnitId::LANDER,      "Lander"},
-                               {                  UnitId::CRUISER,     "Cruiser"},
-                               {                UnitId::SUBMARINE,   "Submarine"},
-                               {               UnitId::BATTLESHIP,  "Battleship"},
-                               {     UnitId::TRANSPORT_HELICOPTER,     "Chinook"},
-                               {        UnitId::BATTLE_HELICOPTER,  "Helicopter"},
-                               {                  UnitId::FIGHTER,     "Fighter"},
-                               {                   UnitId::BOMBER,      "Bomber"}
+                               {                UnitTypeId::INFANTERY,    "Infantry"},
+                               {     UnitTypeId::MECHANIZED_INFANTERY,     "Bazooka"},
+                               {                    UnitTypeId::RECON,       "Recon"},
+                               {                      UnitTypeId::APC,         "APC"},
+                               {                UnitTypeId::ARTILLERY,   "Artillery"},
+                               {            UnitTypeId::ANTI_AIR_TANK,     "AA Tank"},
+                               {UnitTypeId::ANTI_AIR_MISSILE_LAUNCHER,   "Rocket AA"},
+                               {         UnitTypeId::ROCKET_ARTILLERY,        "MLRS"},
+                               {              UnitTypeId::MEDIUM_TANK, "Medium Tank"},
+                               {                 UnitTypeId::NEO_TANK,    "Neo Tank"},
+                               {               UnitTypeId::HEAVY_TANK,  "Heavy Tank"},
+                               {                   UnitTypeId::LANDER,      "Lander"},
+                               {                  UnitTypeId::CRUISER,     "Cruiser"},
+                               {                UnitTypeId::SUBMARINE,   "Submarine"},
+                               {               UnitTypeId::BATTLESHIP,  "Battleship"},
+                               {     UnitTypeId::TRANSPORT_HELICOPTER,     "Chinook"},
+                               {        UnitTypeId::BATTLE_HELICOPTER,  "Helicopter"},
+                               {                  UnitTypeId::FIGHTER,     "Fighter"},
+                               {                   UnitTypeId::BOMBER,      "Bomber"}
 })
 {
 }
 
-void RecruitingMenu::setOptions(const std::vector<UnitId> recruitableUnits)
+void RecruitingMenu::setOptions(const std::vector<UnitTypeId> recruitableUnits)
 {
 
     m_options = recruitableUnits;
@@ -44,7 +44,7 @@ void RecruitingMenu::render(Engine& engine)
 
     if (TTF_Init() == -1)
     {
-        std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl;
+        std::cerr << "Failed to initialize TTF: " << TTF_GetError() << "\n";
         return;
     }
 
@@ -60,7 +60,7 @@ void RecruitingMenu::render(Engine& engine)
     TTF_Font*   font = TTF_OpenFont(fullPath.c_str(), 16);
     if (!font)
     {
-        std::cerr << "Failed to load font: " << TTF_GetError() << std::endl;
+        std::cerr << "Failed to load font: " << TTF_GetError() << "\n";
         return;
     }
 
@@ -76,7 +76,7 @@ void RecruitingMenu::render(Engine& engine)
     SDL_SetRenderDrawColor(engine.renderer(), 0, 0, 0, 255);
     int i = 0;
 
-    for (UnitId id : m_options)
+    for (UnitTypeId id : m_options)
     {
         // std::pair<std::string, int> unit_option = unitNames.at(cost2UnitId.at(cost));
         if (i == m_selectedOption)
@@ -97,7 +97,7 @@ void RecruitingMenu::render(Engine& engine)
         SDL_RenderCopy(engine.renderer(), textTexture, nullptr, &textRect);
 
         SDL_Texture* unit_texture = spritesheet->getUnitTextures()
-                                        .at(static_cast<int>(UnitFaction::URED))
+                                        .at(static_cast<int>(Faction::URED))
                                         .at(static_cast<int>(id))
                                         .at(static_cast<int>(UnitState::IDLE))
                                         .first;
@@ -154,7 +154,7 @@ void RecruitingMenu::update(int x, int y)
     this->m_y = y;
 }
 
-UnitId RecruitingMenu::getSelectedOption()
+UnitTypeId RecruitingMenu::getSelectedOption()
 {
     return m_selectedId;
 }
diff --git a/src/game/ui/context/RecruitingMenu.hpp b/src/game/ui/context/RecruitingMenu.hpp
index a5d988c309d754d98a19605be9255afc7cde775b..b37e60d45e9e57da26b7bc22bb5326ffcde7ffe2 100644
--- a/src/game/ui/context/RecruitingMenu.hpp
+++ b/src/game/ui/context/RecruitingMenu.hpp
@@ -10,7 +10,7 @@ class RecruitingMenu : public Scene
 {
 
     public:
-        UnitId getSelectedOption();
+        UnitTypeId getSelectedOption();
 
         void handleEvent(Engine& engine, SDL_Event& event);
 
@@ -18,18 +18,18 @@ class RecruitingMenu : public Scene
 
         RecruitingMenu();
 
-        void setOptions(const std::vector<UnitId> recruitableUnits);
+        void setOptions(const std::vector<UnitTypeId> recruitableUnits);
 
         void render(Engine& engine) override;
 
     private:
-        size_t                                        m_selectedOption;
-        std::vector<UnitId>                           m_options;
-        int                                           m_x;
-        int                                           m_y;
-        const std::unordered_map<UnitId, std::string> unitNames;
-        std::unordered_map<int, UnitId>               cost2UnitId;
-        UnitId                                        m_selectedId;
+        size_t                                            m_selectedOption;
+        std::vector<UnitTypeId>                           m_options;
+        int                                               m_x;
+        int                                               m_y;
+        const std::unordered_map<UnitTypeId, std::string> unitNames;
+        std::unordered_map<int, UnitTypeId>               cost2UnitId;
+        UnitTypeId                                        m_selectedId;
 
         void selectSprite();
 };
diff --git a/src/game/ui/menu/EndScreen.cpp b/src/game/ui/menu/EndScreen.cpp
index 5c3f7a33f66f06f2eaa9f6178d359b7464598c6f..ad33b22394cbca09522aa69ff75c8114c2eb76eb 100644
--- a/src/game/ui/menu/EndScreen.cpp
+++ b/src/game/ui/menu/EndScreen.cpp
@@ -8,26 +8,26 @@ namespace advanced_wars
 {
 Endscreen::Endscreen(Player& player) : m_moenyLeft(player.getMoney())
 {
-    std::cout << "Player faction: " << static_cast<int>(player.getFaction()) << std::endl;
+    std::cout << "Player faction: " << static_cast<int>(player.getFaction()) << "\n";
     switch (player.getFaction())
     {
-    case UnitFaction::UBLUE:
+    case Faction::UBLUE:
         m_color = {0, 0, 255, 255};
         m_playerString = "Blue";
         break;
-    case UnitFaction::UGREEN:
+    case Faction::UGREEN:
         m_color = {0, 255, 0, 255};
         m_playerString = "Green";
         break;
-    case UnitFaction::UPURPLE:
+    case Faction::UPURPLE:
         m_color = {255, 0, 255, 255};
         m_playerString = "Purple";
         break;
-    case UnitFaction::URED:
+    case Faction::URED:
         m_color = {255, 0, 0, 255};
         m_playerString = "Red";
         break;
-    case UnitFaction::UYELLOW:
+    case Faction::UYELLOW:
         m_color = {255, 255, 0, 255};
         m_playerString = "Yellow";
         break;
@@ -44,7 +44,7 @@ void Endscreen::render(Engine& engine)
 
     if (TTF_Init() == -1)
     {
-        std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl;
+        std::cerr << "Failed to initialize TTF: " << TTF_GetError() << "\n";
         return;
     }
     // Draw Background
@@ -54,7 +54,7 @@ void Endscreen::render(Engine& engine)
     SDL_Surface* backgroundSurface = IMG_Load(fullPath.c_str());
     if (!backgroundSurface)
     {
-        std::cerr << "Failed to load background image: " << IMG_GetError() << std::endl;
+        std::cerr << "Failed to load background image: " << IMG_GetError() << "\n";
         return;
     }
 
diff --git a/src/game/ui/menu/Menu.cpp b/src/game/ui/menu/Menu.cpp
index 3efb242b4547040f7a544be4760f67b49e090b8b..efdbb448af97afa3229f58c6a15564fed1636992 100644
--- a/src/game/ui/menu/Menu.cpp
+++ b/src/game/ui/menu/Menu.cpp
@@ -33,10 +33,12 @@ void Menu::render(Engine& engine)
 {
     if (TTF_Init() == -1)
     {
-        std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl;
+        std::cerr << "Failed to initialize TTF: " << TTF_GetError() << "\n";
         return;
     }
 
+    int windowWidth = engine.getWindow().w();
+
     if (m_backgroundTexture)
     {
         SDL_RenderCopy(engine.renderer(), m_backgroundTexture, nullptr, nullptr);
@@ -53,7 +55,7 @@ void Menu::render(Engine& engine)
     TTF_Font*   titleFont = TTF_OpenFont(fullPath.c_str(), 48);
     if (!titleFont)
     {
-        std::cerr << "Failed to load title font: " << fullPath << TTF_GetError() << std::endl;
+        std::cerr << "Failed to load title font: " << fullPath << TTF_GetError() << "\n";
         return;
     }
 
@@ -61,7 +63,7 @@ void Menu::render(Engine& engine)
     if (!menuFont)
     {
         TTF_CloseFont(titleFont);
-        std::cerr << "Failed to load menu font: " << fullPath << TTF_GetError() << std::endl;
+        std::cerr << "Failed to load menu font: " << fullPath << TTF_GetError() << "\n";
         return;
     }
 
@@ -73,7 +75,8 @@ void Menu::render(Engine& engine)
     {
         SDL_Texture* titleTexture = SDL_CreateTextureFromSurface(engine.renderer(), titleSurface);
         SDL_Rect     titleRect = {
-            static_cast<int>((800 - titleSurface->w) / 2), 50, titleSurface->w, titleSurface->h};
+            static_cast<int>((windowWidth - titleSurface->w) / 2), 50, titleSurface->w,
+            titleSurface->h};
         SDL_RenderCopy(engine.renderer(), titleTexture, nullptr, &titleRect);
         SDL_DestroyTexture(titleTexture);
         SDL_FreeSurface(titleSurface);
@@ -87,13 +90,11 @@ void Menu::render(Engine& engine)
         {
             continue;
         }
-
         SDL_Texture* textTexture = SDL_CreateTextureFromSurface(engine.renderer(), textSurface);
         SDL_Rect     textRect = {
-            static_cast<int>((800 - textSurface->w) / 2), static_cast<int>(150 + i * 50),
+            static_cast<int>((windowWidth - textSurface->w) / 2), static_cast<int>(150 + i * 50),
             textSurface->w, textSurface->h};
         SDL_RenderCopy(engine.renderer(), textTexture, nullptr, &textRect);
-
         SDL_DestroyTexture(textTexture);
         SDL_FreeSurface(textSurface);
     }
@@ -120,93 +121,17 @@ void Menu::handleEvent(Engine& engine, SDL_Event& event)
         {
             if (m_options[m_selectedOption] == "Exit")
             {
-                std::cout << "Exiting game..." << std::endl;
+                std::cout << "Exiting game..." << "\n";
                 engine.exit();
             }
             else if (m_options[m_selectedOption] == "Start Game")
             {
-                std::cout << "Starting game..." << std::endl;
-
-                // Construct a level
-                std::vector<Tile> tiles;
-                for (int y = 0; y < 20; y++)
-                {
-                    for (int x = 0; x < 20; x++)
-                    {
-                        tiles.push_back(Tile(TileId::PLAIN, x, y));
-                    }
-                }
-
-                // Fill the edges with water
-                for (size_t n = 0; n < 20; n++)
-                {
-                    // Vertical
-                    tiles.at(n * 20) = Tile(TileId::WATER, 0, n);
-                    tiles.at(n * 20 + 19) = Tile(TileId::WATER, 19, n);
-                    // Horizontal
-                    tiles.at(n) = Tile(TileId::WATER, n, 0);
-                    tiles.at(19 * 20 + n) = Tile(TileId::WATER, n, 19);
-                }
-
-                // Make the edges cliffs
-                for (size_t n = 1; n < 19; n++)
-                {
-                    // Vertical
-                    tiles.at(n * 20 + 1) = Tile(TileId::CLIFF_RIGHT, 1, n);
-                    tiles.at(n * 20 + 18) = Tile(TileId::CLIFF_LEFT, 18, n);
-
-                    // Horizontal
-                    tiles.at(20 + n) = Tile(TileId::CLIFF_BOTTOM, n, 1);
-                    tiles.at(18 * 20 + n) = Tile(TileId::CLIFF_TOP, n, 18);
-                }
-
-                // Fix the corners
-                tiles.at(20 + 1) = Tile(TileId::CLIFF_CORNER_TOP_LEFT, 1, 1);
-                tiles.at(20 + 18) = Tile(TileId::CLIFF_CORNER_TOP_RIGHT, 18, 1);
-                tiles.at(18 * 20 + 1) = Tile(TileId::CLIFF_CORNER_BOTTOM_LEFT, 1, 18);
-                tiles.at(18 * 20 + 18) = Tile(TileId::CLIFF_CORNER_BOTTOM_RIGHT, 18, 18);
-
-                // Buildings
-                std::vector<Building> buildings;
-
-                for (int y = 0; y < 6; y++)
-                {
-                    for (int x = 0; x < 5; x++)
-                    {
-                        BuildingId      id = static_cast<BuildingId>(x);
-                        BuildingFaction faction = static_cast<BuildingFaction>(y);
-
-                        buildings.push_back(Building(3 + x, 3 + 2 * y, id, faction));
-                    }
-                }
-
-                Config config = Config("../config.xml");
-                // Units
-                std::vector<Unit> units;
-
-                for (int y = 0; y < 19; y++)
-                {
-                    for (int x = 0; x < 6; x++)
-                    {
-                        units.push_back(Unit(
-                            x + 9, y + 2, UnitFaction::URED, static_cast<UnitId>(y),
-                            static_cast<UnitState>(x), config));
-                    }
-                }
-
-                std::vector<Effect> effects(
-                    {Effect(3, 15, EffectId::LAND_EXPLOSION, false),
-                     Effect(5, 15, EffectId::AIR_EXPLOSION, true),
-                     Effect(5, 18, EffectId::NAVAL_EXPLOSION, true)});
-
-                std::shared_ptr<Level> level = std::make_shared<Level>(
-                    "Osnabrück", 20, 20, tiles, buildings, units, effects, std::queue<Player>{});
-
-                engine.pushScene(Level::loadLevel(m_level_filepath, engine));
+                std::cout << "Starting game..." << "\n";
+                engine.startGame(m_level_filepath);
             }
             else if (m_options[m_selectedOption] == "Options")
             {
-                std::cout << "Opening options..." << std::endl;
+                std::cout << "Opening options..." << "\n";
             }
         }
     }
@@ -218,7 +143,7 @@ void Menu::loadBackground(Engine& engine, const std::string& imagePath)
     SDL_Surface* backgroundSurface = IMG_Load(imagePath.c_str());
     if (!backgroundSurface)
     {
-        std::cerr << "Failed to load background image: " << IMG_GetError() << std::endl;
+        std::cerr << "Failed to load background image: " << IMG_GetError() << "\n";
         return;
     }
 
@@ -230,7 +155,7 @@ void Menu::loadBackground(Engine& engine, const std::string& imagePath)
 
     if (!m_backgroundTexture)
     {
-        std::cerr << "Failed to create background texture: " << SDL_GetError() << std::endl;
+        std::cerr << "Failed to create background texture: " << SDL_GetError() << "\n";
     }
 }
 
diff --git a/src/game/ui/menu/PauseMenu.cpp b/src/game/ui/menu/PauseMenu.cpp
index 026d206214acc6eb8824f00ace595be0152e196c..3bf5679dd17b81be64b301e9658834bc98ddd507 100644
--- a/src/game/ui/menu/PauseMenu.cpp
+++ b/src/game/ui/menu/PauseMenu.cpp
@@ -14,7 +14,7 @@ PauseMenu::PauseMenu(int selectedOption, SDL_Texture* backgroundTexture)
     // Initialize SDL_ttf
     if (TTF_Init() == -1)
     {
-        std::cerr << "Failed to initialize SDL_ttf: " << TTF_GetError() << std::endl;
+        std::cerr << "Failed to initialize SDL_ttf: " << TTF_GetError() << "\n";
     }
 
     if (!m_backgroundTexture)
@@ -37,7 +37,7 @@ void PauseMenu::render(Engine& engine)
 {
     if (TTF_Init() == -1)
     {
-        std::cerr << "Failed to initialize SDL_ttf: " << TTF_GetError() << std::endl;
+        std::cerr << "Failed to initialize SDL_ttf: " << TTF_GetError() << "\n";
     }
 
     SDL_Renderer* renderer = engine.renderer();
@@ -59,7 +59,7 @@ void PauseMenu::render(Engine& engine)
     TTF_Font* font = TTF_OpenFont(fullPath.c_str(), 24);
     if (!font)
     {
-        std::cerr << "Failed to load menu font: " << fullPath << " " << TTF_GetError() << std::endl;
+        std::cerr << "Failed to load menu font: " << fullPath << " " << TTF_GetError() << "\n";
         return;
     }
 
@@ -96,7 +96,7 @@ void PauseMenu::handleEvent(Engine& engine, SDL_Event& event)
         }
         else if (event.key.keysym.sym == SDLK_ESCAPE)
         {
-            std::cout << "Resuming game..." << std::endl;
+            std::cout << "Resuming game..." << "\n";
             engine.popScene();
         }
         else if (event.key.keysym.sym == SDLK_RETURN)
@@ -104,13 +104,13 @@ void PauseMenu::handleEvent(Engine& engine, SDL_Event& event)
             if (m_options[m_selectedOption] == "Exit")
             {
                 // exit into main menu
-                std::cout << "Exiting game..." << std::endl;
+                std::cout << "Exiting game..." << "\n";
                 engine.returnToMenu();
             }
             else if (m_options[m_selectedOption] == "Resume")
             {
                 // resume game
-                std::cout << "Resuming game..." << std::endl;
+                std::cout << "Resuming game..." << "\n";
                 engine.popScene();
             }
         }
@@ -123,7 +123,7 @@ void PauseMenu::loadBackground(Engine& engine, const std::string& imagePath)
     SDL_Surface* surface = IMG_Load(imagePath.c_str());
     if (!surface)
     {
-        std::cerr << "Failed to load image: " << IMG_GetError() << std::endl;
+        std::cerr << "Failed to load image: " << IMG_GetError() << "\n";
         return;
     }
     m_backgroundTexture = SDL_CreateTextureFromSurface(engine.renderer(), surface);
diff --git a/src/game/ui/modals/HelpMenu.cpp b/src/game/ui/modals/HelpMenu.cpp
index 9902bb50bba1b0559638f76f2648bf1772ce4eba..dc62236b4510821e51a636afe5c0f9a9f877a4c8 100644
--- a/src/game/ui/modals/HelpMenu.cpp
+++ b/src/game/ui/modals/HelpMenu.cpp
@@ -33,7 +33,7 @@ void HelpMenu::render(advanced_wars::Engine& engine)
 {
     if (TTF_Init() == -1)
     {
-        std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl;
+        std::cerr << "Failed to initialize TTF: " << TTF_GetError() << "\n";
         return;
     }
 
@@ -43,7 +43,7 @@ void HelpMenu::render(advanced_wars::Engine& engine)
     TTF_Font*   font = TTF_OpenFont(fullPath.c_str(), 16);
     if (!font)
     {
-        std::cerr << "Failed to load font: " << TTF_GetError() << std::endl;
+        std::cerr << "Failed to load font: " << TTF_GetError() << "\n";
         return;
     }
 
diff --git a/src/game/ui/modals/UnitInfoMenu.cpp b/src/game/ui/modals/UnitInfoMenu.cpp
index db84ebfe6cd23bdd23b6ef1572a000a1dce8b073..3fc2284b143d7b1fafe00e6319529489d2a44cc9 100644
--- a/src/game/ui/modals/UnitInfoMenu.cpp
+++ b/src/game/ui/modals/UnitInfoMenu.cpp
@@ -31,30 +31,33 @@ std::string UnitInfoMenu::getMovementTypeString(MovementType type)
     }
 }
 
-std::unordered_map<UnitId, std::string> unitDescriptions = {
-    {                UnitId::INFANTERY,"Infanterie   Kostenguenstig   und   vielseitig   einsetzbar"                                       },
-    {     UnitId::MECHANIZED_INFANTERY,
-     "Mech-Infanterie   Stark   gegen   Panzer   langsam   aber   effizient"                                   },
-    {                    UnitId::RECON,       "Aufklaerung   Schnell   und   ideal   für   frühe   Aufklaerung"},
-    {              UnitId::MEDIUM_TANK,    "Mittlerer   Panzer   Guter   Allrounder   stark   und   ausgewogen"},
-    {               UnitId::HEAVY_TANK, "Schwerer   Panzer   Langsam   aber   sehr   stark   und   beschützend"},
-    {                 UnitId::NEO_TANK,             "Neo Tank   Einer der besten Panzer   stark und vielseitig"},
-    {                      UnitId::APC,         "Transporter   Traeger fuer Infanterie   keine Offensivkraefte"},
-    {            UnitId::ANTI_AIR_TANK,                         "FlugabwehrPanzer   Ideal zur Luftverteidigung"},
-    {                UnitId::ARTILLERY,  "Artillerie   Kann aus Distanz zufuegen   aber verletzbar im Nahkampf"},
-    {         UnitId::ROCKET_ARTILLERY,
-     "Raketenartillerie   Grosse Reichweite   ideal fuer defensive Taktiken"                                   },
-    {UnitId::ANTI_AIR_MISSILE_LAUNCHER,
-     "Raketenwerfer   Kann Flugeinheiten auf grosse Distanz angreifen"                                         },
-    {                  UnitId::FIGHTER,                                "Jaeger   Ideal fuer Luftueberlegenheit"},
-    {                   UnitId::BOMBER,
-     "Bomber   Stark gegen Boden- und Seeziele   aber verletzbar gegen Luft-und Flak"                          },
-    {        UnitId::BATTLE_HELICOPTER,         "Kampfhubschrauber   Stark gegen Bodenfahrzeuge und Infanterie"},
-    {     UnitId::TRANSPORT_HELICOPTER,         "Transporthubschrauber   Kann Einheiten schnell transportieren"},
-    {               UnitId::BATTLESHIP,              "Schlachtschiff   Langreichweitenangriff auf See und Land"},
-    {                  UnitId::CRUISER,                "Kreuzer   Verteidigung gegen Luft und U-Boot-Einheiten"},
-    {                   UnitId::LANDER,                             "Landungsschiff   Transport und Versorgung"},
-    {                UnitId::SUBMARINE,           "U-Boot   Versteckt sich und kann Ueberwasserziele angreifen"}
+std::unordered_map<UnitTypeId, std::string> unitDescriptions = {
+    {                UnitTypeId::INFANTERY,"Infanterie   Kostenguenstig   und   vielseitig   einsetzbar"                                           },
+    {     UnitTypeId::MECHANIZED_INFANTERY,
+     "Mech-Infanterie   Stark   gegen   Panzer   langsam   aber   effizient"                                      },
+    {                    UnitTypeId::RECON,      "Aufklaerung   Schnell   und   ideal   für   frühe   Aufklaerung"},
+    {              UnitTypeId::MEDIUM_TANK,   "Mittlerer   Panzer   Guter   Allrounder   stark   und   ausgewogen"},
+    {               UnitTypeId::HEAVY_TANK,
+     "Schwerer   Panzer   Langsam   aber   sehr   stark   und   beschützend"                                      },
+    {                 UnitTypeId::NEO_TANK,            "Neo Tank   Einer der besten Panzer   stark und vielseitig"},
+    {                      UnitTypeId::APC,        "Transporter   Traeger fuer Infanterie   keine Offensivkraefte"},
+    {            UnitTypeId::ANTI_AIR_TANK,                        "FlugabwehrPanzer   Ideal zur Luftverteidigung"},
+    {                UnitTypeId::ARTILLERY, "Artillerie   Kann aus Distanz zufuegen   aber verletzbar im Nahkampf"},
+    {         UnitTypeId::ROCKET_ARTILLERY,
+     "Raketenartillerie   Grosse Reichweite   ideal fuer defensive Taktiken"                                      },
+    {UnitTypeId::ANTI_AIR_MISSILE_LAUNCHER,
+     "Raketenwerfer   Kann Flugeinheiten auf grosse Distanz angreifen"                                            },
+    {                  UnitTypeId::FIGHTER,                               "Jaeger   Ideal fuer Luftueberlegenheit"},
+    {                   UnitTypeId::BOMBER,
+     "Bomber   Stark gegen Boden- und Seeziele   aber verletzbar gegen Luft-und Flak"                             },
+    {        UnitTypeId::BATTLE_HELICOPTER,
+     "Kampfhubschrauber   Stark gegen Bodenfahrzeuge und Infanterie"                                              },
+    {     UnitTypeId::TRANSPORT_HELICOPTER,
+     "Transporthubschrauber   Kann Einheiten schnell transportieren"                                              },
+    {               UnitTypeId::BATTLESHIP,             "Schlachtschiff   Langreichweitenangriff auf See und Land"},
+    {                  UnitTypeId::CRUISER,               "Kreuzer   Verteidigung gegen Luft und U-Boot-Einheiten"},
+    {                   UnitTypeId::LANDER,                            "Landungsschiff   Transport und Versorgung"},
+    {                UnitTypeId::SUBMARINE,          "U-Boot   Versteckt sich und kann Ueberwasserziele angreifen"}
 };
 
 void UnitInfoMenu::handleEvent(Engine& engine, SDL_Event& event)
@@ -78,7 +81,7 @@ void UnitInfoMenu::render(Engine& engine)
     // TTF Initialisierung
     if (TTF_Init() == -1)
     {
-        std::cerr << "TTF konnte nicht initialisiert werden: " << TTF_GetError() << std::endl;
+        std::cerr << "TTF konnte nicht initialisiert werden: " << TTF_GetError() << "\n";
         return;
     }
 
@@ -88,13 +91,13 @@ void UnitInfoMenu::render(Engine& engine)
 
     if (!font)
     {
-        std::cerr << "Failed to load font: " << TTF_GetError() << std::endl;
+        std::cerr << "Failed to load font: " << TTF_GetError() << "\n";
         return;
     }
 
-    SDL_Color yellow = {255, 255, 0, 255}; // Gelb für den Text
-    int       spacing = 10;                // Abstand zwischen den Textzeilen
-    UnitId    unitId = m_currentUnit->getId();
+    SDL_Color  yellow = {255, 255, 0, 255}; // Gelb für den Text
+    int        spacing = 10;                // Abstand zwischen den Textzeilen
+    UnitTypeId unitId = m_currentUnit->getUnitTypeId();
 
     // Textzeilen, einschließlich der Beschreibung
     std::vector<std::string> info_lines = {
diff --git a/src/util/Dimensions.hpp b/src/util/Dimensions.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ffc679de95fd1d5722d5d2a1bcd78abf50db62fb
--- /dev/null
+++ b/src/util/Dimensions.hpp
@@ -0,0 +1,42 @@
+namespace advanced_wars
+{
+
+constexpr float PIXELS_PER_METER = 16.0f;
+
+/// Tile → Pixel
+inline int tileToPixel(int tile)
+{
+    return tile * 16;
+}
+
+/// Pixel → Tile
+inline int pixelToTile(int pixel)
+{
+    return pixel / 16;
+}
+
+/// Box2D (Meter) → Pixel
+inline float worldToPixel(float world)
+{
+    return world * PIXELS_PER_METER;
+}
+
+/// Pixel → Box2D (Meter)
+inline float pixelToWorld(float pixel)
+{
+    return pixel / PIXELS_PER_METER;
+}
+
+/// Tile → Box2D (Meter) (Oberer linker Punkt des Tiles)
+inline float tileToWorld(int tile)
+{
+    return pixelToWorld(tileToPixel(tile));
+}
+
+/// Box2D (Meter) → Tile (Berechnung über Pixel)
+inline int worldToTile(float world)
+{
+    return pixelToTile(worldToPixel(world));
+}
+
+} // namespace advanced_wars