diff --git a/game/src/BulletObject.cpp b/game/src/BulletObject.cpp
index 423a15cc30ddab1cddf99af7e3845b5dbb4d4cb3..a1192c71bd82398100e9db45934b6b216f4fd3b9 100644
--- a/game/src/BulletObject.cpp
+++ b/game/src/BulletObject.cpp
@@ -2,7 +2,7 @@
 
 BulletObject::BulletObject(b2World *world, const b2Vec2 &position, const b2Vec2 &size, float density, float scale,
                            float friction, const std::vector<int> &tileIDs)
-    : DynamicObject(world, position, size, density, scale, friction, tileIDs)
+    : DynamicObject(world, position, size, density, scale, friction, tileIDs, true)
 {
     m_body->SetLinearDamping(0.0f);
 }
diff --git a/game/src/DynamicObject.cpp b/game/src/DynamicObject.cpp
index ccbca68a74dd1eed5d11b9d029f811aa6ddbd105..4ee347d49d02626424b7f88ba2ba71e37c4bba01 100644
--- a/game/src/DynamicObject.cpp
+++ b/game/src/DynamicObject.cpp
@@ -1,8 +1,8 @@
 #include "DynamicObject.hpp"
 
 DynamicObject::DynamicObject(b2World *world, const b2Vec2 &position, const b2Vec2 &size, float density, float scale,
-                             float friction, const std::vector<int> &tileIDs)
-    : GameObject(world, position, size, density, scale, friction, tileIDs)
+                             float friction, const std::vector<int> &tileIDs, bool isBullet)
+    : GameObject(world, position, size, density, scale, friction, tileIDs, isBullet, true)
 {
     m_body->SetLinearDamping(3.0f);
 }
\ No newline at end of file
diff --git a/game/src/DynamicObject.hpp b/game/src/DynamicObject.hpp
index 247f01df4cb287b88022f2594143ef276ba60b99..1ab60ba74144a862f38ecb168da028f6f31afb69 100644
--- a/game/src/DynamicObject.hpp
+++ b/game/src/DynamicObject.hpp
@@ -28,5 +28,5 @@ class DynamicObject : public GameObject
      * @param tileIDs The tile IDs representing the object's texture in the tilesheet.
      */
     DynamicObject(b2World *world, const b2Vec2 &position, const b2Vec2 &size, float density, float scale,
-                  float friction, const std::vector<int> &tileIDs);
+                  float friction, const std::vector<int> &tileIDs, bool isBullet);
 };
diff --git a/game/src/Enemy.cpp b/game/src/Enemy.cpp
index e61abf896562bc2395a2e84322d5d7a7d7479c26..6bdb9622810d35c014f79358f8a85224a17f603b 100644
--- a/game/src/Enemy.cpp
+++ b/game/src/Enemy.cpp
@@ -2,9 +2,9 @@
 #include <box2d/b2_math.h>
 
 Enemy::Enemy(b2World *world, const b2Vec2 &position, const b2Vec2 &size, float density, float scale, float friction,
-             BulletManager &bulletmanager, const std::vector<int> &tileIDs)
-    : DynamicObject(world, position, size, density, scale, friction, tileIDs), m_lastFire(1000), m_fireRate(2),
-      m_fireDelay(static_cast<Uint32>(std::round(1000.0 / m_fireRate)))
+             BulletManager &bulletmanager, const std::vector<int> &tileIDs, int health, int damage)
+    : DynamicObject(world, position, size, density, scale, friction, tileIDs, false), m_lastFire(1000), m_fireRate(2),
+      m_fireDelay(static_cast<Uint32>(std::round(1000.0 / m_fireRate))), m_health(health), m_damage(damage)
 {
     m_body->GetUserData().pointer = 4; // 4 = Enemy (idenfier for contact listener)
 }
@@ -30,6 +30,11 @@ void Enemy::set_fireRate(int rate)
     m_fireDelay = static_cast<Uint32>(std::round(1000.0 / m_fireRate));
 }
 
+void Enemy::take_damage(int damage)
+{
+    m_health-=damage;
+}
+
 b2Body *Enemy::getBody()
 {
     return m_body;
diff --git a/game/src/Enemy.hpp b/game/src/Enemy.hpp
index b07b141e2771ed8df98350ef87f1465550155fb1..c8d16893c44cbc4904ef20000fd47b7ca5b1af56 100644
--- a/game/src/Enemy.hpp
+++ b/game/src/Enemy.hpp
@@ -30,7 +30,7 @@ class Enemy : public DynamicObject
      * @param tileIDs The tile IDs representing the enemy's texture in the tilesheet.
      */
     Enemy(b2World *world, const b2Vec2 &position, const b2Vec2 &size, float density, float scale, float friction,
-          BulletManager &bulletmanager, const std::vector<int> &tileIDs);
+          BulletManager &bulletmanager, const std::vector<int> &tileIDs, int health, int damage);
 
     /**
      * @brief Retrieves the Enemy's physics body.
@@ -50,6 +50,8 @@ class Enemy : public DynamicObject
      */
     bool shoot(const b2Vec2 &playerPosition, BulletManager &bulletManager);
 
+    void take_damage(int damage);
+
     /**
      * @brief Sets the enemy's fire rate.
      *
@@ -60,8 +62,8 @@ class Enemy : public DynamicObject
     void set_fireRate(int rate);
 
   private:
-    int health;         /**< The health of the enemy, representing its hit points. */
-    int damage;         /**< The amount of damage the enemy can inflict on other objects. */
+    int m_health;         /**< The health of the enemy, representing its hit points. */
+    int m_damage;         /**< The amount of damage the enemy can inflict on other objects. */
     int m_fireRate;     /**< The rate at which the enemy can fire projectiles. */
     Uint32 m_fireDelay; /**< The delay between shots in milliseconds. */
     Uint32 m_lastFire;  /**< The timestamp of the last shot fired. */
diff --git a/game/src/EnemyManager.cpp b/game/src/EnemyManager.cpp
index 137a800c6febdd8609e1a4d9d9deff080239af36..5e2c732735a67c89dd1962f4c9e0a2617217a75a 100644
--- a/game/src/EnemyManager.cpp
+++ b/game/src/EnemyManager.cpp
@@ -15,10 +15,10 @@ EnemyManager::~EnemyManager()
     m_enemies.clear();
 }
 
-void EnemyManager::addEnemy(const b2Vec2 &position, const std::vector<int32_t> &spriteIDs)
+void EnemyManager::addEnemy(const b2Vec2 &position, const std::vector<int32_t> &spriteIDs, int health, int damage)
 {
     Enemy *newEnemy = new Enemy(m_world, position, b2Vec2(16.0f, 16.0f), 1.0f, m_tilesheetManager.getGameScale(), 1.0f,
-                                m_bulletManager, spriteIDs);
+                                m_bulletManager, spriteIDs, health, damage);
     m_enemies.emplace_back(newEnemy);
 }
 
diff --git a/game/src/EnemyManager.hpp b/game/src/EnemyManager.hpp
index 1d78ce27389263d0f2c09abee949875cdb456201..215a977ffa0fefddd4d49d4a1b3b4d91a7e49fdf 100644
--- a/game/src/EnemyManager.hpp
+++ b/game/src/EnemyManager.hpp
@@ -49,7 +49,7 @@ class EnemyManager
      *
      * @param position The position where the new enemy will be placed in the world.
      */
-    void addEnemy(const b2Vec2 &position, const std::vector<int32_t> &spriteIDs);
+    void addEnemy(const b2Vec2 &position, const std::vector<int32_t> &spriteIDs, int health, int damage);
 
     /**
      * @brief Handles the random shooting of enemy projectiles.
diff --git a/game/src/GameContext.cpp b/game/src/GameContext.cpp
index 26bb3bb5abd071e15adf3d928a74c32f832ffd28..9ce70d735ea21f2868c052280896c123b2c0fa45 100644
--- a/game/src/GameContext.cpp
+++ b/game/src/GameContext.cpp
@@ -31,7 +31,7 @@ void GameContext::loadRoom(const lvl::Room &next_room)
     {
         b2Vec2 enemy_pos = {static_cast<float>(enemy_it->position.x * m_tileSize),
                             static_cast<float>(enemy_it->position.y * m_tileSize)};
-        m_enemyManager.addEnemy(enemy_pos, m_level.getEnemies().at(enemy_it->id).getSprites());
+        m_enemyManager.addEnemy(enemy_pos, m_level.getEnemies().at(enemy_it->id).getSprites(), m_level.getEnemies()[0].getHealth(), 5);
     }
 
     const std::unordered_set<int> valid_ids = {102, 103, 104, 134, 135, 136, 166, 167, 168, 198, 199}; // door ids
diff --git a/game/src/GameObject.cpp b/game/src/GameObject.cpp
index e99398442f18087ed4dfdbc6ed97237e767eddc0..dd8bc80bc7f9b81e5967a9c066d6129789f1020e 100644
--- a/game/src/GameObject.cpp
+++ b/game/src/GameObject.cpp
@@ -1,8 +1,9 @@
 #include "GameObject.hpp"
 #include "TilesheetManager.hpp"
+#include <box2d/b2_body.h>
 
 GameObject::GameObject(b2World *world, const b2Vec2 &position, const b2Vec2 &size, float density, float scale,
-                       float friction, const std::vector<int> &tileIDs)
+                       float friction, const std::vector<int> &tileIDs, bool isBullet, bool isDynamic)
     : m_world(world), m_size(scale * size), m_frameDuration(0.0f), m_lastFrameSwitch(0.0f), m_currentFrame(tileIDs[0]),
       m_firstFrame(tileIDs[0]), m_lastFrame(m_firstFrame + tileIDs.size() - 1), m_tileIDs(tileIDs)
 {
@@ -10,7 +11,14 @@ GameObject::GameObject(b2World *world, const b2Vec2 &position, const b2Vec2 &siz
     // Box2D
     m_pixelsPerMeterScaled = pixelsPerMeter * scale;
     b2BodyDef bodyDef;
-    bodyDef.type = b2_dynamicBody;
+    if(isDynamic)
+    {
+        bodyDef.type = b2_dynamicBody;
+    }
+    else 
+    {
+        bodyDef.type = b2_staticBody;
+    }
     b2Vec2 scaledPosition = {position.x / m_pixelsPerMeterScaled, position.y / m_pixelsPerMeterScaled};
     bodyDef.position = scaledPosition;
     m_body = m_world->CreateBody(&bodyDef);
@@ -24,6 +32,10 @@ GameObject::GameObject(b2World *world, const b2Vec2 &position, const b2Vec2 &siz
     fixtureDef.shape = &boxShape;
     fixtureDef.density = density;
     fixtureDef.friction = friction;
+    if(isBullet)
+    {
+        fixtureDef.filter.groupIndex = -1;
+    }
 
     m_body->CreateFixture(&fixtureDef);
 
diff --git a/game/src/GameObject.hpp b/game/src/GameObject.hpp
index 486346b7e7fd677b44e466abb63623f11017a53d..d271b5d8b27a141124a835cf3f36318b4276edf2 100644
--- a/game/src/GameObject.hpp
+++ b/game/src/GameObject.hpp
@@ -34,7 +34,7 @@ class GameObject
      * @param tileIDs The list of tile IDs representing the animation frames for the object.
      */
     GameObject(b2World *world, const b2Vec2 &position, const b2Vec2 &size, float density, float scale, float friction,
-               const std::vector<int> &tileIDs);
+               const std::vector<int> &tileIDs, bool isBullet, bool isDynamic);
 
     /**
      * @brief Destructor for the GameObject class.
diff --git a/game/src/GameWindow.cpp b/game/src/GameWindow.cpp
index 58aad669636dfc3d715eb5f6060f82158807f33a..82a838097610c88d11c6bbdf8844922a47d5a931 100644
--- a/game/src/GameWindow.cpp
+++ b/game/src/GameWindow.cpp
@@ -9,7 +9,7 @@ GameWindow::GameWindow(const int32_t width, const int32_t height, const float_t
       m_objectManager(m_level, &m_world, m_tilesheetManager),
       m_player(&m_world, b2Vec2({static_cast<float>(width) / 2, static_cast<float>(height) / 2}),
                b2Vec2({16.0f, 16.0f}), 1.0f, m_Scale, 1.0f, m_bulletManager, m_tilesheetManager,
-               m_level.getPlayer().getSprites()),
+               m_level.getPlayer().getSprites(), m_level.getPlayer().getHealth(), 5),
       m_gameContext(m_level, m_enemyManager, m_bulletManager, m_tilesheetManager, m_objectManager),
       m_Camera(width, height, m_level.getRooms().at(2).getWidth() * m_level.getSpritesheet().getTileSize() * m_Scale,
                m_level.getRooms().at(2).getHeight() * m_level.getSpritesheet().getTileSize() * m_Scale)
diff --git a/game/src/Player.cpp b/game/src/Player.cpp
index 9f96bf9e150d6814fe2b2e83248a6beb7676a37a..3c2572ef1228155bcc9a5d0836259db9895a7058 100644
--- a/game/src/Player.cpp
+++ b/game/src/Player.cpp
@@ -1,10 +1,12 @@
 #include "Player.hpp"
 
 Player::Player(b2World *world, const b2Vec2 &position, const b2Vec2 &size, float density, float scale, float friction,
-               BulletManager &bulletmanager, TilesheetManager &tilesheetManager, const std::vector<int> &tileIDs)
-    : DynamicObject(world, position, size, density, scale, friction, tileIDs), m_alive(true),
+               BulletManager &bulletmanager, TilesheetManager &tilesheetManager, const std::vector<int> &tileIDs, int health, int damage)
+    : DynamicObject(world, position, size, density, scale, friction, tileIDs, false), m_alive(true),
       m_bulletManager(bulletmanager), m_lastFire(1000), m_fireRate(5),
-      m_fireDelay(static_cast<Uint32>(std::round(1000.0 / m_fireRate)))
+      m_fireDelay(static_cast<Uint32>(std::round(1000.0 / m_fireRate))),
+      m_health(health),
+      m_damage(damage)
 {
     m_body->GetUserData().pointer = 2; // 2 = Player (idenfier for contact listener)
 }
@@ -97,3 +99,8 @@ void Player::set_fireRate(int rate) // if items are ever implemented, this will
     m_fireRate = rate;
     m_fireDelay = static_cast<Uint32>(std::round(1000.0 / m_fireRate));
 }
+
+void Player::take_damage(int damage)
+{
+    m_health-=damage;
+}
diff --git a/game/src/Player.hpp b/game/src/Player.hpp
index 9f4a8d9cecb45d5ffb287c58a30d483ad53741fd..92ca0cebf7e44a0d97cef1047a50967ec2b719e8 100644
--- a/game/src/Player.hpp
+++ b/game/src/Player.hpp
@@ -29,7 +29,7 @@ class Player : public DynamicObject
      * @param tileIDs The tile IDs representing the player's texture in the tilesheet.
      */
     Player(b2World *world, const b2Vec2 &position, const b2Vec2 &size, float density, float scale, float friction,
-           BulletManager &bulletmanager, TilesheetManager &tilesheetManager, const std::vector<int> &tileIDs);
+           BulletManager &bulletmanager, TilesheetManager &tilesheetManager, const std::vector<int> &tileIDs, int health, int damage);
 
     /**
      * @brief Destructor for the Player class.
@@ -68,9 +68,12 @@ class Player : public DynamicObject
      */
     void set_fireRate(int rate);
 
+    void take_damage(int damage);
+
   private:
     bool m_alive;                   /**< A flag indicating if the player is alive. */
     int m_health;                   /**< The player's health value, determines if the player is alive. */
+    int m_damage;
     int m_fireRate;                 /**< The player's fire rate (bullets per second). */
     Uint32 m_fireDelay;             /**< The delay between shots in milliseconds. */
     Uint32 m_lastFire;              /**< The timestamp of the last shot fired. */
diff --git a/game/src/StaticObject.cpp b/game/src/StaticObject.cpp
index 9ef574e701f95a88542315e5489fe498ce887e80..67acb9c1470938c48450c30911bd5af5043bc91c 100644
--- a/game/src/StaticObject.cpp
+++ b/game/src/StaticObject.cpp
@@ -2,7 +2,7 @@
 
 StaticObject::StaticObject(b2World *world, const b2Vec2 &position, const b2Vec2 &size, float scale, float friction,
                            const std::vector<int> &tileIDs)
-    : GameObject(world, position, size, 0.0f, scale, friction, tileIDs)
+    : GameObject(world, position, size, 0.0f, scale, friction, tileIDs, false, false)
 {
 }