From bc2dbb65301f9d110f7ee4f9b379dc584597bd75 Mon Sep 17 00:00:00 2001
From: ms622 <ms622@hdm-stuttgart.de>
Date: Thu, 18 Jan 2024 18:19:43 +0100
Subject: [PATCH] update: implemented system for gameplay objects such as heal
 items, bombs etc. #74 #79 #80

---
 .../Controller/GameSceneController.java       |  21 ++-
 .../DataStorage/Classes/RuntimeInfo.java      |  12 ++
 .../Model/Entity/EntityFactory.java           |  14 ++
 .../Model/Entity/GameplayObjects/Bomb.java    |  94 ++++++++++++
 .../Model/Entity/GameplayObjects/Heart.java   | 114 ++++++++++++++
 .../Entity/GameplayObjects/ObjectStatus.java  |   6 +
 .../Entity/GameplayObjects/ObjectType.java    |   7 +
 .../battlearena/Model/Entity/IEntity.java     |  26 ++--
 .../Model/Entity/NetworkPlayerTwo.java        |   8 +-
 .../battlearena/Model/Entity/Player.java      | 141 +++++++++---------
 src/main/java/module-info.java                |   1 +
 11 files changed, 362 insertions(+), 82 deletions(-)
 create mode 100644 src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/GameplayObjects/Bomb.java
 create mode 100644 src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/GameplayObjects/Heart.java
 create mode 100644 src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/GameplayObjects/ObjectStatus.java
 create mode 100644 src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/GameplayObjects/ObjectType.java

diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Controller/GameSceneController.java b/src/main/java/de/hdm_stuttgart/battlearena/Controller/GameSceneController.java
index febd5cd7..7b899713 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Controller/GameSceneController.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Controller/GameSceneController.java
@@ -22,6 +22,7 @@ import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.LogManager;
 
 import java.net.URL;
+import java.util.List;
 import java.util.ResourceBundle;
 
 public class GameSceneController implements Initializable {
@@ -133,8 +134,9 @@ public class GameSceneController implements Initializable {
         enemy.updateEntityMovement(this);
         player.attack(enemy, graphicsContext2D);
         enemy.attack(player, graphicsContext2D);
-        player.checkHealTile(player, graphicsContext2D);
-        enemy.checkHealTile(enemy, graphicsContext2D);
+        updateGameplayObjects();
+        player.checkGameplayObjectInteraction(player, graphicsContext2D);
+        enemy.checkGameplayObjectInteraction(enemy, graphicsContext2D);
         player.placeBomb(player, enemy, graphicsContext2D);
         enemy.placeBomb(enemy, player, graphicsContext2D);
     }
@@ -143,6 +145,21 @@ public class GameSceneController implements Initializable {
         tileManager.renderMap();
         player.renderEntity(graphicsContext);
         enemy.renderEntity(graphicsContext);
+        renderGameplayObjects(graphicsContext);
+    }
+    
+    private void renderGameplayObjects(GraphicsContext graphicsContext) {
+        List<IEntity> gameplayObjects = runtimeInfo.getGameplayObjects();
+        for (IEntity gameplayObject : gameplayObjects) {
+            gameplayObject.renderEntity(graphicsContext);
+        }
+    }
+
+    private void updateGameplayObjects() {
+        List<IEntity> gameplayObjects = runtimeInfo.getGameplayObjects();
+        for (IEntity gameplayObject : gameplayObjects) {
+            //Todo: remove every gameplay object with used status
+        }
     }
 
     public IEntity getEnemy() {
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/RuntimeInfo.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/RuntimeInfo.java
index d307e3e6..fe3a0a47 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/RuntimeInfo.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/RuntimeInfo.java
@@ -6,11 +6,13 @@ import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.ParserE
 import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities.HashGenerator;
 import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities.Parser;
 import de.hdm_stuttgart.battlearena.Model.Entity.EntityClass;
+import de.hdm_stuttgart.battlearena.Model.Entity.IEntity;
 import de.hdm_stuttgart.battlearena.Model.Map.Biom;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
 import java.util.ArrayList;
+import java.util.List;
 
 public class RuntimeInfo {
 
@@ -29,6 +31,8 @@ public class RuntimeInfo {
 
     private Biom mapBiom = Biom.DARK_LANDS; //Default value: GRASS
 
+    private List<IEntity> gameplayObjects = new ArrayList<>();
+
 
     private RuntimeInfo(){};
 
@@ -101,6 +105,14 @@ public class RuntimeInfo {
         this.mapBiom = mapBiom;
     }
 
+    public List<IEntity> getGameplayObjects() {
+        return gameplayObjects;
+    }
+
+    public void setGameplayObjects(List<IEntity> gameplayObjects) {
+        this.gameplayObjects = gameplayObjects;
+    }
+
     public int gameTimeInHours(){
         return persistenceInst.getStatistics().getGameTime() / 3600;
     }
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/EntityFactory.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/EntityFactory.java
index 2e49bcac..5a5480f4 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/EntityFactory.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/EntityFactory.java
@@ -2,6 +2,9 @@ package de.hdm_stuttgart.battlearena.Model.Entity;
 
 import de.hdm_stuttgart.battlearena.Controller.Enum.PlayerMode;
 import de.hdm_stuttgart.battlearena.Controller.GameSceneController;
+import de.hdm_stuttgart.battlearena.Model.Entity.GameplayObjects.Bomb;
+import de.hdm_stuttgart.battlearena.Model.Entity.GameplayObjects.Heart;
+import de.hdm_stuttgart.battlearena.Model.Entity.GameplayObjects.ObjectType;
 import de.hdm_stuttgart.battlearena.Model.Inputs.InputHandler;
 
 import javafx.scene.canvas.GraphicsContext;
@@ -26,4 +29,15 @@ public class EntityFactory {
         throw new IllegalArgumentException ("Entity type not supported " + entityType);
     }
 
+    public static IEntity createGameplayObject(ObjectType objectType, int cordX, int cordY, GraphicsContext graphicsContext) {
+        if (objectType == ObjectType.HEART) {
+            return new Heart(cordX, cordY, graphicsContext);
+        } else if (objectType == ObjectType.BIG_BOMB) {
+            return new Bomb();
+        } else if (objectType == ObjectType.BOMB) {
+            return new Bomb();
+        }
+        throw new IllegalArgumentException();
+    }
+
 }
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/GameplayObjects/Bomb.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/GameplayObjects/Bomb.java
new file mode 100644
index 00000000..c1ed5a00
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/GameplayObjects/Bomb.java
@@ -0,0 +1,94 @@
+package de.hdm_stuttgart.battlearena.Model.Entity.GameplayObjects;
+
+import de.hdm_stuttgart.battlearena.Controller.GameSceneController;
+import de.hdm_stuttgart.battlearena.Model.Entity.EntityDirection;
+import de.hdm_stuttgart.battlearena.Model.Entity.IEntity;
+import javafx.geometry.BoundingBox;
+import javafx.scene.canvas.GraphicsContext;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.LogManager;
+
+public class Bomb implements IEntity {
+
+    private static final Logger log = LogManager.getLogger(Bomb.class);
+
+    @Override
+    public void initializeEntity() {
+
+    }
+
+    @Override
+    public void loadEntitySprites() {
+
+    }
+
+    @Override
+    public void updateEntityMovement(GameSceneController gameScene) {
+
+    }
+
+    @Override
+    public void checkGameplayObjectInteraction(IEntity entity, GraphicsContext graphicsContext) {
+
+    }
+
+    @Override
+    public void placeBomb(IEntity entity, IEntity entity2, GraphicsContext graphicsContext) {
+
+    }
+
+    @Override
+    public void attack(IEntity entity, GraphicsContext graphicsContext) {
+
+    }
+
+    @Override
+    public void updateEntityWalkAnimation() {
+
+    }
+
+    @Override
+    public void renderEntity(GraphicsContext graphicsContext) {
+
+    }
+
+    @Override
+    public void healPlayer(int heal) {
+
+    }
+
+    @Override
+    public BoundingBox getBoxCollider() {
+        return null;
+    }
+
+    @Override
+    public EntityDirection getEntityDirection() {
+        return null;
+    }
+
+    @Override
+    public int getEntitySpeed() {
+        return 0;
+    }
+
+    @Override
+    public void gotHit(int damageDone) {
+
+    }
+
+    @Override
+    public int getMapPosX() {
+        return 0;
+    }
+
+    @Override
+    public int getMapPosY() {
+        return 0;
+    }
+
+    @Override
+    public ObjectType getOBJECT_TYPE() {
+        return null;
+    }
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/GameplayObjects/Heart.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/GameplayObjects/Heart.java
new file mode 100644
index 00000000..b0d4141a
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/GameplayObjects/Heart.java
@@ -0,0 +1,114 @@
+package de.hdm_stuttgart.battlearena.Model.Entity.GameplayObjects;
+
+import de.hdm_stuttgart.battlearena.Controller.GameSceneController;
+import de.hdm_stuttgart.battlearena.Model.Entity.EntityDirection;
+import de.hdm_stuttgart.battlearena.Model.Entity.IEntity;
+
+import javafx.geometry.BoundingBox;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.image.Image;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.LogManager;
+
+import java.util.Objects;
+
+public class Heart implements IEntity {
+
+    private static final Logger log = LogManager.getLogger(Heart.class);
+
+    private final int posX;
+    private final int posY;
+    private Image sprite;
+    private final GraphicsContext graphicsContext;
+    private BoundingBox boxCollider;
+    private final ObjectType OBJECT_TYPE = ObjectType.HEART;
+
+    public Heart(int posX, int posY, GraphicsContext graphicsContext) {
+        this.posX = posX;
+        this.posY = posY;
+        this.graphicsContext = graphicsContext;
+
+        initializeEntity();
+    }
+
+    @Override
+    public void initializeEntity() {
+        loadEntitySprites();
+        boxCollider = new BoundingBox(posX+12, posY+12, 24, 24);
+    }
+
+    @Override
+    public void loadEntitySprites() {
+        sprite = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/objects/heal/heart.png")));
+    }
+
+    @Override
+    public void updateEntityMovement(GameSceneController gameScene) {
+
+    }
+
+    @Override
+    public void checkGameplayObjectInteraction(IEntity entity, GraphicsContext graphicsContext) {
+
+    }
+
+    @Override
+    public void placeBomb(IEntity entity, IEntity entity2, GraphicsContext graphicsContext) {
+
+    }
+
+    @Override
+    public void attack(IEntity entity, GraphicsContext graphicsContext) {
+
+    }
+
+    @Override
+    public void updateEntityWalkAnimation() {
+
+    }
+
+    @Override
+    public void renderEntity(GraphicsContext graphicsContext) {
+        graphicsContext.drawImage(sprite, posX, posY, 48, 48);
+    }
+
+    @Override
+    public void healPlayer(int heal) {
+
+    }
+
+    @Override
+    public BoundingBox getBoxCollider() {
+        return boxCollider;
+    }
+
+    @Override
+    public EntityDirection getEntityDirection() {
+        return null;
+    }
+
+    @Override
+    public int getEntitySpeed() {
+        return 0;
+    }
+
+    @Override
+    public void gotHit(int damageDone) {
+
+    }
+
+    @Override
+    public int getMapPosX() {
+        return posX;
+    }
+
+    @Override
+    public int getMapPosY() {
+        return posY;
+    }
+
+    public ObjectType getOBJECT_TYPE() {
+        return OBJECT_TYPE;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/GameplayObjects/ObjectStatus.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/GameplayObjects/ObjectStatus.java
new file mode 100644
index 00000000..265e1407
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/GameplayObjects/ObjectStatus.java
@@ -0,0 +1,6 @@
+package de.hdm_stuttgart.battlearena.Model.Entity.GameplayObjects;
+
+public enum ObjectStatus {
+    USED,
+    UNUSED
+}
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/GameplayObjects/ObjectType.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/GameplayObjects/ObjectType.java
new file mode 100644
index 00000000..e918d447
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/GameplayObjects/ObjectType.java
@@ -0,0 +1,7 @@
+package de.hdm_stuttgart.battlearena.Model.Entity.GameplayObjects;
+
+public enum ObjectType {
+    BIG_BOMB,
+    BOMB,
+    HEART
+}
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/IEntity.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/IEntity.java
index b55bde72..966bdfe8 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/IEntity.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/IEntity.java
@@ -1,39 +1,43 @@
 package de.hdm_stuttgart.battlearena.Model.Entity;
 
 import de.hdm_stuttgart.battlearena.Controller.GameSceneController;
+import de.hdm_stuttgart.battlearena.Model.Entity.GameplayObjects.ObjectType;
 import javafx.geometry.BoundingBox;
 import javafx.scene.canvas.GraphicsContext;
 
 public interface IEntity {
 
-   void initializeEntity();
+    void initializeEntity();
 
-   void loadEntitySprites();
+    void loadEntitySprites();
 
-   void updateEntityMovement(GameSceneController gameScene);
+    void updateEntityMovement(GameSceneController gameScene);
 
-   void checkHealTile(IEntity entity, GraphicsContext graphicsContext);
+    //checks collision with GameplayObjects by iterating through GameplayObjects list
+    void checkGameplayObjectInteraction(IEntity entity, GraphicsContext graphicsContext);
 
     void placeBomb(IEntity entity, IEntity entity2, GraphicsContext graphicsContext);
 
     void attack(IEntity entity, GraphicsContext graphicsContext);
 
-   void updateEntityWalkAnimation();
+    void updateEntityWalkAnimation();
 
-   void renderEntity(GraphicsContext graphicsContext);
+    void renderEntity(GraphicsContext graphicsContext);
 
     void healPlayer(int heal);
 
     BoundingBox getBoxCollider();
 
-   EntityDirection getEntityDirection();
+    EntityDirection getEntityDirection();
 
-   int getEntitySpeed();
+    int getEntitySpeed();
 
-   void gotHit(int damageDone);
+    void gotHit(int damageDone);
 
-   int getMapPosX();
+    int getMapPosX();
 
-   int getMapPosY();
+    int getMapPosY();
+
+    public ObjectType getOBJECT_TYPE();
 
 }
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/NetworkPlayerTwo.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/NetworkPlayerTwo.java
index 70dc4e04..e2aa0c39 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/NetworkPlayerTwo.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/NetworkPlayerTwo.java
@@ -2,6 +2,7 @@ package de.hdm_stuttgart.battlearena.Model.Entity;
 
 import de.hdm_stuttgart.battlearena.Controller.GameSceneController;
 
+import de.hdm_stuttgart.battlearena.Model.Entity.GameplayObjects.ObjectType;
 import javafx.geometry.BoundingBox;
 import javafx.scene.canvas.GraphicsContext;
 import javafx.scene.paint.Color;
@@ -37,7 +38,7 @@ class NetworkPlayerTwo implements IEntity{
     }
 
     @Override
-    public void checkHealTile(IEntity entity, GraphicsContext graphicsContext) {
+    public void checkGameplayObjectInteraction(IEntity entity, GraphicsContext graphicsContext) {
 
     }
 
@@ -99,4 +100,9 @@ class NetworkPlayerTwo implements IEntity{
         return 0;
     }
 
+    @Override
+    public ObjectType getOBJECT_TYPE() {
+        return null;
+    }
+
 }
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/Player.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/Player.java
index 5fdfadc9..1aef7340 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/Player.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/Player.java
@@ -2,6 +2,9 @@ package de.hdm_stuttgart.battlearena.Model.Entity;
 
 import de.hdm_stuttgart.battlearena.Controller.Enum.PlayerMode;
 import de.hdm_stuttgart.battlearena.Controller.GameSceneController;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.RuntimeInfo;
+import de.hdm_stuttgart.battlearena.Model.Entity.GameplayObjects.Heart;
+import de.hdm_stuttgart.battlearena.Model.Entity.GameplayObjects.ObjectType;
 import de.hdm_stuttgart.battlearena.Model.Inputs.InputHandler;
 
 import de.hdm_stuttgart.battlearena.Model.Map.TileManager;
@@ -13,6 +16,7 @@ import javafx.scene.image.Image;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.LogManager;
 
+import java.util.List;
 import java.util.Objects;
 
 class Player implements IEntity {
@@ -22,6 +26,9 @@ class Player implements IEntity {
     private final PlayerMode PLAYER_MODE;
 
     InputHandler inputHandler;
+
+    RuntimeInfo runtimeInfo = RuntimeInfo.getInstance();
+
     CollisionHandler collisionHandler = new CollisionHandler();
 
     GraphicsContext gameScene;
@@ -64,7 +71,7 @@ class Player implements IEntity {
     private EntityDirection playerDirection;
 
     private int health;
-    private  int maxPlayerHealth;
+    private int maxPlayerHealth;
     private int damage;
 
     public Player(GraphicsContext gameScene, InputHandler inputHandler, EntityClass entityClass,
@@ -280,50 +287,59 @@ class Player implements IEntity {
 
         boxCollider = new BoundingBox(mapPosX + 15, mapPosY + 10, playerWidth, playerHeight);
     }
+
     @Override
-    public void checkHealTile(IEntity entity, GraphicsContext graphicsContext){
-        int xTile = entity.getMapPosX() / gameSceneController.getScaledTileSize();
-        int yTile = entity.getMapPosY() / gameSceneController.getScaledTileSize();
-        if(TileManager.tileMap[yTile][xTile +1 ] == 5){
-            entity.healPlayer(1);
-            TileManager.tileMap[yTile][xTile +1] = 2;
-            log.info("Healed +1: " + health);
+    public void checkGameplayObjectInteraction(IEntity entity, GraphicsContext graphicsContext) {
+        List<IEntity> gameplayObjects = runtimeInfo.getGameplayObjects();
+        for (IEntity gameplayObject : gameplayObjects) {
+            if (gameplayObject.getOBJECT_TYPE() == ObjectType.HEART) {
+                if (gameplayObject.getBoxCollider().intersects(boxCollider)) {
+                    log.info("Collision with heart");
+                    healPlayer(5);
+                    //Todo: set status of gameplay object to used
+                }
+            } else if (gameplayObject.getOBJECT_TYPE() == ObjectType.BOMB) {
+                if (gameplayObject.getBoxCollider().intersects(boxCollider)) {
+                    log.info("Collision with bomb");
+                    //Todo: implement later
+                }
+            }
         }
     }
 
     @Override
-    public void placeBomb(IEntity entity, IEntity entity2, GraphicsContext graphicsContext){
+    public void placeBomb(IEntity entity, IEntity entity2, GraphicsContext graphicsContext) {
         boolean isDestructible;
         int xTile = entity.getMapPosX() / gameSceneController.getScaledTileSize();
         int yTile = entity.getMapPosY() / gameSceneController.getScaledTileSize();
         int xTile2 = entity2.getMapPosX() / gameSceneController.getScaledTileSize();
         int yTile2 = entity2.getMapPosY() / gameSceneController.getScaledTileSize();
-        if(inputHandler.isBomb() &&  PLAYER_MODE == PlayerMode.PLAYER_ONE ||
+        if (inputHandler.isBomb() && PLAYER_MODE == PlayerMode.PLAYER_ONE ||
                 inputHandler.isSdBomb() && PLAYER_MODE == PlayerMode.PLAYER_TWO) {
             isDestructible = checkTileNon_Destructible(yTile, xTile);
-            if(isDestructible){
+            if (isDestructible) {
                 TileManager.tileMap[yTile][xTile] = 7;
-                for (int i=0;i<3; i++){
-                    isDestructible = checkTileNon_Destructible(yTile +1 +i, xTile);         //If Tile solid , -> should stop comparing,
-                    if(isDestructible && (yTile < 18 && xTile <18)){                            //because for now, Tile behind gets destroyed aswell
-                       TileManager.tileMap[yTile +1 + i][xTile] = 8;
+                for (int i = 0; i < 3; i++) {
+                    isDestructible = checkTileNon_Destructible(yTile + 1 + i, xTile);         //If Tile solid , -> should stop comparing,
+                    if (isDestructible && (yTile < 18 && xTile < 18)) {                            //because for now, Tile behind gets destroyed aswell
+                        TileManager.tileMap[yTile + 1 + i][xTile] = 8;
                        /*if(entity || entity2) {
                            entity2.gotHit(2);    //See if enemy or player hit
                        }*/
                     }
-                    isDestructible = checkTileNon_Destructible(yTile -1 -i, xTile);
-                    if(isDestructible && (yTile < 18 && xTile <18 && yTile > 0 && xTile > 0)){
-                        TileManager.tileMap[yTile -1 -i][xTile] = 8;
+                    isDestructible = checkTileNon_Destructible(yTile - 1 - i, xTile);
+                    if (isDestructible && (yTile < 18 && xTile < 18 && yTile > 0 && xTile > 0)) {
+                        TileManager.tileMap[yTile - 1 - i][xTile] = 8;
                         entity.gotHit(2);
                     }
-                    isDestructible = checkTileNon_Destructible(yTile , xTile +1 +i);
-                    if(isDestructible && (yTile < 18 && xTile <18 && yTile > 0 && xTile > 0)){
-                        TileManager.tileMap[yTile][xTile +1 +i] = 8;
+                    isDestructible = checkTileNon_Destructible(yTile, xTile + 1 + i);
+                    if (isDestructible && (yTile < 18 && xTile < 18 && yTile > 0 && xTile > 0)) {
+                        TileManager.tileMap[yTile][xTile + 1 + i] = 8;
                         entity.gotHit(2);
                     }
-                    isDestructible = checkTileNon_Destructible(yTile, xTile -1 -i);
-                    if(isDestructible && (yTile < 18 && xTile <18 && yTile > 0 && xTile > 0)){
-                        TileManager.tileMap[yTile][xTile -1 -i] = 8;
+                    isDestructible = checkTileNon_Destructible(yTile, xTile - 1 - i);
+                    if (isDestructible && (yTile < 18 && xTile < 18 && yTile > 0 && xTile > 0)) {
+                        TileManager.tileMap[yTile][xTile - 1 - i] = 8;
                         entity.gotHit(2);
                     }
                 }
@@ -344,9 +360,10 @@ class Player implements IEntity {
             TileManager.tileMap[yTile][xTile-2] = 8;*/
         }
     }
-    public boolean checkTileNon_Destructible(int y, int x){     //Change it with a DestructionHandler like CollisionHandler
+
+    public boolean checkTileNon_Destructible(int y, int x) {     //Change it with a DestructionHandler like CollisionHandler
         //tileSet[xTile].getDestruction();
-        if(TileManager.tileMap[y][x] != 10 && TileManager.tileMap[y][x] != 3 && TileManager.tileMap[y][x] != 4){
+        if (TileManager.tileMap[y][x] != 10 && TileManager.tileMap[y][x] != 3 && TileManager.tileMap[y][x] != 4) {
             return true;
         }
         return false;
@@ -358,8 +375,7 @@ class Player implements IEntity {
 
         int xTile = mapPosX / gameSceneController.getScaledTileSize();
         int yTile = mapPosY / gameSceneController.getScaledTileSize();
-        //int xTile = (int) (Math.random() * (18 - 1));   //Get xTile Coordinate +1 /-1 of playerTile
-        //int yTile = (int) (Math.random() * (18 - 1));   //Get yTile Coordinate +1 /-1 of playerTile
+
         double dropChance = 0.5;
         double randomDropChance = Math.random() * 1;
 
@@ -374,62 +390,45 @@ class Player implements IEntity {
                 hitBox = new BoundingBox(mapPosX + playerWidth, mapPosY - 10, attackWidth, attackRange);
                 graphicsContext.strokeRect(mapPosX + playerWidth, mapPosY - 10, attackWidth, attackRange);
                 graphicsContext.drawImage(swordUp, mapPosX + 8, mapPosY - 10, 32, 32);
-                if (hitBox.intersects(entity.getBoxCollider())) {
-                    entity.gotHit(damage);
-                    graphicsContext.strokeText("Hit", 10, 10);
-
-                    if (((TileManager.tileMap[xTile][yTile] == 3) && randomDropChance > dropChance)||
-                            ((TileManager.tileMap[xTile][yTile] == 1)  && randomDropChance > dropChance))
-                        TileManager.tileMap[yTile-1][xTile+1] = 5;
-                    //TileManager.tileMap[yTile-2][xTile] = 5;
-                    //TileManager.tileMap[yTile-3][xTile] = 5;
-                }
+                hitEnemy(entity, graphicsContext, hitBox, dropChance, randomDropChance);
             } else if (playerDirection == EntityDirection.DOWN) {
                 hitBox = new BoundingBox(mapPosX + playerWidth, mapPosY + playerHeight, attackWidth, attackRange);
                 graphicsContext.strokeRect(mapPosX + playerWidth, mapPosY + playerHeight, attackWidth, attackRange);
                 graphicsContext.drawImage(swordDown, mapPosX + 8, mapPosY + playerHeight, 32, 32);
-                if (hitBox.intersects(entity.getBoxCollider())) {
-                    entity.gotHit(damage);
-                    graphicsContext.strokeText("Hit", 10, 10);
-
-                    if (((TileManager.tileMap[xTile][yTile] == 3) && randomDropChance > dropChance)||
-                            ((TileManager.tileMap[xTile][yTile] == 1)  && randomDropChance > dropChance))
-                        TileManager.tileMap[yTile-1][xTile+1] = 5;
-                    //TileManager.tileMap[yTile-2][xTile] = 5;
-                    //TileManager.tileMap[yTile-3][xTile] = 5;
-                }
+                hitEnemy(entity, graphicsContext, hitBox, dropChance, randomDropChance);
             } else if (playerDirection == EntityDirection.LEFT) {
                 hitBox = new BoundingBox(mapPosX - attackWidth, mapPosY + ((double) playerHeight / 2),
                         attackRange, attackWidth);
                 graphicsContext.strokeRect(mapPosX - attackWidth, mapPosY + ((double) playerHeight / 2),
                         attackRange, attackWidth);
                 graphicsContext.drawImage(swordLeft, mapPosX - 8, mapPosY + 8, 32, 32);
-                if (hitBox.intersects(entity.getBoxCollider())) {
-                    entity.gotHit(damage);
-                    graphicsContext.strokeText("Hit", 10, 10);
-
-                    if (((TileManager.tileMap[xTile][yTile] == 3) && randomDropChance > dropChance)||
-                            ((TileManager.tileMap[xTile][yTile] == 1)  && randomDropChance > dropChance))
-                        TileManager.tileMap[yTile-1][xTile+1] = 5;
-                    //TileManager.tileMap[yTile-2][xTile] = 5;
-                    //TileManager.tileMap[yTile-3][xTile] = 5;
-                }
+                hitEnemy(entity, graphicsContext, hitBox, dropChance, randomDropChance);
             } else {
                 hitBox = new BoundingBox(mapPosX + playerWidth + attackWidth, mapPosY + ((double) playerHeight / 2),
                         attackRange, attackWidth);
                 graphicsContext.strokeRect(mapPosX + playerWidth + attackWidth, mapPosY + ((double) playerHeight / 2),
                         attackRange, attackWidth);
                 graphicsContext.drawImage(swordRight, mapPosX + playerWidth + 8, mapPosY + 8, 32, 32);
-                if (hitBox.intersects(entity.getBoxCollider())) {
-                    entity.gotHit(damage);
-                    graphicsContext.strokeText("Hit", 10, 10);
-
-                    if (((TileManager.tileMap[xTile][yTile] == 3) && randomDropChance > dropChance)||
-                            ((TileManager.tileMap[xTile][yTile] == 1)  && randomDropChance > dropChance))
-                        TileManager.tileMap[yTile-1][xTile+1] = 5;
-                    //TileManager.tileMap[yTile-2][xTile] = 5;
-                    //TileManager.tileMap[yTile-3][xTile] = 5;
-                }
+                hitEnemy(entity, graphicsContext, hitBox, dropChance, randomDropChance);
+            }
+        }
+    }
+
+    private void hitEnemy(IEntity entity, GraphicsContext graphicsContext, BoundingBox hitBox, double dropChance, double randomDropChance) {
+        if (hitBox.intersects(entity.getBoxCollider())) {
+            entity.gotHit(damage);
+            log.info("Hit enemy");
+
+            //spawning heart entity
+            if (randomDropChance > dropChance) {
+                int spawnCordX = mapPosX + 48;
+                int spawnCordY = mapPosY + 48;
+
+                List<IEntity> gameplayObjects = runtimeInfo.getGameplayObjects();
+                IEntity heart = EntityFactory.createGameplayObject(ObjectType.HEART, spawnCordX, spawnCordY, graphicsContext);
+                gameplayObjects.add(heart);
+                runtimeInfo.setGameplayObjects(gameplayObjects);
+                log.info("heart dropped");
             }
         }
     }
@@ -497,6 +496,7 @@ class Player implements IEntity {
     public void gotHit(int damageDone) {
         health -= damageDone;
     }
+
     @Override
     public void healPlayer(int healthRegenerated) {
         int regeneratedHealth = health + healthRegenerated;
@@ -534,4 +534,9 @@ class Player implements IEntity {
         return mapPosY;
     }
 
+    @Override
+    public ObjectType getOBJECT_TYPE() {
+        return null;
+    }
+
 }
\ No newline at end of file
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index 0aa58560..cc01c050 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -21,5 +21,6 @@ module gui {
     exports de.hdm_stuttgart.battlearena.Model.Map;
     exports de.hdm_stuttgart.battlearena.Controller.Utilities;
     exports de.hdm_stuttgart.battlearena.Model.Multiplayer;
+    exports de.hdm_stuttgart.battlearena.Model.Entity.GameplayObjects to javafx.fxml;
     opens de.hdm_stuttgart.battlearena.Controller.Utilities to javafx.fxml;
 }
\ No newline at end of file
-- 
GitLab