From 0bb2e9099d1f1997c95c67e6698334269e0c9e3f Mon Sep 17 00:00:00 2001 From: R00V <149782421+rofidakhaled@users.noreply.github.com> Date: Wed, 11 Dec 2024 00:30:36 +0200 Subject: [PATCH 1/9] implementing ECS pattern --- entity-component-system/README.md | 0 .../etc/entity-component-system.urm.puml | 121 ++++++++ entity-component-system/pom.xml | 74 +++++ .../src/main/java/com/iluwatar/App.java | 104 +++++++ .../src/main/java/com/iluwatar/Component.java | 107 +++++++ .../src/main/java/com/iluwatar/Entity.java | 292 ++++++++++++++++++ .../main/java/com/iluwatar/GameSystem.java | 172 +++++++++++ .../java/com/iluwatar/HealthComponent.java | 121 ++++++++ .../java/com/iluwatar/TransformComponent.java | 171 ++++++++++ .../java/com/iluwatar/VelocityComponent.java | 148 +++++++++ .../src/test/java/com/iluwatar/AppTest.java | 124 ++++++++ .../test/java/com/iluwatar/ComponentTest.java | 52 ++++ .../test/java/com/iluwatar/EntityTest.java | 98 ++++++ .../java/com/iluwatar/GameSystemTest.java | 111 +++++++ .../com/iluwatar/HealthComponentTest.java | 75 +++++ .../com/iluwatar/TransformComponentTest.java | 83 +++++ .../com/iluwatar/VelocityComponentTest.java | 64 ++++ pom.xml | 1 + update-header.sh | 25 ++ 19 files changed, 1943 insertions(+) create mode 100644 entity-component-system/README.md create mode 100644 entity-component-system/etc/entity-component-system.urm.puml create mode 100644 entity-component-system/pom.xml create mode 100644 entity-component-system/src/main/java/com/iluwatar/App.java create mode 100644 entity-component-system/src/main/java/com/iluwatar/Component.java create mode 100644 entity-component-system/src/main/java/com/iluwatar/Entity.java create mode 100644 entity-component-system/src/main/java/com/iluwatar/GameSystem.java create mode 100644 entity-component-system/src/main/java/com/iluwatar/HealthComponent.java create mode 100644 entity-component-system/src/main/java/com/iluwatar/TransformComponent.java create mode 100644 entity-component-system/src/main/java/com/iluwatar/VelocityComponent.java create mode 100644 entity-component-system/src/test/java/com/iluwatar/AppTest.java create mode 100644 entity-component-system/src/test/java/com/iluwatar/ComponentTest.java create mode 100644 entity-component-system/src/test/java/com/iluwatar/EntityTest.java create mode 100644 entity-component-system/src/test/java/com/iluwatar/GameSystemTest.java create mode 100644 entity-component-system/src/test/java/com/iluwatar/HealthComponentTest.java create mode 100644 entity-component-system/src/test/java/com/iluwatar/TransformComponentTest.java create mode 100644 entity-component-system/src/test/java/com/iluwatar/VelocityComponentTest.java diff --git a/entity-component-system/README.md b/entity-component-system/README.md new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/entity-component-system/etc/entity-component-system.urm.puml b/entity-component-system/etc/entity-component-system.urm.puml new file mode 100644 index 000000000000..1213969d7c8e --- /dev/null +++ b/entity-component-system/etc/entity-component-system.urm.puml @@ -0,0 +1,121 @@ +@startuml +package com.iluwatar { + class App { + + App() + + main(args : String[]) {static} + } + abstract class Component { + - isEnabled : boolean + - name : String + - parent : Entity + + Component() + + getEnabled() : boolean + + getName() : String + + getParent() : Entity + + setEnabled(isEnabled : boolean) + + setName(name : String) + + setParent(parent : Entity) + + update(float) {abstract} + } + class Entity { + - children : List + - components : List + - entityId : UUID + - gameSystem : GameSystem + - isEnabled : boolean + - name : String + - parent : Entity + - transform : TransformComponent + + Entity(entityName : String) + + addChild(child : Entity) + + addComponent(component : Component) + + getChildren() : List + + getComponent(componentName : String) : Component + + getEntityId() : UUID + + getGameSystem() : GameSystem + + getMeshRenderComponents() : List + + getName() : String + + getParent() : Entity + + getTransformComponent() : TransformComponent + + isEnabled() : boolean + + removeChild(child : Entity) + + removeComponent(component : Component) + + renderEntity() + + setEnabled(enabled : boolean) + + setGameSystem(gameSystem : GameSystem) + + setIsEnabled(isEnabled : boolean) + + setName(name : String) + + setParent(newParent : Entity) + + update(deltaTime : float) + } + class GameSystem { + - entities : List + + GameSystem() + + addEntity(entity : Entity) + - calculateDistance(point1 : float[], point2 : float[]) : float + + getSystemMatrix(entity : Entity) : float[][] + + getSystemPosition(entity : Entity) : float[] + - multiplyMatrices(matrix1 : float[][], matrix2 : float[][]) : float[][] + + removeEntity(entity : Entity) + + renderSystem() + + sortEntitiesByDistance(referencePoint : float[]) + + update(deltaTime : float) + } + class HealthComponent { + - currentHealth : float + - isAlive : boolean + - logger : Logger {static} + - maxHealth : float + + HealthComponent(maxHealth : float) + + applyDamage(damage : float) + + getCurrentHealth() : float + + getMaxHealth() : float + + heal(amount : float) + + isAlive() : boolean + + setAlive(isAlive : boolean) + + setCurrentHealth(currentHealth : float) + + setMaxHealth(maxHealth : float) + + update(deltaTime : float) + } + class TransformComponent { + - position : float[] + - rotation : float[] + - scale : float[] + + TransformComponent() + + TransformComponent(initPosition : float[], initRotation : float[], initScale : float[]) + - applyRotation(matrix : float[][]) + + getPosition() : float[] + + getRotation() : float[] + + getScale() : float[] + + getTransformMatrix() : float[][] + + setPosition(position : float[]) + + setRotation(eulerAngles : float[]) + + setScale(scale : float[]) + + update(deltaTime : float) + } + class VelocityComponent { + - logger : Logger {static} + - velocityX : float + - velocityY : float + - velocityZ : float + + VelocityComponent(velocityX : float, velocityY : float, velocityZ : float) + + applyForce(forceX : float, forceY : float, forceZ : float) + + applyFriction(frictionCoefficient : float) + + getVelocityX() : float + + getVelocityY() : float + + getVelocityZ() : float + + setVelocityX(velocityX : float) + + setVelocityY(velocityY : float) + + setVelocityZ(velocityZ : float) + + update(deltaTime : float) + } +} +Entity --> "-transform" TransformComponent +Entity --> "-parent" Entity +Entity --> "-children" Entity +Entity --> "-gameSystem" GameSystem +Entity --> "-components" Component +HealthComponent --|> Component +TransformComponent --|> Component +VelocityComponent --|> Component +@enduml \ No newline at end of file diff --git a/entity-component-system/pom.xml b/entity-component-system/pom.xml new file mode 100644 index 000000000000..cc5ae82d3ff3 --- /dev/null +++ b/entity-component-system/pom.xml @@ -0,0 +1,74 @@ + + + + + java-design-patterns + com.iluwatar + 1.26.0-SNAPSHOT + + com.iluwatar + 1.26.0-SNAPSHOT + 4.0.0 + entity-component-system + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-api + test + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + + + + com.iluwatar.entity-component-system.Main + + + + + + + + + diff --git a/entity-component-system/src/main/java/com/iluwatar/App.java b/entity-component-system/src/main/java/com/iluwatar/App.java new file mode 100644 index 000000000000..f0fb1569e319 --- /dev/null +++ b/entity-component-system/src/main/java/com/iluwatar/App.java @@ -0,0 +1,104 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar; + +/** + * The main entry point for the application. + * This class simulates a game loop where entities are created, updated, and their states are modified. + */ +public class App { + + /** + * The main method that runs the application. + * It creates entities, adds components, updates them over several frames, + * and demonstrates applying damage and forces to entities. + * + * @param args Command-line arguments (not used in this application) + */ + public static void main(String[] args) { + // Create example entities + Entity entity1 = new Entity("Entity1"); + Entity entity2 = new Entity("Entity2"); + + // Set up some transform components (position, rotation, scale) + TransformComponent transform1 = new TransformComponent(new float[]{0.0f, 0.0f, 0.0f}, + new float[]{0.0f, 0.0f, 0.0f}, new float[]{1.0f, 1.0f, 1.0f}); + TransformComponent transform2 = new TransformComponent(new float[]{5.0f, 0.0f, 0.0f}, + new float[]{0.0f, 45.0f, 0.0f}, new float[]{1.0f, 1.0f, 1.0f}); + + // Set the transform components for each entity + entity1.addComponent(transform1); + entity2.addComponent(transform2); + + // Create a health component for entity1 with initial health of 100 + HealthComponent health1 = new HealthComponent(100); // Ensure HealthComponent is implemented + entity1.addComponent(health1); + + // Create a velocity component for entity1 + VelocityComponent velocity1 = new VelocityComponent(1.0f, 0.0f, 0.0f); + entity1.addComponent(velocity1); + + // Set up a system and add entities to the system + GameSystem gameSystem = new GameSystem(); + gameSystem.addEntity(entity1); + gameSystem.addEntity(entity2); + + // Simulate game update loop (e.g., 60 FPS) + float deltaTime = 1.0f / 60.0f; // 60 FPS + + // Simulate for a few frames + for (int i = 0; i < 10; i++) { + System.out.println("Frame: " + (i + 1)); + + // Update all entities in the system + gameSystem.update(deltaTime); + + // Apply some damage to entity1's health component at frame 6 + if (i == 5) { + health1.applyDamage(30); + System.out.println("Entity1's health after damage: " + health1.getCurrentHealth()); + } + + // Apply some force to entity1's velocity at frame 3 + if (i == 3) { + velocity1.applyForce(0.5f, 0.0f, 0.0f); + System.out.println("Entity1's velocity after force: (" + velocity1.getVelocityX() + ", " + + velocity1.getVelocityY() + ", " + velocity1.getVelocityZ() + ")"); + } + + // Render the system (optional rendering logic can be added here) + gameSystem.renderSystem(); + } + + // After the simulation, check final entity states + System.out.println("\nFinal Entity States:"); + System.out.println("Entity1 position: " + entity1.getTransformComponent().getPosition()[0] + ", " + + entity1.getTransformComponent().getPosition()[1] + ", " + + entity1.getTransformComponent().getPosition()[2]); + System.out.println("Entity1 velocity: " + velocity1.getVelocityX() + ", " + + velocity1.getVelocityY() + ", " + velocity1.getVelocityZ()); + System.out.println("Entity1 health: " + health1.getCurrentHealth()); + } +} diff --git a/entity-component-system/src/main/java/com/iluwatar/Component.java b/entity-component-system/src/main/java/com/iluwatar/Component.java new file mode 100644 index 000000000000..dc1bce36866a --- /dev/null +++ b/entity-component-system/src/main/java/com/iluwatar/Component.java @@ -0,0 +1,107 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar; + +/** + * Abstract class representing a component in the ECS system. + * Each component can be enabled or disabled and associated with an entity. + * Subclasses of this class must implement the update method. + */ +public abstract class Component { + + private String name; + private boolean isEnabled; + private Entity parent; + + /** + * Default constructor for the component. + * Initializes a new component with default values. + */ + public Component() { + // Constructor left empty intentionally, no specific initialization required + } + + /** + * Gets the name of the component. + * + * @return the name of the component + */ + public String getName() { + return name; + } + + /** + * Sets the name of the component. + * + * @param name the name of the component + */ + public void setName(String name) { + this.name = name; + } + + /** + * Gets the enabled state of the component. + * + * @return true if the component is enabled, false otherwise + */ + public boolean getEnabled() { + return isEnabled; + } + + /** + * Sets the enabled state of the component. + * + * @param isEnabled true to enable the component, false to disable it + */ + public void setEnabled(boolean isEnabled) { + this.isEnabled = isEnabled; + } + + /** + * Gets the parent entity of this component. + * + * @return the parent entity + */ + public Entity getParent() { + return parent; + } + + /** + * Sets the parent entity of this component. + * + * @param parent the parent entity to set + */ + public void setParent(Entity parent) { + this.parent = parent; + } + + /** + * Abstract method to update the component. + * Subclasses must implement this method to define their update behavior. + * + * @param deltaTime the time elapsed since the last update + */ + public abstract void update(float deltaTime); +} diff --git a/entity-component-system/src/main/java/com/iluwatar/Entity.java b/entity-component-system/src/main/java/com/iluwatar/Entity.java new file mode 100644 index 000000000000..fe78dade3bf4 --- /dev/null +++ b/entity-component-system/src/main/java/com/iluwatar/Entity.java @@ -0,0 +1,292 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * Represents an entity in the ECS system. + * Each entity can have components, children entities, and a parent entity. + * Entities can be enabled or disabled, and their components can be updated. + */ +public class Entity { + + private String name; + private boolean isEnabled; + private TransformComponent transform; + private Entity parent; + private GameSystem gameSystem; + private List components; + private List children; + + /** The unique identifier for the entity. */ + private UUID entityId; + + /** + * Constructs a new entity with a specified name. + * + * @param entityName the name of the entity + */ + public Entity(String entityName) { + name = entityName; + components = new ArrayList<>(); + children = new ArrayList<>(); + final UUID entityId = UUID.randomUUID(); // Generates a unique UUID for this entity + transform = new TransformComponent(new float[] {0.0f, 0.0f, 0.0f}, new float[] {0.0f, 0.0f, 0.0f}, new float[] {1.0f, 1.0f, 1.0f}); + addComponent(transform); + } + + /** + * Adds a component to the entity. + * + * @param component the component to be added + */ + public void addComponent(Component component) { + if (component != null) { + components.add(component); + component.setEnabled(isEnabled); + component.setParent(this); + } + } + + /** + * Removes a component from the entity. + * + * @param component the component to be removed + */ + public void removeComponent(Component component) { + components.remove(component); + } + + /** + * Retrieves a component by its name. + * + * @param componentName the name of the component + * @return the component matching the specified name, or null if not found + */ + public Component getComponent(String componentName) { + for (Component component : components) { + if (component.getName().equals(componentName)) { + return component; + } + } + return null; + } + + /** + * Sets the parent entity for this entity. + * + * @param newParent the new parent entity + */ + public void setParent(Entity newParent) { + if (parent != null) { + parent.removeChild(this); + } + + parent = newParent; + + if (parent != null) { + parent.addChild(this); + } + } + + /** + * Adds a child entity to this entity. + * + * @param child the child entity to be added + */ + public void addChild(Entity child) { + if (child != null && !children.contains(child)) { + children.add(child); + // Set the parent only if it isn't already set. + if (child.getParent() != this) { + child.setParent(this); + } + } + } + + + /** + * Removes a child entity from this entity. + * + * @param child the child entity to be removed + */ + public void removeChild(Entity child) { + children.remove(child); + } + + /** + * Enables or disables the entity and all its components and children. + * + * @param enabled whether the entity should be enabled or not + */ + public void setEnabled(boolean enabled) { + isEnabled = enabled; + + for (Component component : components) { + component.setEnabled(enabled); + } + + for (Entity child : children) { + child.setEnabled(enabled); + } + } + + public boolean getEnabled() { + return isEnabled; + } + + /** + * Updates the entity and its components. + * + * @param deltaTime the time elapsed since the last update + */ + public void update(float deltaTime) { + if (!isEnabled) { + return; + } + + for (Component component : components) { + if (component.getEnabled()) { + component.update(deltaTime); + } + } + + for (Entity child : children) { + child.update(deltaTime); + } + } + + /** + * Gets the transform component of the entity. + * + * @return the transform component + */ + public TransformComponent getTransformComponent() { + return transform; + } + + /** + * Gets the transform component of the entity. + * + */ + public void setTransformComponent(TransformComponent transform) { + this.transform = transform; + } + + /** + * Retrieves the mesh render components associated with this entity. + * + * @return a list of mesh render components + */ + public List getComponents() { + return components; + } + + /** + * Renders the entity and its components. + */ + public void renderEntity() { + for (Component component : components) { + // Render each component + } + } + + // Getters and Setters for fields + + /** + * Gets the name of the entity. + * + * @return the name of the entity + */ + public String getName() { + return name; + } + + /** + * Gets the unique identifier of the entity. + * + * @return the unique entity identifier + */ + public UUID getEntityId() { + return entityId; + } + + /** + * Gets the current enabled state of the entity. + * + * @return true if the entity is enabled, false otherwise + */ + public boolean isEnabled() { + return isEnabled; + } + + /** + * Sets the current enabled state of the entity. + * + * @param isEnabled true to enable the entity, false to disable it + */ + public void setIsEnabled(boolean isEnabled) { + this.isEnabled = isEnabled; + } + + /** + * Gets the game system this entity belongs to. + * + * @return the game system the entity is part of + */ + public GameSystem getGameSystem() { + return gameSystem; + } + + /** + * Sets the game system this entity belongs to. + * + * @param gameSystem the game system to set + */ + public void setGameSystem(GameSystem gameSystem) { + this.gameSystem = gameSystem; + } + + /** + * Gets the parent entity of this entity. + * + * @return the parent entity + */ + public Entity getParent() { + return parent; + } + + /** + * Gets the children entities of this entity. + * + * @return the list of children entities + */ + public List getChildren() { + return children; + } +} diff --git a/entity-component-system/src/main/java/com/iluwatar/GameSystem.java b/entity-component-system/src/main/java/com/iluwatar/GameSystem.java new file mode 100644 index 000000000000..9577a9d976ab --- /dev/null +++ b/entity-component-system/src/main/java/com/iluwatar/GameSystem.java @@ -0,0 +1,172 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar; + +import java.util.ArrayList; +import java.util.List; + +/** + * System class that manages entities within the system. + * It handles adding and removing entities, updating them, rendering, + * and sorting them by distance from a reference point. + */ +public class GameSystem { + + private List entities; + + /** + * Constructor for initializing the system with an empty list of entities. + */ + public GameSystem() { + entities = new ArrayList<>(); + } + + /** + * Adds an entity to the system, including its children recursively. + * + * @param entity the entity to be added + */ + public void addEntity(Entity entity) { + if (entity != null) { + entities.add(entity); + entity.setGameSystem(this); + + // Recursively add children entities + for (Entity child : entity.getChildren()) { + addEntity(child); + } + } + } + + /** + * Removes an entity from the system. + * + * @param entity the entity to be removed + */ + public void removeEntity(Entity entity) { + entities.remove(entity); + } + + /** + * Gets the system matrix for a specific entity by considering its transform and the transform of its parent. + * + * @param entity the entity whose system matrix is to be calculated + * @return the 4x4 system transformation matrix + */ + public float[][] getSystemMatrix(Entity entity) { + float[][] systemMatrix = entity.getTransformComponent().getTransformMatrix(); + + if (entity.getParent() != null) { + float[][] parentMatrix = getSystemMatrix(entity.getParent()); + systemMatrix = multiplyMatrices(parentMatrix, systemMatrix); + } + + return systemMatrix; + } + + /** + * Gets the system position of an entity from its transformation matrix. + * + * @param entity the entity whose position is to be retrieved + * @return an array representing the entity's position [x, y, z] + */ + public float[] getSystemPosition(Entity entity) { + float[][] systemMatrix = getSystemMatrix(entity); + return new float[] { systemMatrix[0][3], systemMatrix[1][3], systemMatrix[2][3] }; // Position is in the 4th column + } + + /** + * Updates all entities in the system by calling their update methods. + * + * @param deltaTime the time elapsed since the last update + */ + public void update(float deltaTime) { + for (Entity entity : entities) { + entity.update(deltaTime); + } + } + + /** + * Renders the system (rendering logic can be implemented as needed). + */ + public void renderSystem() { + for (Entity entity : entities) { + // Implement rendering logic + } + } + + /** + * Sorts the entities by their distance from a given reference point in descending order. + * + * @param referencePoint the point from which the distance is measured + */ + public void sortEntitiesByDistance(float[] referencePoint) { + entities.sort((e1, e2) -> { + float[] pos1 = getSystemPosition(e1); + float[] pos2 = getSystemPosition(e2); + float distance1 = calculateDistance(pos1, referencePoint); + float distance2 = calculateDistance(pos2, referencePoint); + return Float.compare(distance2, distance1); // Sort in descending order + }); + } + + public List getEntities() { + return entities; + } + + /** + * Helper method to calculate the distance between two points in 3D space. + * + * @param point1 the first point + * @param point2 the second point + * @return the distance between the two points + */ + private float calculateDistance(float[] point1, float[] point2) { + float dx = point1[0] - point2[0]; + float dy = point1[1] - point2[1]; + float dz = point1[2] - point2[2]; + return (float) Math.sqrt(dx * dx + dy * dy + dz * dz); + } + + /** + * Helper method to multiply two 4x4 matrices. + * + * @param matrix1 the first matrix + * @param matrix2 the second matrix + * @return the resulting matrix after multiplication + */ + private float[][] multiplyMatrices(float[][] matrix1, float[][] matrix2) { + float[][] result = new float[4][4]; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + result[i][j] = 0; + for (int k = 0; k < 4; k++) { + result[i][j] += matrix1[i][k] * matrix2[k][j]; + } + } + } + return result; + } +} diff --git a/entity-component-system/src/main/java/com/iluwatar/HealthComponent.java b/entity-component-system/src/main/java/com/iluwatar/HealthComponent.java new file mode 100644 index 000000000000..334125bc5a1d --- /dev/null +++ b/entity-component-system/src/main/java/com/iluwatar/HealthComponent.java @@ -0,0 +1,121 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar; + +import java.util.logging.Logger; + +/** + * Abstract class representing a health component in the ECS system. + * This component tracks the current health, max health, and whether the entity is alive. + * Subclasses must implement the updateHealth method to define custom behavior for updating health. + */ +public class HealthComponent extends Component { + + private static final Logger logger = Logger.getLogger(HealthComponent.class.getName()); + + private float currentHealth; + private float maxHealth; + private boolean isAlive; + + /** + * Constructor for initializing the health component with a maximum health value. + * The current health is set to the maximum health, and the entity is considered alive. + * + * @param maxHealth the maximum health of the entity + */ + public HealthComponent(float maxHealth) { + this.maxHealth = maxHealth; + this.currentHealth = maxHealth; + this.isAlive = true; + } + + /** + * Abstract method for updating the health component. + * Subclasses must implement this method to define how health is updated. + * + * @param deltaTime the time elapsed since the last update + */ + @Override + public void update(float deltaTime) { + logger.info(String.format("Updated health component: %f", currentHealth)); + } + + /** + * Applies damage to the entity. If the entity is alive, the damage is subtracted from the current health. + * If health drops to zero or below, the entity is marked as dead. + * + * @param damage the amount of damage to apply + */ + public void applyDamage(float damage) { + if (isAlive) { + currentHealth -= damage; + if (currentHealth <= 0) { + currentHealth = 0; + isAlive = false; + } + } + } + + /** + * Heals the entity by a specified amount. If the entity is alive, the current health is increased, + * but it cannot exceed the maximum health. + * + * @param amount the amount to heal + */ + public void heal(float amount) { + if (isAlive) { + currentHealth += amount; + if (currentHealth > maxHealth) { + currentHealth = maxHealth; + } + } + } + + // Setters and Getters + + public float getCurrentHealth() { + return currentHealth; + } + + public void setCurrentHealth(float currentHealth) { + this.currentHealth = currentHealth; + } + + public float getMaxHealth() { + return maxHealth; + } + + public void setMaxHealth(float maxHealth) { + this.maxHealth = maxHealth; + } + + public boolean isAlive() { + return isAlive; + } + + public void setAlive(boolean isAlive) { + this.isAlive = isAlive; + } +} diff --git a/entity-component-system/src/main/java/com/iluwatar/TransformComponent.java b/entity-component-system/src/main/java/com/iluwatar/TransformComponent.java new file mode 100644 index 000000000000..e28113ccfb8e --- /dev/null +++ b/entity-component-system/src/main/java/com/iluwatar/TransformComponent.java @@ -0,0 +1,171 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar; + +/** + * A component that handles the transformation of an entity in 3D space. + * This includes position, scale, and rotation (represented by Euler angles). + */ +public class TransformComponent extends Component { + + private float[] position; // Position of the entity (x, y, z) + private float[] scale; // Scale of the entity (x, y, z) + private float[] rotation; // Rotation of the entity (pitch, yaw, roll) + + /** + * Constructs a TransformComponent with the specified position, rotation, and scale. + * + * @param initPosition the initial position of the entity + * @param initRotation the initial rotation (Euler angles: pitch, yaw, roll) + * @param initScale the initial scale of the entity + */ + public TransformComponent(float[] initPosition, float[] initRotation, float[] initScale) { + super(); + this.position = initPosition != null ? initPosition : new float[]{0.0f, 0.0f, 0.0f}; + this.scale = initScale != null ? initScale : new float[]{1.0f, 1.0f, 1.0f}; + this.rotation = initRotation != null ? initRotation : new float[]{0.0f, 0.0f, 0.0f}; + } + + /** + * Default constructor that initializes the transform component with default values. + */ + public TransformComponent() { + this(new float[]{0.0f, 0.0f, 0.0f}, new float[]{0.0f, 0.0f, 0.0f}, new float[]{1.0f, 1.0f, 1.0f}); + } + + /** + * Updates the transform component (add any transformations here if needed). + * + * @param deltaTime the time elapsed since the last update + */ + @Override + public void update(float deltaTime) { + // No specific updates in this implementation + } + + /** + * Returns the 4x4 transformation matrix that represents the position, scale, and rotation of the entity. + * + * @return a 4x4 transformation matrix + */ + public float[][] getTransformMatrix() { + float[][] matrix = new float[4][4]; + + // Initialize as an identity matrix + matrix[0][0] = 1.0f; + matrix[0][1] = 0.0f; + matrix[0][2] = 0.0f; + matrix[0][3] = 0.0f; + + matrix[1][0] = 0.0f; + matrix[1][1] = 1.0f; + matrix[1][2] = 0.0f; + matrix[1][3] = 0.0f; + + matrix[2][0] = 0.0f; + matrix[2][1] = 0.0f; + matrix[2][2] = 1.0f; + matrix[2][3] = 0.0f; + + matrix[3][0] = 0.0f; + matrix[3][1] = 0.0f; + matrix[3][2] = 0.0f; + matrix[3][3] = 1.0f; + + // Apply scaling + matrix[0][0] *= scale[0]; + matrix[1][1] *= scale[1]; + matrix[2][2] *= scale[2]; + + // Apply rotation (pitch, yaw, roll) + applyRotation(matrix); + + // Apply translation (position) + matrix[0][3] = position[0]; + matrix[1][3] = position[1]; + matrix[2][3] = position[2]; + + return matrix; + } + + /** + * Applies the rotation to the transformation matrix based on the Euler angles. + * + * @param matrix the transformation matrix to be modified + */ + private void applyRotation(float[][] matrix) { + // Matrix transformations using rotation directly + matrix[1][1] = (float) Math.cos(rotation[0]); // pitch + matrix[1][2] = (float) -Math.sin(rotation[0]); + matrix[2][1] = (float) Math.sin(rotation[0]); + matrix[2][2] = (float) Math.cos(rotation[0]); + + matrix[0][0] = (float) Math.cos(rotation[1]); // yaw + matrix[0][2] = (float) Math.sin(rotation[1]); + matrix[2][0] = (float) -Math.sin(rotation[1]); + matrix[2][2] = (float) Math.cos(rotation[1]); + + matrix[0][0] = (float) Math.cos(rotation[2]); // roll + matrix[0][1] = (float) -Math.sin(rotation[2]); + matrix[1][0] = (float) Math.sin(rotation[2]); + matrix[1][1] = (float) Math.cos(rotation[2]); + } + + /** + * Sets the rotation of the entity using Euler angles (pitch, yaw, roll). + * + * @param eulerAngles an array of Euler angles [pitch, yaw, roll] + */ + public void setRotation(float[] eulerAngles) { + this.rotation = eulerAngles != null ? eulerAngles : new float[]{0.0f, 0.0f, 0.0f}; // pitch, yaw, roll + } + + /** + * Gets the rotation of the entity as Euler angles (pitch, yaw, roll). + * + * @return the rotation as an array of Euler angles [pitch, yaw, roll] + */ + public float[] getRotation() { + return rotation; + } + + // Getters and Setters for position and scale + + public float[] getPosition() { + return position; + } + + public void setPosition(float[] position) { + this.position = position != null ? position : new float[]{0.0f, 0.0f, 0.0f}; + } + + public float[] getScale() { + return scale; + } + + public void setScale(float[] scale) { + this.scale = scale != null ? scale : new float[]{1.0f, 1.0f, 1.0f}; + } +} diff --git a/entity-component-system/src/main/java/com/iluwatar/VelocityComponent.java b/entity-component-system/src/main/java/com/iluwatar/VelocityComponent.java new file mode 100644 index 000000000000..0008a51ae8f2 --- /dev/null +++ b/entity-component-system/src/main/java/com/iluwatar/VelocityComponent.java @@ -0,0 +1,148 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar; + +import java.util.logging.Logger; + +/** + * A component that handles the velocity of an entity in 3D space. + * It allows updating velocity, applying forces, and friction. + */ +public class VelocityComponent extends Component { + + private static final Logger logger = Logger.getLogger(VelocityComponent.class.getName()); + + private float velocityX; // The velocity in the X direction + private float velocityY; // The velocity in the Y direction + private float velocityZ; // The velocity in the Z direction + + /** + * Constructs a VelocityComponent with the given velocity values in the X, Y, and Z directions. + * + * @param velocityX the initial velocity in the X direction + * @param velocityY the initial velocity in the Y direction + * @param velocityZ the initial velocity in the Z direction + */ + public VelocityComponent(float velocityX, float velocityY, float velocityZ) { + this.velocityX = velocityX; + this.velocityY = velocityY; + this.velocityZ = velocityZ; + } + + /** + * Updates the velocity of the entity based on delta time. + * This method multiplies the current velocity by the delta time to simulate movement. + * + * @param deltaTime the time elapsed since the last update + */ + public void update(float deltaTime) { + velocityX += velocityX * deltaTime; + velocityY += velocityY * deltaTime; + velocityZ += velocityZ * deltaTime; + + } + + /** + * Applies a force to the entity, updating its velocity. + * The force values will be added to the current velocity. + * + * @param forceX the force applied in the X direction + * @param forceY the force applied in the Y direction + * @param forceZ the force applied in the Z direction + */ + public void applyForce(float forceX, float forceY, float forceZ) { + this.velocityX += forceX; + this.velocityY += forceY; + this.velocityZ += forceZ; + } + + /** + * Applies friction to the entity's velocity. The velocity is reduced by the friction coefficient. + * A friction coefficient of 0 means no friction, and 1 means full friction (stopping the entity). + * + * @param frictionCoefficient the coefficient of friction applied to the velocity + */ + public void applyFriction(float frictionCoefficient) { + this.velocityX *= (1 - frictionCoefficient); + this.velocityY *= (1 - frictionCoefficient); + this.velocityZ *= (1 - frictionCoefficient); + } + + // Getters and setters for velocityX, velocityY, and velocityZ + + /** + * Returns the velocity in the X direction. + * + * @return the velocity in the X direction + */ + public float getVelocityX() { + return velocityX; + } + + /** + * Sets the velocity in the X direction. + * + * @param velocityX the velocity in the X direction + */ + public void setVelocityX(float velocityX) { + this.velocityX = velocityX; + } + + /** + * Returns the velocity in the Y direction. + * + * @return the velocity in the Y direction + */ + public float getVelocityY() { + return velocityY; + } + + /** + * Sets the velocity in the Y direction. + * + * @param velocityY the velocity in the Y direction + */ + public void setVelocityY(float velocityY) { + this.velocityY = velocityY; + } + + /** + * Returns the velocity in the Z direction. + * + * @return the velocity in the Z direction + */ + public float getVelocityZ() { + return velocityZ; + } + + /** + * Sets the velocity in the Z direction. + * + * @param velocityZ the velocity in the Z direction + */ + public void setVelocityZ(float velocityZ) { + this.velocityZ = velocityZ; + } +} diff --git a/entity-component-system/src/test/java/com/iluwatar/AppTest.java b/entity-component-system/src/test/java/com/iluwatar/AppTest.java new file mode 100644 index 000000000000..647538d5113e --- /dev/null +++ b/entity-component-system/src/test/java/com/iluwatar/AppTest.java @@ -0,0 +1,124 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class AppTest { + + private Entity entity1; + private Entity entity2; + private HealthComponent health1; + private VelocityComponent velocity1; + TransformComponent transform1 = new TransformComponent(new float[]{0.0f, 0.0f, 0.0f}, + new float[]{0.0f, 0.0f, 0.0f}, new float[]{1.0f, 1.0f, 1.0f}); + TransformComponent transform2 = new TransformComponent(new float[]{5.0f, 0.0f, 0.0f}, + new float[]{0.0f, 45.0f, 0.0f}, new float[]{1.0f, 1.0f, 1.0f}); + + @BeforeEach + public void setUp() { + entity1 = new Entity("Entity1"); + entity2 = new Entity("Entity2"); + + entity1.addComponent(transform1); + entity2.addComponent(transform2); + + health1 = new HealthComponent(100); + entity1.addComponent(health1); + + velocity1 = new VelocityComponent(1.0f, 0.0f, 0.0f); + entity1.addComponent(velocity1); + } + + @Test + public void testHealthComponentApplyDamage() { + + health1.applyDamage(30); + + assertEquals(70, health1.getCurrentHealth(), "Health should be reduced by 30"); + } + + @Test + public void testVelocityComponentApplyForce() { + + velocity1.applyForce(0.5f, 0.0f, 0.0f); + + assertEquals(1.5f, velocity1.getVelocityX(), "Velocity X should be updated by the applied force"); + assertEquals(0.0f, velocity1.getVelocityY(), "Velocity Y should remain unchanged"); + assertEquals(0.0f, velocity1.getVelocityZ(), "Velocity Z should remain unchanged"); + } + + @Test + public void testEntityUpdate() { + + float deltaTime = 1.0f / 60.0f; + velocity1.setVelocityY(12.0f); + float initialVelocityY = velocity1.getVelocityY(); + velocity1.update(deltaTime); + + assertTrue(velocity1.getVelocityY() > initialVelocityY, "Velocity should increase over time"); + } + + @Test + public void testEntityHealthAfterDamageAndForce() { + + health1.applyDamage(40); + + velocity1.applyForce(0.2f, 0.0f, 0.0f); + + entity1.update(1.0f / 60.0f); + + assertEquals(60, health1.getCurrentHealth(), "Health should be reduced by 40"); + assertEquals(1.2f, velocity1.getVelocityX(), "Velocity X should be updated by the applied force"); + } + + @Test + public void testFinalEntityStateAfterSimulation() { + + GameSystem gameSystem = new GameSystem(); + gameSystem.addEntity(entity1); + gameSystem.addEntity(entity2); + TransformComponent transform1 = new TransformComponent(new float[]{5.0f, 0.0f, 0.0f}, + new float[]{0.0f, 45.0f, 0.0f}, new float[]{1.0f, 1.0f, 1.0f}); + entity1.setTransformComponent(transform1); + + for (int i = 0; i < 10; i++) { + gameSystem.update(1.0f / 60.0f); + if (i == 5) { + health1.applyDamage(30); + } + if (i == 3) { + velocity1.applyForce(0.5f, 0.0f, 0.0f); + } + } + + assertEquals(70, health1.getCurrentHealth(), "Final health should be 70 after applying 30 damage"); + assertEquals(1.5f, velocity1.getVelocityX(), "Final velocity X should be 1.5 after applying force"); + assertNotNull(entity1.getTransformComponent(), "Entity1 should have a transform component"); + + } +} \ No newline at end of file diff --git a/entity-component-system/src/test/java/com/iluwatar/ComponentTest.java b/entity-component-system/src/test/java/com/iluwatar/ComponentTest.java new file mode 100644 index 000000000000..6100388fae01 --- /dev/null +++ b/entity-component-system/src/test/java/com/iluwatar/ComponentTest.java @@ -0,0 +1,52 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class ComponentTest { + + @Test + public void testComponentEnabled() { + Component component = new HealthComponent(100); + component.setEnabled(true); + + assertTrue(component.getEnabled(), "The component should be enabled."); + + component.setEnabled(false); + assertFalse(component.getEnabled(), "The component should be disabled."); + } + + @Test + public void testComponentParent() { + Component component = new HealthComponent(100); + Entity parentEntity = new Entity("ParentEntity"); + + component.setParent(parentEntity); + assertEquals(parentEntity, component.getParent(), "The component's parent should be set correctly."); + } +} diff --git a/entity-component-system/src/test/java/com/iluwatar/EntityTest.java b/entity-component-system/src/test/java/com/iluwatar/EntityTest.java new file mode 100644 index 000000000000..17f9b6017568 --- /dev/null +++ b/entity-component-system/src/test/java/com/iluwatar/EntityTest.java @@ -0,0 +1,98 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class EntityTest { + + private Entity entity1; + private Entity entity2; + private TransformComponent transform1; + private TransformComponent transform2; + + @BeforeEach + public void setUp() { + entity1 = new Entity("Entity1"); + entity2 = new Entity("Entity2"); + + transform1 = new TransformComponent(new float[]{0.0f, 0.0f, 0.0f}, + new float[]{0.0f, 0.0f, 0.0f}, new float[]{1.0f, 1.0f, 1.0f}); + transform2 = new TransformComponent(new float[]{5.0f, 0.0f, 0.0f}, + new float[]{0.0f, 45.0f, 0.0f}, new float[]{1.0f, 1.0f, 1.0f}); + + } + + @Test + public void testAddComponent() { + Component component = new HealthComponent(100); + entity1.addComponent(component); + + assertEquals(2, entity1.getComponents().size(), "Entity1 should have 1 component."); + } + + @Test + public void testRemoveComponent() { + Component component = new HealthComponent(100); + + entity2.removeComponent(component); + + assertEquals(1, entity2.getComponents().size(), "Entity1 should have no components."); + } + + @Test + public void testSetParent() { + entity1 = new Entity("Entity1"); + entity2 = new Entity("Entity2"); + entity1.setParent(entity2); + assertEquals(entity2.getEntityId(), entity1.getParent().getEntityId(), "Entity1 should have Entity2 as its parent."); + } + + @Test + public void testAddChild() { + entity1.addChild(entity2); + + assertTrue(entity1.getChildren().contains(entity2), "Entity1 should have Entity2 as its child."); + } + + @Test + public void testSetEnabled() { + entity1.setEnabled(false); + assertFalse(entity1.getEnabled(), "Entity1 should be disabled."); + entity1.setEnabled(true); + assertTrue(entity1.getEnabled(), "Entity1 should be enabled."); + } + + @Test + public void testUpdate() { + float deltaTime = 1.0f / 60.0f; + entity1.update(deltaTime); + + assertNotNull(entity1, "Entity1 should be updated."); + } +} diff --git a/entity-component-system/src/test/java/com/iluwatar/GameSystemTest.java b/entity-component-system/src/test/java/com/iluwatar/GameSystemTest.java new file mode 100644 index 000000000000..e0c08a637017 --- /dev/null +++ b/entity-component-system/src/test/java/com/iluwatar/GameSystemTest.java @@ -0,0 +1,111 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; + +public class GameSystemTest { + + private GameSystem gameSystem; + private Entity entity1; + private Entity entity2; + private Entity childEntity; + + @BeforeEach + public void setUp() { + gameSystem = new GameSystem(); + + entity1 = new Entity("Entity1"); + entity2 = new Entity("Entity2"); + childEntity = new Entity("ChildEntity"); + + entity1.addChild(childEntity); + + gameSystem.addEntity(entity1); + gameSystem.addEntity(entity2); + } + + @Test + public void testAddEntity() { + assertEquals(3, gameSystem.getEntities().size(), "There should be three entities in the system."); + } + + @Test + public void testRemoveEntity() { + gameSystem.removeEntity(entity2); + assertEquals(2, gameSystem.getEntities().size(), "Entity2 should be removed from the system."); + } + + @Test + public void testGetSystemMatrix() { + // Set a mock transform for entity1 and childEntity + float[][] matrix1 = gameSystem.getSystemMatrix(entity1); + float[][] matrix2 = gameSystem.getSystemMatrix(childEntity); + + assertNotNull(matrix1, "System matrix for entity1 should not be null."); + assertNotNull(matrix2, "System matrix for childEntity should not be null."); + assertNotEquals(matrix1, matrix2, "Matrices should be different due to different transformations."); + } + + @Test + public void testGetSystemPosition() { + float[] position1 = gameSystem.getSystemPosition(entity1); + float[] position2 = gameSystem.getSystemPosition(entity2); + + assertNotNull(position1, "Position for entity1 should not be null."); + assertNotNull(position2, "Position for entity2 should not be null."); + assertEquals(3, position1.length, "Position should be a 3D vector."); + assertEquals(3, position2.length, "Position should be a 3D vector."); + } + + @Test + public void testSortEntitiesByDistance() { + + float[] referencePoint = {0.0f, 0.0f, 0.0f}; + + entity1.getTransformComponent().setPosition(new float[] {1.0f, 0.0f, 0.0f}); + entity2.getTransformComponent().setPosition(new float[] {3.0f, 0.0f, 0.0f}); + + gameSystem.sortEntitiesByDistance(referencePoint); + + List sortedEntities = gameSystem.getEntities(); + + assertEquals(entity2, sortedEntities.get(0), "Entity2 should be closer to the reference point than Entity1."); + assertEquals(entity1, sortedEntities.get(1), "Entity1 should be farther from the reference point than Entity2."); + } + + @Test + public void testRenderSystem() { + + try { + gameSystem.renderSystem(); + } catch (Exception e) { + fail("Render method should not throw any exceptions."); + } + } +} diff --git a/entity-component-system/src/test/java/com/iluwatar/HealthComponentTest.java b/entity-component-system/src/test/java/com/iluwatar/HealthComponentTest.java new file mode 100644 index 000000000000..6c28c95088e7 --- /dev/null +++ b/entity-component-system/src/test/java/com/iluwatar/HealthComponentTest.java @@ -0,0 +1,75 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class HealthComponentTest { + + private HealthComponent healthComponent; + + @BeforeEach + public void setUp() { + healthComponent = new HealthComponent(100); + } + + @Test + public void testInitialHealth() { + assertEquals(100, healthComponent.getCurrentHealth(), "Initial health should be 100."); + } + + @Test + public void testApplyDamage() { + healthComponent.applyDamage(30); + assertEquals(70, healthComponent.getCurrentHealth(), "Health should decrease by 30 after damage."); + + healthComponent.applyDamage(100); + assertEquals(0, healthComponent.getCurrentHealth(), "Health should not go below 0."); + } + + @Test + public void testHeal() { + healthComponent.applyDamage(50); + healthComponent.heal(30); + assertEquals(80, healthComponent.getCurrentHealth(), "Health should increase by 30 after healing."); + + healthComponent.heal(50); + assertEquals(100, healthComponent.getCurrentHealth(), "Health should not exceed maximum (100)."); + } + + @Test + public void testHealthCannotGoAboveMax() { + healthComponent.heal(150); + assertEquals(100, healthComponent.getCurrentHealth(), "Health should not exceed the max value (100)."); + } + + @Test + public void testHealthCannotGoBelowZero() { + healthComponent.applyDamage(200); + assertEquals(0, healthComponent.getCurrentHealth(), "Health should not go below 0."); + } +} diff --git a/entity-component-system/src/test/java/com/iluwatar/TransformComponentTest.java b/entity-component-system/src/test/java/com/iluwatar/TransformComponentTest.java new file mode 100644 index 000000000000..b5d7b0830393 --- /dev/null +++ b/entity-component-system/src/test/java/com/iluwatar/TransformComponentTest.java @@ -0,0 +1,83 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class TransformComponentTest { + + private TransformComponent transform; + + @BeforeEach + public void setUp() { + transform = new TransformComponent(new float[]{0.0f, 0.0f, 0.0f}, + new float[]{0.0f, 0.0f, 0.0f}, new float[]{1.0f, 1.0f, 1.0f}); + } + + @Test + public void testGetPosition() { + float[] position = transform.getPosition(); + + assertArrayEquals(new float[]{0.0f, 0.0f, 0.0f}, position, "The position should be initialized correctly."); + } + + @Test + public void testSetPosition() { + transform.setPosition(new float[]{10.0f, 20.0f, 30.0f}); + + assertArrayEquals(new float[]{10.0f, 20.0f, 30.0f}, transform.getPosition(), "Position should be updated correctly."); + } + + @Test + public void testGetRotation() { + float[] rotation = transform.getRotation(); + + assertArrayEquals(new float[]{0.0f, 0.0f, 0.0f}, rotation, "The rotation should be initialized correctly."); + } + + @Test + public void testSetRotation() { + transform.setRotation(new float[]{90.0f, 0.0f, 0.0f}); + + assertArrayEquals(new float[]{90.0f, 0.0f, 0.0f}, transform.getRotation(), "Rotation should be updated correctly."); + } + + @Test + public void testGetScale() { + float[] scale = transform.getScale(); + + assertArrayEquals(new float[]{1.0f, 1.0f, 1.0f}, scale, "The scale should be initialized correctly."); + } + + @Test + public void testSetScale() { + transform.setScale(new float[]{2.0f, 2.0f, 2.0f}); + + assertArrayEquals(new float[]{2.0f, 2.0f, 2.0f}, transform.getScale(), "Scale should be updated correctly."); + } +} diff --git a/entity-component-system/src/test/java/com/iluwatar/VelocityComponentTest.java b/entity-component-system/src/test/java/com/iluwatar/VelocityComponentTest.java new file mode 100644 index 000000000000..d0a762ac4f42 --- /dev/null +++ b/entity-component-system/src/test/java/com/iluwatar/VelocityComponentTest.java @@ -0,0 +1,64 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class VelocityComponentTest { + + private VelocityComponent velocity; + + @BeforeEach + public void setUp() { + velocity = new VelocityComponent(1.0f, 0.0f, 0.0f); + } + + @Test + public void testApplyForce() { + velocity.applyForce(2.0f, 0.0f, 0.0f); + + assertEquals(3.0f, velocity.getVelocityX(), "VelocityX should increase after applying force."); + } + + @Test + public void testApplyFriction() { + velocity.applyFriction(0.1f); // Applying friction coefficient of 0.1 + + assertEquals(0.9f, velocity.getVelocityX(), "VelocityX should be reduced by the friction coefficient."); + } + + @Test + public void testUpdateVelocity() { + float deltaTime = 1.0f / 60.0f; + + float initialVelocityX = velocity.getVelocityX(); + velocity.update(deltaTime); + + assertTrue(velocity.getVelocityX() > initialVelocityX, "VelocityX should increase after updating."); + } +} diff --git a/pom.xml b/pom.xml index 5cc512b7de94..deb4514b7e6e 100644 --- a/pom.xml +++ b/pom.xml @@ -223,6 +223,7 @@ templateview money table-inheritance + entity-component-system diff --git a/update-header.sh b/update-header.sh index 48da4dcd6125..568d00d52a03 100755 --- a/update-header.sh +++ b/update-header.sh @@ -1,4 +1,29 @@ #!/bin/bash +# +# This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). +# +# The MIT License +# Copyright © 2014-2022 Ilkka Seppälä +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# + # Find all README.md files in subdirectories one level deep # and replace "### " with "## " at the beginning of lines From 49cfb6b3e6e002b9e7b23a43ed2fe349423a6379 Mon Sep 17 00:00:00 2001 From: R00V <149782421+rofidakhaled@users.noreply.github.com> Date: Wed, 11 Dec 2024 15:24:34 +0200 Subject: [PATCH 2/9] adding test cases to all classes --- .../src/main/java/com/iluwatar/App.java | 31 +++--- .../src/main/java/com/iluwatar/Entity.java | 5 +- .../java/com/iluwatar/HealthComponent.java | 2 +- .../test/java/com/iluwatar/ComponentTest.java | 15 +++ .../test/java/com/iluwatar/EntityTest.java | 97 ++++++++++++++++++- .../com/iluwatar/HealthComponentTest.java | 48 +++++++++ .../com/iluwatar/TransformComponentTest.java | 21 ++++ .../com/iluwatar/VelocityComponentTest.java | 21 ++++ 8 files changed, 224 insertions(+), 16 deletions(-) diff --git a/entity-component-system/src/main/java/com/iluwatar/App.java b/entity-component-system/src/main/java/com/iluwatar/App.java index f0fb1569e319..79906898270e 100644 --- a/entity-component-system/src/main/java/com/iluwatar/App.java +++ b/entity-component-system/src/main/java/com/iluwatar/App.java @@ -24,12 +24,18 @@ */ package com.iluwatar; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * The main entry point for the application. * This class simulates a game loop where entities are created, updated, and their states are modified. */ public class App { + // Create a logger instance + public static final Logger logger = LoggerFactory.getLogger(App.class); + /** * The main method that runs the application. * It creates entities, adds components, updates them over several frames, @@ -38,7 +44,7 @@ public class App { * @param args Command-line arguments (not used in this application) */ public static void main(String[] args) { - // Create example entities + Entity entity1 = new Entity("Entity1"); Entity entity2 = new Entity("Entity2"); @@ -70,7 +76,7 @@ public static void main(String[] args) { // Simulate for a few frames for (int i = 0; i < 10; i++) { - System.out.println("Frame: " + (i + 1)); + logger.info("Frame: {}", i + 1); // Update all entities in the system gameSystem.update(deltaTime); @@ -78,14 +84,14 @@ public static void main(String[] args) { // Apply some damage to entity1's health component at frame 6 if (i == 5) { health1.applyDamage(30); - System.out.println("Entity1's health after damage: " + health1.getCurrentHealth()); + logger.info("Entity1's health after damage: {}", health1.getCurrentHealth()); } // Apply some force to entity1's velocity at frame 3 if (i == 3) { velocity1.applyForce(0.5f, 0.0f, 0.0f); - System.out.println("Entity1's velocity after force: (" + velocity1.getVelocityX() + ", " - + velocity1.getVelocityY() + ", " + velocity1.getVelocityZ() + ")"); + logger.info("Entity1's velocity after force: ({}, {}, {})", velocity1.getVelocityX(), + velocity1.getVelocityY(), velocity1.getVelocityZ()); } // Render the system (optional rendering logic can be added here) @@ -93,12 +99,13 @@ public static void main(String[] args) { } // After the simulation, check final entity states - System.out.println("\nFinal Entity States:"); - System.out.println("Entity1 position: " + entity1.getTransformComponent().getPosition()[0] + ", " - + entity1.getTransformComponent().getPosition()[1] + ", " - + entity1.getTransformComponent().getPosition()[2]); - System.out.println("Entity1 velocity: " + velocity1.getVelocityX() + ", " - + velocity1.getVelocityY() + ", " + velocity1.getVelocityZ()); - System.out.println("Entity1 health: " + health1.getCurrentHealth()); + logger.info("\nFinal Entity States:"); + logger.info("Entity1 position: {}, {}, {}", + entity1.getTransformComponent().getPosition()[0], + entity1.getTransformComponent().getPosition()[1], + entity1.getTransformComponent().getPosition()[2]); + logger.info("Entity1 velocity: {}, {}, {}", + velocity1.getVelocityX(), velocity1.getVelocityY(), velocity1.getVelocityZ()); + logger.info("Entity1 health: {}", health1.getCurrentHealth()); } } diff --git a/entity-component-system/src/main/java/com/iluwatar/Entity.java b/entity-component-system/src/main/java/com/iluwatar/Entity.java index fe78dade3bf4..f22d69773115 100644 --- a/entity-component-system/src/main/java/com/iluwatar/Entity.java +++ b/entity-component-system/src/main/java/com/iluwatar/Entity.java @@ -26,6 +26,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.UUID; /** @@ -58,6 +59,7 @@ public Entity(String entityName) { final UUID entityId = UUID.randomUUID(); // Generates a unique UUID for this entity transform = new TransformComponent(new float[] {0.0f, 0.0f, 0.0f}, new float[] {0.0f, 0.0f, 0.0f}, new float[] {1.0f, 1.0f, 1.0f}); addComponent(transform); + } /** @@ -90,7 +92,7 @@ public void removeComponent(Component component) { */ public Component getComponent(String componentName) { for (Component component : components) { - if (component.getName().equals(componentName)) { + if (Objects.equals(component.getName(), componentName)) { return component; } } @@ -204,6 +206,7 @@ public void setTransformComponent(TransformComponent transform) { * @return a list of mesh render components */ public List getComponents() { + return components; } diff --git a/entity-component-system/src/main/java/com/iluwatar/HealthComponent.java b/entity-component-system/src/main/java/com/iluwatar/HealthComponent.java index 334125bc5a1d..5444d5d4c8ad 100644 --- a/entity-component-system/src/main/java/com/iluwatar/HealthComponent.java +++ b/entity-component-system/src/main/java/com/iluwatar/HealthComponent.java @@ -59,7 +59,7 @@ public HealthComponent(float maxHealth) { */ @Override public void update(float deltaTime) { - logger.info(String.format("Updated health component: %f", currentHealth)); + //update health } /** diff --git a/entity-component-system/src/test/java/com/iluwatar/ComponentTest.java b/entity-component-system/src/test/java/com/iluwatar/ComponentTest.java index 6100388fae01..4abb81cd3d68 100644 --- a/entity-component-system/src/test/java/com/iluwatar/ComponentTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/ComponentTest.java @@ -29,6 +29,21 @@ import static org.junit.jupiter.api.Assertions.*; public class ComponentTest { + @Test + public void testGetName() { + Component component = new HealthComponent(100); + component.setName("Health"); + + assertEquals("Health", component.getName(), "getName should return 'TestComponent'"); + } + + @Test + public void testSetName() { + Component component = new HealthComponent(100); + component.setName("Health"); + + assertEquals("Health", component.getName(), "getName should return 'TestComponent'"); + } @Test public void testComponentEnabled() { diff --git a/entity-component-system/src/test/java/com/iluwatar/EntityTest.java b/entity-component-system/src/test/java/com/iluwatar/EntityTest.java index 17f9b6017568..1e1a232558fa 100644 --- a/entity-component-system/src/test/java/com/iluwatar/EntityTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/EntityTest.java @@ -65,6 +65,7 @@ public void testRemoveComponent() { assertEquals(1, entity2.getComponents().size(), "Entity1 should have no components."); } + /* @Test public void testSetParent() { entity1 = new Entity("Entity1"); @@ -72,20 +73,71 @@ public void testSetParent() { entity1.setParent(entity2); assertEquals(entity2.getEntityId(), entity1.getParent().getEntityId(), "Entity1 should have Entity2 as its parent."); } - +*/ @Test public void testAddChild() { entity1.addChild(entity2); assertTrue(entity1.getChildren().contains(entity2), "Entity1 should have Entity2 as its child."); } - +/* @Test public void testSetEnabled() { entity1.setEnabled(false); assertFalse(entity1.getEnabled(), "Entity1 should be disabled."); entity1.setEnabled(true); assertTrue(entity1.getEnabled(), "Entity1 should be enabled."); + } */ + + @Test + public void testGetComponent() { + + Component component = new HealthComponent(100); + component.setName("HealthComponent"); + Entity entity = new Entity("Entity1"); + entity.addComponent(component); + Component retrievedComponent = entity.getComponent("HealthComponent"); + + assertEquals(component, retrievedComponent, "The component returned should match the added component."); + + Component nonExistentComponent = entity.getComponent("NonExistentComponent"); + assertNull(nonExistentComponent, "The component should return null if it doesn't exist."); + } + + @Test + public void testSetEnabled() { + + Component component = new HealthComponent(100); + Entity entity = new Entity("MyEntity"); + entity.addComponent(component); + + assertFalse(component.getEnabled(), "Component should be disabled initially."); + + entity.setEnabled(false); + + assertFalse(component.getEnabled(), "Component should be disabled after calling setEnabled(false)."); + + entity.setEnabled(true); + + assertTrue(component.getEnabled(), "Component should be enabled after calling setEnabled(true)."); + } + + @Test + public void testSetParent() { + + Entity parent = new Entity("parent"); + Entity child = new Entity("child"); + + child.setParent(parent); + + assertTrue(parent.getChildren().contains(child), "Parent should contain child in its children list."); + + Entity newParent = new Entity("newParent"); + child.setParent(newParent); + + assertFalse(parent.getChildren().contains(child), "Parent should no longer contain child after setting a new parent."); + + assertTrue(newParent.getChildren().contains(child), "New parent should contain child in its children list."); } @Test @@ -95,4 +147,45 @@ public void testUpdate() { assertNotNull(entity1, "Entity1 should be updated."); } + + @Test + public void testRenderEntity() { + + Component component = new HealthComponent(100); + Entity entity = new Entity("MyEntity"); + entity.addComponent(component); + entity.renderEntity(); + + assertDoesNotThrow(() -> component.update(1.0f), "render function should not throw an exception"); + } + + @Test + public void testGetName() { + Entity entity = new Entity("MyEntity"); + + assertEquals("MyEntity", entity.getName(), "The entity name should match the given name."); + } + + @Test + public void testSetIsEnabled() { + Entity entity = new Entity("MyEntity"); + + entity.setIsEnabled(false); + + assertFalse(entity.isEnabled(), "The entity should be disabled after calling setIsEnabled(false)."); + + entity.setIsEnabled(true); + + assertTrue(entity.isEnabled(), "The entity should be enabled after calling setIsEnabled(true)."); + } + + @Test + public void testGetAndSetGameSystem() { + + GameSystem gameSystem = new GameSystem(); + Entity entity = new Entity("MyEntity"); + entity.setGameSystem(gameSystem); + + assertEquals(gameSystem, entity.getGameSystem(), "The game system should match the one set."); + } } diff --git a/entity-component-system/src/test/java/com/iluwatar/HealthComponentTest.java b/entity-component-system/src/test/java/com/iluwatar/HealthComponentTest.java index 6c28c95088e7..7a3ee47ebf23 100644 --- a/entity-component-system/src/test/java/com/iluwatar/HealthComponentTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/HealthComponentTest.java @@ -60,7 +60,55 @@ public void testHeal() { healthComponent.heal(50); assertEquals(100, healthComponent.getCurrentHealth(), "Health should not exceed maximum (100)."); } + @Test + public void testUpdateFunction() { + healthComponent = new HealthComponent(100); + + assertDoesNotThrow(() -> healthComponent.update(1.0f), "update function should not throw an exception"); + } + + @Test + public void testGetMaxHealth() { + HealthComponent healthComponent = new HealthComponent(100f); + + assertEquals(100f, healthComponent.getMaxHealth(), "Max health should be 100."); + } + + @Test + public void testSetMaxHealth() { + HealthComponent healthComponent = new HealthComponent(100f); + healthComponent.setMaxHealth(120f); + + assertEquals(120f, healthComponent.getMaxHealth(), "Max health should be updated to 120."); + } + + @Test + public void testIsAlive() { + + HealthComponent healthComponent = new HealthComponent(100f); + assertTrue(healthComponent.isAlive(), "Entity should be alive initially."); + healthComponent.applyDamage(100f); + + assertFalse(healthComponent.isAlive(), "Entity should be dead after taking 100 damage."); + } + + @Test + public void testSetAlive() { + HealthComponent healthComponent = new HealthComponent(100f); + assertTrue(healthComponent.isAlive(), "Entity should be alive initially."); + healthComponent.setAlive(false); + + assertFalse(healthComponent.isAlive(), "Entity should be dead after setting alive to false."); + } + + @Test + public void testSetCurrentHealth() { + HealthComponent healthComponent = new HealthComponent(100f); + healthComponent.setCurrentHealth(80f); + + assertEquals(80f, healthComponent.getCurrentHealth(), "Current health should be updated to 80."); + } @Test public void testHealthCannotGoAboveMax() { healthComponent.heal(150); diff --git a/entity-component-system/src/test/java/com/iluwatar/TransformComponentTest.java b/entity-component-system/src/test/java/com/iluwatar/TransformComponentTest.java index b5d7b0830393..2afbeaceea22 100644 --- a/entity-component-system/src/test/java/com/iluwatar/TransformComponentTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/TransformComponentTest.java @@ -39,6 +39,20 @@ public void setUp() { new float[]{0.0f, 0.0f, 0.0f}, new float[]{1.0f, 1.0f, 1.0f}); } + + @Test + public void testTransformComponentConstructor() { + TransformComponent transform = new TransformComponent(); + + float[] expectedPosition = new float[]{0.0f, 0.0f, 0.0f}; + float[] expectedRotation = new float[]{0.0f, 0.0f, 0.0f}; + float[] expectedScale = new float[]{1.0f, 1.0f, 1.0f}; + + assertArrayEquals(expectedPosition, transform.getPosition(), "Position should be initialized to [0.0f, 0.0f, 0.0f]"); + assertArrayEquals(expectedRotation, transform.getRotation(), "Rotation should be initialized to [0.0f, 0.0f, 0.0f]"); + assertArrayEquals(expectedScale, transform.getScale(), "Scale should be initialized to [1.0f, 1.0f, 1.0f]"); + } + @Test public void testGetPosition() { float[] position = transform.getPosition(); @@ -74,6 +88,13 @@ public void testGetScale() { assertArrayEquals(new float[]{1.0f, 1.0f, 1.0f}, scale, "The scale should be initialized correctly."); } + @Test + public void testUpdateFunction() { + TransformComponent transform = new TransformComponent(); + + assertDoesNotThrow(() -> transform.update(1.0f), "update function should not throw an exception"); + } + @Test public void testSetScale() { transform.setScale(new float[]{2.0f, 2.0f, 2.0f}); diff --git a/entity-component-system/src/test/java/com/iluwatar/VelocityComponentTest.java b/entity-component-system/src/test/java/com/iluwatar/VelocityComponentTest.java index d0a762ac4f42..0eaaf83615b6 100644 --- a/entity-component-system/src/test/java/com/iluwatar/VelocityComponentTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/VelocityComponentTest.java @@ -61,4 +61,25 @@ public void testUpdateVelocity() { assertTrue(velocity.getVelocityX() > initialVelocityX, "VelocityX should increase after updating."); } + + @Test + public void testSetVelocityX() { + + velocity = new VelocityComponent(1.0f, 0.0f, 0.0f); + velocity.setVelocityX(5.0f); + assertEquals(5.0f, velocity.getVelocityX(), "The velocityX should be set to 5.0f"); + + velocity.setVelocityX(10.0f); + assertEquals(10.0f, velocity.getVelocityX(), "The velocityX should now be set to 10.0f"); + } + @Test + public void testSetVelocityZ() { + + velocity = new VelocityComponent(1.0f, 0.0f, 0.0f); + velocity.setVelocityZ(5.0f); + assertEquals(5.0f, velocity.getVelocityZ(), "The velocityZ should be set to 5.0f"); + + velocity.setVelocityZ(10.0f); + assertEquals(10.0f, velocity.getVelocityZ(), "The velocityZ should now be set to 10.0f"); + } } From cd41e1a7f2694b124de66dfba74d5803e33af380 Mon Sep 17 00:00:00 2001 From: R00V <149782421+rofidakhaled@users.noreply.github.com> Date: Fri, 13 Dec 2024 12:19:28 +0200 Subject: [PATCH 3/9] Update EntityTest.java --- .../src/test/java/com/iluwatar/EntityTest.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/entity-component-system/src/test/java/com/iluwatar/EntityTest.java b/entity-component-system/src/test/java/com/iluwatar/EntityTest.java index 1e1a232558fa..cd6017cb0586 100644 --- a/entity-component-system/src/test/java/com/iluwatar/EntityTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/EntityTest.java @@ -169,14 +169,17 @@ public void testGetName() { @Test public void testSetIsEnabled() { Entity entity = new Entity("MyEntity"); - + Entity entity2 = new Entity("child"); + entity.addChild(entity2); entity.setIsEnabled(false); assertFalse(entity.isEnabled(), "The entity should be disabled after calling setIsEnabled(false)."); - + assertFalse(entity2.isEnabled(), "The entity child should be disabled after calling setIsEnabled(false)."); + entity.setIsEnabled(true); assertTrue(entity.isEnabled(), "The entity should be enabled after calling setIsEnabled(true)."); + assertTrue(entity2.isEnabled(), "The entity child should be enabled after calling setIsEnabled(true)."); } @Test From 38ef4a6124f1604a4b74e98c3c88ed30db5374c1 Mon Sep 17 00:00:00 2001 From: R00V Date: Sat, 14 Dec 2024 15:43:46 +0200 Subject: [PATCH 4/9] even more test cases --- .../src/main/java/com/iluwatar/App.java | 34 +------ .../src/main/java/com/iluwatar/Entity.java | 6 ++ .../java/com/iluwatar/VelocityComponent.java | 20 ++++ .../src/test/java/com/iluwatar/AppTest.java | 93 +++++++++++++++++++ .../test/java/com/iluwatar/EntityTest.java | 48 ++++++++++ .../com/iluwatar/VelocityComponentTest.java | 13 +++ 6 files changed, 182 insertions(+), 32 deletions(-) diff --git a/entity-component-system/src/main/java/com/iluwatar/App.java b/entity-component-system/src/main/java/com/iluwatar/App.java index 79906898270e..8815bde07241 100644 --- a/entity-component-system/src/main/java/com/iluwatar/App.java +++ b/entity-component-system/src/main/java/com/iluwatar/App.java @@ -24,18 +24,12 @@ */ package com.iluwatar; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** * The main entry point for the application. * This class simulates a game loop where entities are created, updated, and their states are modified. */ public class App { - // Create a logger instance - public static final Logger logger = LoggerFactory.getLogger(App.class); - /** * The main method that runs the application. * It creates entities, adds components, updates them over several frames, @@ -44,68 +38,44 @@ public class App { * @param args Command-line arguments (not used in this application) */ public static void main(String[] args) { + System.out.print("Hello, World!"); Entity entity1 = new Entity("Entity1"); Entity entity2 = new Entity("Entity2"); - // Set up some transform components (position, rotation, scale) TransformComponent transform1 = new TransformComponent(new float[]{0.0f, 0.0f, 0.0f}, new float[]{0.0f, 0.0f, 0.0f}, new float[]{1.0f, 1.0f, 1.0f}); TransformComponent transform2 = new TransformComponent(new float[]{5.0f, 0.0f, 0.0f}, new float[]{0.0f, 45.0f, 0.0f}, new float[]{1.0f, 1.0f, 1.0f}); - // Set the transform components for each entity entity1.addComponent(transform1); entity2.addComponent(transform2); - // Create a health component for entity1 with initial health of 100 HealthComponent health1 = new HealthComponent(100); // Ensure HealthComponent is implemented entity1.addComponent(health1); - // Create a velocity component for entity1 VelocityComponent velocity1 = new VelocityComponent(1.0f, 0.0f, 0.0f); entity1.addComponent(velocity1); - // Set up a system and add entities to the system GameSystem gameSystem = new GameSystem(); gameSystem.addEntity(entity1); gameSystem.addEntity(entity2); - // Simulate game update loop (e.g., 60 FPS) - float deltaTime = 1.0f / 60.0f; // 60 FPS + float deltaTime = 1.0f / 60.0f; - // Simulate for a few frames for (int i = 0; i < 10; i++) { - logger.info("Frame: {}", i + 1); - // Update all entities in the system gameSystem.update(deltaTime); - // Apply some damage to entity1's health component at frame 6 if (i == 5) { health1.applyDamage(30); - logger.info("Entity1's health after damage: {}", health1.getCurrentHealth()); } - // Apply some force to entity1's velocity at frame 3 if (i == 3) { velocity1.applyForce(0.5f, 0.0f, 0.0f); - logger.info("Entity1's velocity after force: ({}, {}, {})", velocity1.getVelocityX(), - velocity1.getVelocityY(), velocity1.getVelocityZ()); } - // Render the system (optional rendering logic can be added here) gameSystem.renderSystem(); } - - // After the simulation, check final entity states - logger.info("\nFinal Entity States:"); - logger.info("Entity1 position: {}, {}, {}", - entity1.getTransformComponent().getPosition()[0], - entity1.getTransformComponent().getPosition()[1], - entity1.getTransformComponent().getPosition()[2]); - logger.info("Entity1 velocity: {}, {}, {}", - velocity1.getVelocityX(), velocity1.getVelocityY(), velocity1.getVelocityZ()); - logger.info("Entity1 health: {}", health1.getCurrentHealth()); } } diff --git a/entity-component-system/src/main/java/com/iluwatar/Entity.java b/entity-component-system/src/main/java/com/iluwatar/Entity.java index f22d69773115..1abc22991cfd 100644 --- a/entity-component-system/src/main/java/com/iluwatar/Entity.java +++ b/entity-component-system/src/main/java/com/iluwatar/Entity.java @@ -254,7 +254,13 @@ public boolean isEnabled() { * @param isEnabled true to enable the entity, false to disable it */ public void setIsEnabled(boolean isEnabled) { + this.isEnabled = isEnabled; + + for (Entity child : children) { + child.setIsEnabled(isEnabled); + + } } /** diff --git a/entity-component-system/src/main/java/com/iluwatar/VelocityComponent.java b/entity-component-system/src/main/java/com/iluwatar/VelocityComponent.java index 0008a51ae8f2..d5c85207e96e 100644 --- a/entity-component-system/src/main/java/com/iluwatar/VelocityComponent.java +++ b/entity-component-system/src/main/java/com/iluwatar/VelocityComponent.java @@ -38,6 +38,10 @@ public class VelocityComponent extends Component { private float velocityY; // The velocity in the Y direction private float velocityZ; // The velocity in the Z direction + private final float initialVelocityX; + private final float initialVelocityY; + private final float initialVelocityZ; + /** * Constructs a VelocityComponent with the given velocity values in the X, Y, and Z directions. * @@ -49,8 +53,24 @@ public VelocityComponent(float velocityX, float velocityY, float velocityZ) { this.velocityX = velocityX; this.velocityY = velocityY; this.velocityZ = velocityZ; + + this.initialVelocityX = velocityX; + this.initialVelocityY = velocityY; + this.initialVelocityZ = velocityZ; + } + + /** + * update the velocity of the entity. + * This method resets the velocity + * + */ + public void resetVelocity() { + this.velocityX = this.initialVelocityX; + this.velocityY = this.initialVelocityY; + this.velocityZ = this.initialVelocityZ; } + /** * Updates the velocity of the entity based on delta time. * This method multiplies the current velocity by the delta time to simulate movement. diff --git a/entity-component-system/src/test/java/com/iluwatar/AppTest.java b/entity-component-system/src/test/java/com/iluwatar/AppTest.java index 647538d5113e..0a2e6532546b 100644 --- a/entity-component-system/src/test/java/com/iluwatar/AppTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/AppTest.java @@ -27,6 +27,8 @@ import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; public class AppTest { @@ -53,7 +55,16 @@ public void setUp() { velocity1 = new VelocityComponent(1.0f, 0.0f, 0.0f); entity1.addComponent(velocity1); } + @Test + public void testMain_shouldPrintHelloWorld() { + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outputStream)); + App.main(new String[]{}); + + assertEquals("Hello, World!", outputStream.toString(), "The output should be 'Hello, World!'"); + } @Test public void testHealthComponentApplyDamage() { @@ -121,4 +132,86 @@ public void testFinalEntityStateAfterSimulation() { assertNotNull(entity1.getTransformComponent(), "Entity1 should have a transform component"); } + + @Test + public void testAddTransformComponent() { + entity1.addComponent(transform1); + assertTrue(entity1.getComponents().contains(transform1), "Entity1 should contain the added TransformComponent."); + } + + @Test + public void testGameLoopUpdatesEntityState() { + GameSystem gameSystem = new GameSystem(); + gameSystem.addEntity(entity1); + + for (int i = 0; i < 5; i++) { + gameSystem.update(1.0f / 60.0f); + } + + // Check the updated health and velocity + assertEquals(100, health1.getCurrentHealth(), "Health should not be affected yet."); + assertEquals(1.0f, velocity1.getVelocityX(), "Velocity X should remain the same as no force is applied."); + } + + @Test + public void testHealthReductionOverMultipleDamages() { + health1.applyDamage(20); + health1.applyDamage(30); + + assertEquals(50, health1.getCurrentHealth(), "Health should be reduced by 50 after two damage applications."); + } + + @Test + public void testEntityRemovalFromGameSystem() { + GameSystem gameSystem = new GameSystem(); + gameSystem.addEntity(entity1); + + gameSystem.removeEntity(entity1); + + // Assert that entity1 is no longer in the system + assertFalse(gameSystem.getEntities().contains(entity1), "Entity1 should no longer be in the GameSystem after removal."); + } + + @Test + public void testEntityWithoutComponents() { + Entity entity = new Entity("EmptyEntity"); + entity.removeComponent(entity.getTransformComponent()); + assertTrue(entity.getComponents().isEmpty(), "Entity should have no components."); + assertEquals("EmptyEntity", entity.getName(), "Entity should have the correct name."); + } + + @Test + public void testSetParentAndChildren() { + Entity parentEntity = new Entity("ParentEntity"); + Entity childEntity = new Entity("ChildEntity"); + + parentEntity.addChild(childEntity); + + assertTrue(parentEntity.getChildren().contains(childEntity), "Parent entity should contain the child entity."); + assertEquals(parentEntity, childEntity.getParent(), "Child entity should have the parent entity set."); + } + + @Test + public void testVelocityComponentReset() { + velocity1.applyForce(1.0f, 0.0f, 0.0f); + float newVelocityX = velocity1.getVelocityX(); + + velocity1.resetVelocity(); + + assertEquals(1.0f, velocity1.getVelocityX(), "Velocity should be reset to its initial value."); + assertEquals(0.0f, velocity1.getVelocityY(), "Velocity Y should remain reset."); + assertEquals(0.0f, velocity1.getVelocityZ(), "Velocity Z should remain reset."); + } + + @Test + public void testHealthAndForceAppliedTogether() { + health1.applyDamage(20); + velocity1.applyForce(0.5f, 0.0f, 0.0f); + + // Update entity state after applying damage and force + entity1.update(1.0f / 60.0f); + + assertEquals(80, health1.getCurrentHealth(), "Health should be reduced by 20 after damage."); + assertEquals(1.5f, velocity1.getVelocityX(), "Velocity X should increase by 0.5 after applying force."); + } } \ No newline at end of file diff --git a/entity-component-system/src/test/java/com/iluwatar/EntityTest.java b/entity-component-system/src/test/java/com/iluwatar/EntityTest.java index cd6017cb0586..f8db0a666c25 100644 --- a/entity-component-system/src/test/java/com/iluwatar/EntityTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/EntityTest.java @@ -191,4 +191,52 @@ public void testGetAndSetGameSystem() { assertEquals(gameSystem, entity.getGameSystem(), "The game system should match the one set."); } + + @Test + public void testUpdate_whenEntityDisabled_shouldReturnImmediately() { + + + Entity parent = new Entity("parent"); + Entity child = new Entity("child"); + + child.setParent(parent); + + parent.setEnabled(false); + parent.addComponent(transform1); + + parent.update(1.0f); + + assertFalse(transform1.getEnabled(), "Component should not be enabled."); + assertDoesNotThrow(() -> transform1.update(1.0f), "Component update should not throw an exception when entity is disabled."); + + assertDoesNotThrow(() -> child.update(1.0f), "Child entity should not throw an exception if the parent is disabled."); + } + + @Test + public void testUpdate_shouldUpdateEnabledComponents() { + entity1.setEnabled(true); + entity2.setEnabled(false); + entity1.addComponent(transform1); + entity2.addComponent(transform2); + entity1.update(1.0f); + entity2.update(1.0f); + + assertTrue(transform1.getEnabled(), "Transform1 should be enabled after update when the parent entity is enabled."); + assertDoesNotThrow(() -> transform1.update(1.0f), "Transform1 update should not throw an exception when the parent entity is enabled."); + + assertFalse(transform2.getEnabled(), "Transform2 should remain disabled after update when it is added but disabled."); + assertDoesNotThrow(() -> transform2.update(1.0f), "Transform2 update should not throw an exception even though it's disabled."); + } + + @Test + public void testUpdate_shouldUpdateChildEntities() { + Entity child = new Entity("child"); + entity1.setEnabled(true); + entity1.addChild(child); + child.setParent(entity1); + entity1.update(1.0f); + assertDoesNotThrow(() -> child.update(1.0f)); + } } + + diff --git a/entity-component-system/src/test/java/com/iluwatar/VelocityComponentTest.java b/entity-component-system/src/test/java/com/iluwatar/VelocityComponentTest.java index 0eaaf83615b6..5d74261bb953 100644 --- a/entity-component-system/src/test/java/com/iluwatar/VelocityComponentTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/VelocityComponentTest.java @@ -52,6 +52,19 @@ public void testApplyFriction() { assertEquals(0.9f, velocity.getVelocityX(), "VelocityX should be reduced by the friction coefficient."); } + @Test + public void testReset_shouldResetVelocityToZero() { + + velocity.setVelocityX( 5.0f); + velocity.setVelocityY( 10.0f); + velocity.setVelocityZ( 15.0f); + velocity.resetVelocity(); + + assertEquals(1.0f, velocity.getVelocityX(), "Velocity X should be reset to 1.0f"); + assertEquals(0.0f, velocity.getVelocityY(), "Velocity Y should be reset to 0"); + assertEquals(0.0f, velocity.getVelocityZ(), "Velocity Z should be reset to 0"); + } + @Test public void testUpdateVelocity() { float deltaTime = 1.0f / 60.0f; From a9edc072d7751f738b6f816b4d92254265e74a41 Mon Sep 17 00:00:00 2001 From: R00V Date: Fri, 27 Dec 2024 13:48:54 +0200 Subject: [PATCH 5/9] fixing maintainability, and intentionality issues --- .../src/main/java/com/iluwatar/App.java | 2 +- .../src/main/java/com/iluwatar/Component.java | 2 +- .../src/main/java/com/iluwatar/Entity.java | 8 +-- .../main/java/com/iluwatar/GameSystem.java | 4 +- .../java/com/iluwatar/HealthComponent.java | 2 - .../java/com/iluwatar/VelocityComponent.java | 1 - .../src/test/java/com/iluwatar/AppTest.java | 42 ++++++------- .../test/java/com/iluwatar/ComponentTest.java | 20 +++---- .../test/java/com/iluwatar/EntityTest.java | 59 +++++++------------ .../java/com/iluwatar/GameSystemTest.java | 16 ++--- .../com/iluwatar/HealthComponentTest.java | 56 +++++++++--------- .../com/iluwatar/TransformComponentTest.java | 24 ++++---- .../com/iluwatar/VelocityComponentTest.java | 20 +++---- 13 files changed, 113 insertions(+), 143 deletions(-) diff --git a/entity-component-system/src/main/java/com/iluwatar/App.java b/entity-component-system/src/main/java/com/iluwatar/App.java index 8815bde07241..79d0c7645e49 100644 --- a/entity-component-system/src/main/java/com/iluwatar/App.java +++ b/entity-component-system/src/main/java/com/iluwatar/App.java @@ -38,7 +38,7 @@ public class App { * @param args Command-line arguments (not used in this application) */ public static void main(String[] args) { - System.out.print("Hello, World!"); + Entity entity1 = new Entity("Entity1"); Entity entity2 = new Entity("Entity2"); diff --git a/entity-component-system/src/main/java/com/iluwatar/Component.java b/entity-component-system/src/main/java/com/iluwatar/Component.java index dc1bce36866a..ca10766197be 100644 --- a/entity-component-system/src/main/java/com/iluwatar/Component.java +++ b/entity-component-system/src/main/java/com/iluwatar/Component.java @@ -39,7 +39,7 @@ public abstract class Component { * Default constructor for the component. * Initializes a new component with default values. */ - public Component() { + protected Component() { // Constructor left empty intentionally, no specific initialization required } diff --git a/entity-component-system/src/main/java/com/iluwatar/Entity.java b/entity-component-system/src/main/java/com/iluwatar/Entity.java index 1abc22991cfd..4ae0c370855d 100644 --- a/entity-component-system/src/main/java/com/iluwatar/Entity.java +++ b/entity-component-system/src/main/java/com/iluwatar/Entity.java @@ -158,10 +158,6 @@ public void setEnabled(boolean enabled) { } } - public boolean getEnabled() { - return isEnabled; - } - /** * Updates the entity and its components. * @@ -214,9 +210,9 @@ public List getComponents() { * Renders the entity and its components. */ public void renderEntity() { - for (Component component : components) { + //for (Component component : components) { // Render each component - } + //} } // Getters and Setters for fields diff --git a/entity-component-system/src/main/java/com/iluwatar/GameSystem.java b/entity-component-system/src/main/java/com/iluwatar/GameSystem.java index 9577a9d976ab..b0b150103c83 100644 --- a/entity-component-system/src/main/java/com/iluwatar/GameSystem.java +++ b/entity-component-system/src/main/java/com/iluwatar/GameSystem.java @@ -112,9 +112,9 @@ public void update(float deltaTime) { * Renders the system (rendering logic can be implemented as needed). */ public void renderSystem() { - for (Entity entity : entities) { + //for (Entity entity : entities) { // Implement rendering logic - } + //} } /** diff --git a/entity-component-system/src/main/java/com/iluwatar/HealthComponent.java b/entity-component-system/src/main/java/com/iluwatar/HealthComponent.java index 5444d5d4c8ad..95b9cff8b0fc 100644 --- a/entity-component-system/src/main/java/com/iluwatar/HealthComponent.java +++ b/entity-component-system/src/main/java/com/iluwatar/HealthComponent.java @@ -33,8 +33,6 @@ */ public class HealthComponent extends Component { - private static final Logger logger = Logger.getLogger(HealthComponent.class.getName()); - private float currentHealth; private float maxHealth; private boolean isAlive; diff --git a/entity-component-system/src/main/java/com/iluwatar/VelocityComponent.java b/entity-component-system/src/main/java/com/iluwatar/VelocityComponent.java index d5c85207e96e..89dd38bb209d 100644 --- a/entity-component-system/src/main/java/com/iluwatar/VelocityComponent.java +++ b/entity-component-system/src/main/java/com/iluwatar/VelocityComponent.java @@ -32,7 +32,6 @@ */ public class VelocityComponent extends Component { - private static final Logger logger = Logger.getLogger(VelocityComponent.class.getName()); private float velocityX; // The velocity in the X direction private float velocityY; // The velocity in the Y direction diff --git a/entity-component-system/src/test/java/com/iluwatar/AppTest.java b/entity-component-system/src/test/java/com/iluwatar/AppTest.java index 0a2e6532546b..dd9673130ac4 100644 --- a/entity-component-system/src/test/java/com/iluwatar/AppTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/AppTest.java @@ -30,7 +30,7 @@ import java.io.ByteArrayOutputStream; import java.io.PrintStream; -public class AppTest { +class AppTest { private Entity entity1; private Entity entity2; @@ -42,7 +42,7 @@ public class AppTest { new float[]{0.0f, 45.0f, 0.0f}, new float[]{1.0f, 1.0f, 1.0f}); @BeforeEach - public void setUp() { +void setUp() { entity1 = new Entity("Entity1"); entity2 = new Entity("Entity2"); @@ -56,17 +56,12 @@ public void setUp() { entity1.addComponent(velocity1); } @Test - public void testMain_shouldPrintHelloWorld() { - - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - System.setOut(new PrintStream(outputStream)); - - App.main(new String[]{}); - - assertEquals("Hello, World!", outputStream.toString(), "The output should be 'Hello, World!'"); +void testMain_DoesNotThrowException() { + assertDoesNotThrow(() -> App.main(new String[]{}), "Child entity should not throw an exception if the parent is disabled."); } + @Test - public void testHealthComponentApplyDamage() { +void testHealthComponentApplyDamage() { health1.applyDamage(30); @@ -74,7 +69,7 @@ public void testHealthComponentApplyDamage() { } @Test - public void testVelocityComponentApplyForce() { +void testVelocityComponentApplyForce() { velocity1.applyForce(0.5f, 0.0f, 0.0f); @@ -84,7 +79,7 @@ public void testVelocityComponentApplyForce() { } @Test - public void testEntityUpdate() { +void testEntityUpdate() { float deltaTime = 1.0f / 60.0f; velocity1.setVelocityY(12.0f); @@ -95,7 +90,7 @@ public void testEntityUpdate() { } @Test - public void testEntityHealthAfterDamageAndForce() { +void testEntityHealthAfterDamageAndForce() { health1.applyDamage(40); @@ -108,7 +103,7 @@ public void testEntityHealthAfterDamageAndForce() { } @Test - public void testFinalEntityStateAfterSimulation() { +void testFinalEntityStateAfterSimulation() { GameSystem gameSystem = new GameSystem(); gameSystem.addEntity(entity1); @@ -134,13 +129,13 @@ public void testFinalEntityStateAfterSimulation() { } @Test - public void testAddTransformComponent() { +void testAddTransformComponent() { entity1.addComponent(transform1); assertTrue(entity1.getComponents().contains(transform1), "Entity1 should contain the added TransformComponent."); } @Test - public void testGameLoopUpdatesEntityState() { +void testGameLoopUpdatesEntityState() { GameSystem gameSystem = new GameSystem(); gameSystem.addEntity(entity1); @@ -154,7 +149,7 @@ public void testGameLoopUpdatesEntityState() { } @Test - public void testHealthReductionOverMultipleDamages() { +void testHealthReductionOverMultipleDamages() { health1.applyDamage(20); health1.applyDamage(30); @@ -162,7 +157,7 @@ public void testHealthReductionOverMultipleDamages() { } @Test - public void testEntityRemovalFromGameSystem() { +void testEntityRemovalFromGameSystem() { GameSystem gameSystem = new GameSystem(); gameSystem.addEntity(entity1); @@ -173,7 +168,7 @@ public void testEntityRemovalFromGameSystem() { } @Test - public void testEntityWithoutComponents() { +void testEntityWithoutComponents() { Entity entity = new Entity("EmptyEntity"); entity.removeComponent(entity.getTransformComponent()); assertTrue(entity.getComponents().isEmpty(), "Entity should have no components."); @@ -181,7 +176,7 @@ public void testEntityWithoutComponents() { } @Test - public void testSetParentAndChildren() { +void testSetParentAndChildren() { Entity parentEntity = new Entity("ParentEntity"); Entity childEntity = new Entity("ChildEntity"); @@ -192,9 +187,8 @@ public void testSetParentAndChildren() { } @Test - public void testVelocityComponentReset() { +void testVelocityComponentReset() { velocity1.applyForce(1.0f, 0.0f, 0.0f); - float newVelocityX = velocity1.getVelocityX(); velocity1.resetVelocity(); @@ -204,7 +198,7 @@ public void testVelocityComponentReset() { } @Test - public void testHealthAndForceAppliedTogether() { +void testHealthAndForceAppliedTogether() { health1.applyDamage(20); velocity1.applyForce(0.5f, 0.0f, 0.0f); diff --git a/entity-component-system/src/test/java/com/iluwatar/ComponentTest.java b/entity-component-system/src/test/java/com/iluwatar/ComponentTest.java index 4abb81cd3d68..685dedc0f7eb 100644 --- a/entity-component-system/src/test/java/com/iluwatar/ComponentTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/ComponentTest.java @@ -28,25 +28,25 @@ import static org.junit.jupiter.api.Assertions.*; -public class ComponentTest { + class ComponentTest { @Test - public void testGetName() { - Component component = new HealthComponent(100); + void testGetName() { + Component component = new HealthComponent(10); component.setName("Health"); - assertEquals("Health", component.getName(), "getName should return 'TestComponent'"); + assertEquals("Health", component.getName(), "getName should return 'Health'"); } @Test - public void testSetName() { + void testSetName() { Component component = new HealthComponent(100); - component.setName("Health"); - - assertEquals("Health", component.getName(), "getName should return 'TestComponent'"); + component.setName("Velocity"); + component.setName("Transform"); + assertEquals("Transform", component.getName(), "getName should return 'Transform'"); } @Test - public void testComponentEnabled() { + void testComponentEnabled() { Component component = new HealthComponent(100); component.setEnabled(true); @@ -57,7 +57,7 @@ public void testComponentEnabled() { } @Test - public void testComponentParent() { +void testComponentParent() { Component component = new HealthComponent(100); Entity parentEntity = new Entity("ParentEntity"); diff --git a/entity-component-system/src/test/java/com/iluwatar/EntityTest.java b/entity-component-system/src/test/java/com/iluwatar/EntityTest.java index f8db0a666c25..1ddf23ade371 100644 --- a/entity-component-system/src/test/java/com/iluwatar/EntityTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/EntityTest.java @@ -33,11 +33,11 @@ public class EntityTest { private Entity entity1; private Entity entity2; - private TransformComponent transform1; - private TransformComponent transform2; + TransformComponent transform1; + TransformComponent transform2; @BeforeEach - public void setUp() { + void setUp() { entity1 = new Entity("Entity1"); entity2 = new Entity("Entity2"); @@ -49,7 +49,7 @@ public void setUp() { } @Test - public void testAddComponent() { + void testAddComponent() { Component component = new HealthComponent(100); entity1.addComponent(component); @@ -57,7 +57,7 @@ public void testAddComponent() { } @Test - public void testRemoveComponent() { + void testRemoveComponent() { Component component = new HealthComponent(100); entity2.removeComponent(component); @@ -65,32 +65,15 @@ public void testRemoveComponent() { assertEquals(1, entity2.getComponents().size(), "Entity1 should have no components."); } - /* @Test - public void testSetParent() { - entity1 = new Entity("Entity1"); - entity2 = new Entity("Entity2"); - entity1.setParent(entity2); - assertEquals(entity2.getEntityId(), entity1.getParent().getEntityId(), "Entity1 should have Entity2 as its parent."); - } -*/ - @Test - public void testAddChild() { + void testAddChild() { entity1.addChild(entity2); assertTrue(entity1.getChildren().contains(entity2), "Entity1 should have Entity2 as its child."); } -/* - @Test - public void testSetEnabled() { - entity1.setEnabled(false); - assertFalse(entity1.getEnabled(), "Entity1 should be disabled."); - entity1.setEnabled(true); - assertTrue(entity1.getEnabled(), "Entity1 should be enabled."); - } */ @Test - public void testGetComponent() { + void testGetComponent() { Component component = new HealthComponent(100); component.setName("HealthComponent"); @@ -105,7 +88,7 @@ public void testGetComponent() { } @Test - public void testSetEnabled() { + void testSetEnabled() { Component component = new HealthComponent(100); Entity entity = new Entity("MyEntity"); @@ -123,7 +106,7 @@ public void testSetEnabled() { } @Test - public void testSetParent() { + void testSetParent() { Entity parent = new Entity("parent"); Entity child = new Entity("child"); @@ -141,7 +124,7 @@ public void testSetParent() { } @Test - public void testUpdate() { + void testUpdate() { float deltaTime = 1.0f / 60.0f; entity1.update(deltaTime); @@ -149,7 +132,7 @@ public void testUpdate() { } @Test - public void testRenderEntity() { + void testRenderEntity() { Component component = new HealthComponent(100); Entity entity = new Entity("MyEntity"); @@ -160,30 +143,30 @@ public void testRenderEntity() { } @Test - public void testGetName() { + void testGetName() { Entity entity = new Entity("MyEntity"); assertEquals("MyEntity", entity.getName(), "The entity name should match the given name."); } @Test - public void testSetIsEnabled() { + void testSetIsEnabled() { Entity entity = new Entity("MyEntity"); - Entity entity2 = new Entity("child"); - entity.addChild(entity2); + Entity entityChild = new Entity("child"); + entity.addChild(entityChild); entity.setIsEnabled(false); assertFalse(entity.isEnabled(), "The entity should be disabled after calling setIsEnabled(false)."); - assertFalse(entity2.isEnabled(), "The entity child should be disabled after calling setIsEnabled(false)."); + assertFalse(entityChild.isEnabled(), "The entity child should be disabled after calling setIsEnabled(false)."); entity.setIsEnabled(true); assertTrue(entity.isEnabled(), "The entity should be enabled after calling setIsEnabled(true)."); - assertTrue(entity2.isEnabled(), "The entity child should be enabled after calling setIsEnabled(true)."); + assertTrue(entityChild.isEnabled(), "The entity child should be enabled after calling setIsEnabled(true)."); } @Test - public void testGetAndSetGameSystem() { + void testGetAndSetGameSystem() { GameSystem gameSystem = new GameSystem(); Entity entity = new Entity("MyEntity"); @@ -193,7 +176,7 @@ public void testGetAndSetGameSystem() { } @Test - public void testUpdate_whenEntityDisabled_shouldReturnImmediately() { + void testUpdate_whenEntityDisabled_shouldReturnImmediately() { Entity parent = new Entity("parent"); @@ -213,7 +196,7 @@ public void testUpdate_whenEntityDisabled_shouldReturnImmediately() { } @Test - public void testUpdate_shouldUpdateEnabledComponents() { + void testUpdate_shouldUpdateEnabledComponents() { entity1.setEnabled(true); entity2.setEnabled(false); entity1.addComponent(transform1); @@ -229,7 +212,7 @@ public void testUpdate_shouldUpdateEnabledComponents() { } @Test - public void testUpdate_shouldUpdateChildEntities() { + void testUpdate_shouldUpdateChildEntities() { Entity child = new Entity("child"); entity1.setEnabled(true); entity1.addChild(child); diff --git a/entity-component-system/src/test/java/com/iluwatar/GameSystemTest.java b/entity-component-system/src/test/java/com/iluwatar/GameSystemTest.java index e0c08a637017..6e53b24cd07f 100644 --- a/entity-component-system/src/test/java/com/iluwatar/GameSystemTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/GameSystemTest.java @@ -29,7 +29,7 @@ import java.util.List; -public class GameSystemTest { + class GameSystemTest { private GameSystem gameSystem; private Entity entity1; @@ -37,7 +37,7 @@ public class GameSystemTest { private Entity childEntity; @BeforeEach - public void setUp() { + void setUp() { gameSystem = new GameSystem(); entity1 = new Entity("Entity1"); @@ -51,18 +51,18 @@ public void setUp() { } @Test - public void testAddEntity() { + void testAddEntity() { assertEquals(3, gameSystem.getEntities().size(), "There should be three entities in the system."); } @Test - public void testRemoveEntity() { + void testRemoveEntity() { gameSystem.removeEntity(entity2); assertEquals(2, gameSystem.getEntities().size(), "Entity2 should be removed from the system."); } @Test - public void testGetSystemMatrix() { + void testGetSystemMatrix() { // Set a mock transform for entity1 and childEntity float[][] matrix1 = gameSystem.getSystemMatrix(entity1); float[][] matrix2 = gameSystem.getSystemMatrix(childEntity); @@ -73,7 +73,7 @@ public void testGetSystemMatrix() { } @Test - public void testGetSystemPosition() { + void testGetSystemPosition() { float[] position1 = gameSystem.getSystemPosition(entity1); float[] position2 = gameSystem.getSystemPosition(entity2); @@ -84,7 +84,7 @@ public void testGetSystemPosition() { } @Test - public void testSortEntitiesByDistance() { +void testSortEntitiesByDistance() { float[] referencePoint = {0.0f, 0.0f, 0.0f}; @@ -100,7 +100,7 @@ public void testSortEntitiesByDistance() { } @Test - public void testRenderSystem() { +void testRenderSystem() { try { gameSystem.renderSystem(); diff --git a/entity-component-system/src/test/java/com/iluwatar/HealthComponentTest.java b/entity-component-system/src/test/java/com/iluwatar/HealthComponentTest.java index 7a3ee47ebf23..a9de5be67189 100644 --- a/entity-component-system/src/test/java/com/iluwatar/HealthComponentTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/HealthComponentTest.java @@ -28,22 +28,22 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; -public class HealthComponentTest { + class HealthComponentTest { private HealthComponent healthComponent; @BeforeEach - public void setUp() { + void setUp() { healthComponent = new HealthComponent(100); } @Test - public void testInitialHealth() { + void testInitialHealth() { assertEquals(100, healthComponent.getCurrentHealth(), "Initial health should be 100."); } @Test - public void testApplyDamage() { + void testApplyDamage() { healthComponent.applyDamage(30); assertEquals(70, healthComponent.getCurrentHealth(), "Health should decrease by 30 after damage."); @@ -52,7 +52,7 @@ public void testApplyDamage() { } @Test - public void testHeal() { + void testHeal() { healthComponent.applyDamage(50); healthComponent.heal(30); assertEquals(80, healthComponent.getCurrentHealth(), "Health should increase by 30 after healing."); @@ -61,62 +61,62 @@ public void testHeal() { assertEquals(100, healthComponent.getCurrentHealth(), "Health should not exceed maximum (100)."); } @Test - public void testUpdateFunction() { + void testUpdateFunction() { healthComponent = new HealthComponent(100); assertDoesNotThrow(() -> healthComponent.update(1.0f), "update function should not throw an exception"); } @Test - public void testGetMaxHealth() { - HealthComponent healthComponent = new HealthComponent(100f); + void testGetMaxHealth() { + HealthComponent TesthealthComponent = new HealthComponent(100f); - assertEquals(100f, healthComponent.getMaxHealth(), "Max health should be 100."); + assertEquals(100f, TesthealthComponent.getMaxHealth(), "Max health should be 100."); } @Test - public void testSetMaxHealth() { - HealthComponent healthComponent = new HealthComponent(100f); + void testSetMaxHealth() { + HealthComponent TesthealthComponent = new HealthComponent(100f); healthComponent.setMaxHealth(120f); - assertEquals(120f, healthComponent.getMaxHealth(), "Max health should be updated to 120."); + assertEquals(120f, TesthealthComponent.getMaxHealth(), "Max health should be updated to 120."); } @Test - public void testIsAlive() { + void testIsAlive() { - HealthComponent healthComponent = new HealthComponent(100f); - assertTrue(healthComponent.isAlive(), "Entity should be alive initially."); - healthComponent.applyDamage(100f); + HealthComponent TesthealthComponent = new HealthComponent(100f); + assertTrue(TesthealthComponent.isAlive(), "Entity should be alive initially."); + TesthealthComponent.applyDamage(100f); - assertFalse(healthComponent.isAlive(), "Entity should be dead after taking 100 damage."); + assertFalse(TesthealthComponent.isAlive(), "Entity should be dead after taking 100 damage."); } @Test - public void testSetAlive() { + void testSetAlive() { - HealthComponent healthComponent = new HealthComponent(100f); - assertTrue(healthComponent.isAlive(), "Entity should be alive initially."); - healthComponent.setAlive(false); + HealthComponent TesthealthComponent = new HealthComponent(100f); + assertTrue(TesthealthComponent.isAlive(), "Entity should be alive initially."); + TesthealthComponent.setAlive(false); - assertFalse(healthComponent.isAlive(), "Entity should be dead after setting alive to false."); + assertFalse(TesthealthComponent.isAlive(), "Entity should be dead after setting alive to false."); } @Test - public void testSetCurrentHealth() { - HealthComponent healthComponent = new HealthComponent(100f); - healthComponent.setCurrentHealth(80f); + void testSetCurrentHealth() { + HealthComponent TesthealthComponent = new HealthComponent(100f); + TesthealthComponent.setCurrentHealth(80f); - assertEquals(80f, healthComponent.getCurrentHealth(), "Current health should be updated to 80."); + assertEquals(80f, TesthealthComponent.getCurrentHealth(), "Current health should be updated to 80."); } @Test - public void testHealthCannotGoAboveMax() { + void testHealthCannotGoAboveMax() { healthComponent.heal(150); assertEquals(100, healthComponent.getCurrentHealth(), "Health should not exceed the max value (100)."); } @Test - public void testHealthCannotGoBelowZero() { + void testHealthCannotGoBelowZero() { healthComponent.applyDamage(200); assertEquals(0, healthComponent.getCurrentHealth(), "Health should not go below 0."); } diff --git a/entity-component-system/src/test/java/com/iluwatar/TransformComponentTest.java b/entity-component-system/src/test/java/com/iluwatar/TransformComponentTest.java index 2afbeaceea22..d806cf6ed5f2 100644 --- a/entity-component-system/src/test/java/com/iluwatar/TransformComponentTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/TransformComponentTest.java @@ -29,20 +29,20 @@ import static org.junit.jupiter.api.Assertions.*; -public class TransformComponentTest { + class TransformComponentTest { private TransformComponent transform; @BeforeEach - public void setUp() { + void setUp() { transform = new TransformComponent(new float[]{0.0f, 0.0f, 0.0f}, new float[]{0.0f, 0.0f, 0.0f}, new float[]{1.0f, 1.0f, 1.0f}); } @Test - public void testTransformComponentConstructor() { - TransformComponent transform = new TransformComponent(); + void testTransformComponentConstructor() { + TransformComponent Testtransform = new TransformComponent(); float[] expectedPosition = new float[]{0.0f, 0.0f, 0.0f}; float[] expectedRotation = new float[]{0.0f, 0.0f, 0.0f}; @@ -54,49 +54,49 @@ public void testTransformComponentConstructor() { } @Test - public void testGetPosition() { + void testGetPosition() { float[] position = transform.getPosition(); assertArrayEquals(new float[]{0.0f, 0.0f, 0.0f}, position, "The position should be initialized correctly."); } @Test - public void testSetPosition() { + void testSetPosition() { transform.setPosition(new float[]{10.0f, 20.0f, 30.0f}); assertArrayEquals(new float[]{10.0f, 20.0f, 30.0f}, transform.getPosition(), "Position should be updated correctly."); } @Test - public void testGetRotation() { + void testGetRotation() { float[] rotation = transform.getRotation(); assertArrayEquals(new float[]{0.0f, 0.0f, 0.0f}, rotation, "The rotation should be initialized correctly."); } @Test - public void testSetRotation() { + void testSetRotation() { transform.setRotation(new float[]{90.0f, 0.0f, 0.0f}); assertArrayEquals(new float[]{90.0f, 0.0f, 0.0f}, transform.getRotation(), "Rotation should be updated correctly."); } @Test - public void testGetScale() { + void testGetScale() { float[] scale = transform.getScale(); assertArrayEquals(new float[]{1.0f, 1.0f, 1.0f}, scale, "The scale should be initialized correctly."); } @Test - public void testUpdateFunction() { - TransformComponent transform = new TransformComponent(); + void testUpdateFunction() { + TransformComponent Testtransform = new TransformComponent(); assertDoesNotThrow(() -> transform.update(1.0f), "update function should not throw an exception"); } @Test - public void testSetScale() { + void testSetScale() { transform.setScale(new float[]{2.0f, 2.0f, 2.0f}); assertArrayEquals(new float[]{2.0f, 2.0f, 2.0f}, transform.getScale(), "Scale should be updated correctly."); diff --git a/entity-component-system/src/test/java/com/iluwatar/VelocityComponentTest.java b/entity-component-system/src/test/java/com/iluwatar/VelocityComponentTest.java index 5d74261bb953..1eb4ba6e8479 100644 --- a/entity-component-system/src/test/java/com/iluwatar/VelocityComponentTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/VelocityComponentTest.java @@ -29,31 +29,31 @@ import static org.junit.jupiter.api.Assertions.*; -public class VelocityComponentTest { + class VelocityComponentTest { private VelocityComponent velocity; @BeforeEach - public void setUp() { + void setUp() { velocity = new VelocityComponent(1.0f, 0.0f, 0.0f); } @Test - public void testApplyForce() { + void testApplyForce() { velocity.applyForce(2.0f, 0.0f, 0.0f); assertEquals(3.0f, velocity.getVelocityX(), "VelocityX should increase after applying force."); } @Test - public void testApplyFriction() { + void testApplyFriction() { velocity.applyFriction(0.1f); // Applying friction coefficient of 0.1 assertEquals(0.9f, velocity.getVelocityX(), "VelocityX should be reduced by the friction coefficient."); } @Test - public void testReset_shouldResetVelocityToZero() { + void testReset_shouldResetVelocityToZero() { velocity.setVelocityX( 5.0f); velocity.setVelocityY( 10.0f); @@ -66,7 +66,7 @@ public void testReset_shouldResetVelocityToZero() { } @Test - public void testUpdateVelocity() { + void testUpdateVelocity() { float deltaTime = 1.0f / 60.0f; float initialVelocityX = velocity.getVelocityX(); @@ -76,17 +76,17 @@ public void testUpdateVelocity() { } @Test - public void testSetVelocityX() { - + void testSetVelocityX() { + velocity = new VelocityComponent(1.0f, 0.0f, 0.0f); velocity.setVelocityX(5.0f); assertEquals(5.0f, velocity.getVelocityX(), "The velocityX should be set to 5.0f"); - + velocity.setVelocityX(10.0f); assertEquals(10.0f, velocity.getVelocityX(), "The velocityX should now be set to 10.0f"); } @Test - public void testSetVelocityZ() { + void testSetVelocityZ() { velocity = new VelocityComponent(1.0f, 0.0f, 0.0f); velocity.setVelocityZ(5.0f); From 80e42c3fedc04248d991343fcd081daba450e401 Mon Sep 17 00:00:00 2001 From: R00V Date: Fri, 27 Dec 2024 13:50:45 +0200 Subject: [PATCH 6/9] Update HealthComponentTest.java --- .../src/test/java/com/iluwatar/HealthComponentTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/entity-component-system/src/test/java/com/iluwatar/HealthComponentTest.java b/entity-component-system/src/test/java/com/iluwatar/HealthComponentTest.java index a9de5be67189..98f64b15e33b 100644 --- a/entity-component-system/src/test/java/com/iluwatar/HealthComponentTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/HealthComponentTest.java @@ -77,7 +77,7 @@ void testGetMaxHealth() { @Test void testSetMaxHealth() { HealthComponent TesthealthComponent = new HealthComponent(100f); - healthComponent.setMaxHealth(120f); + TesthealthComponent.setMaxHealth(120f); assertEquals(120f, TesthealthComponent.getMaxHealth(), "Max health should be updated to 120."); } From b4c6a303786722d3d208ab202466dcbe27345336 Mon Sep 17 00:00:00 2001 From: R00V Date: Fri, 27 Dec 2024 15:49:12 +0200 Subject: [PATCH 7/9] fixing more maintainability and intentionality issues --- .../src/main/java/com/iluwatar/App.java | 1 - .../src/main/java/com/iluwatar/Entity.java | 22 +++++++----- .../main/java/com/iluwatar/GameSystem.java | 9 ----- .../java/com/iluwatar/HealthComponent.java | 2 +- .../java/com/iluwatar/VelocityComponent.java | 1 - .../src/test/java/com/iluwatar/AppTest.java | 6 ++-- .../test/java/com/iluwatar/EntityTest.java | 35 ++++++++++++------- .../java/com/iluwatar/GameSystemTest.java | 11 +----- .../com/iluwatar/HealthComponentTest.java | 32 ++++++++--------- .../com/iluwatar/TransformComponentTest.java | 12 +++---- 10 files changed, 62 insertions(+), 69 deletions(-) diff --git a/entity-component-system/src/main/java/com/iluwatar/App.java b/entity-component-system/src/main/java/com/iluwatar/App.java index 79d0c7645e49..58ab4cc083cd 100644 --- a/entity-component-system/src/main/java/com/iluwatar/App.java +++ b/entity-component-system/src/main/java/com/iluwatar/App.java @@ -75,7 +75,6 @@ public static void main(String[] args) { velocity1.applyForce(0.5f, 0.0f, 0.0f); } - gameSystem.renderSystem(); } } } diff --git a/entity-component-system/src/main/java/com/iluwatar/Entity.java b/entity-component-system/src/main/java/com/iluwatar/Entity.java index 4ae0c370855d..f978a10819c0 100644 --- a/entity-component-system/src/main/java/com/iluwatar/Entity.java +++ b/entity-component-system/src/main/java/com/iluwatar/Entity.java @@ -131,6 +131,19 @@ public void addChild(Entity child) { } } + /** + * Finds a Child Entity in Children List. + * + * @param entityId the child entity to be removed + */ + public Entity findChildEntity(UUID entityId) { + for (Entity child : children) { + if (Objects.equals(child.getEntityId(), entityId)) { + return child; + } + } + return null; + } /** * Removes a child entity from this entity. @@ -206,15 +219,6 @@ public List getComponents() { return components; } - /** - * Renders the entity and its components. - */ - public void renderEntity() { - //for (Component component : components) { - // Render each component - //} - } - // Getters and Setters for fields /** diff --git a/entity-component-system/src/main/java/com/iluwatar/GameSystem.java b/entity-component-system/src/main/java/com/iluwatar/GameSystem.java index b0b150103c83..c28a1aa395fa 100644 --- a/entity-component-system/src/main/java/com/iluwatar/GameSystem.java +++ b/entity-component-system/src/main/java/com/iluwatar/GameSystem.java @@ -108,15 +108,6 @@ public void update(float deltaTime) { } } - /** - * Renders the system (rendering logic can be implemented as needed). - */ - public void renderSystem() { - //for (Entity entity : entities) { - // Implement rendering logic - //} - } - /** * Sorts the entities by their distance from a given reference point in descending order. * diff --git a/entity-component-system/src/main/java/com/iluwatar/HealthComponent.java b/entity-component-system/src/main/java/com/iluwatar/HealthComponent.java index 95b9cff8b0fc..224b9c842a09 100644 --- a/entity-component-system/src/main/java/com/iluwatar/HealthComponent.java +++ b/entity-component-system/src/main/java/com/iluwatar/HealthComponent.java @@ -24,7 +24,7 @@ */ package com.iluwatar; -import java.util.logging.Logger; + /** * Abstract class representing a health component in the ECS system. diff --git a/entity-component-system/src/main/java/com/iluwatar/VelocityComponent.java b/entity-component-system/src/main/java/com/iluwatar/VelocityComponent.java index 89dd38bb209d..85f04dcae33e 100644 --- a/entity-component-system/src/main/java/com/iluwatar/VelocityComponent.java +++ b/entity-component-system/src/main/java/com/iluwatar/VelocityComponent.java @@ -24,7 +24,6 @@ */ package com.iluwatar; -import java.util.logging.Logger; /** * A component that handles the velocity of an entity in 3D space. diff --git a/entity-component-system/src/test/java/com/iluwatar/AppTest.java b/entity-component-system/src/test/java/com/iluwatar/AppTest.java index dd9673130ac4..b3af79458c76 100644 --- a/entity-component-system/src/test/java/com/iluwatar/AppTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/AppTest.java @@ -27,8 +27,6 @@ import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; class AppTest { @@ -108,9 +106,9 @@ void testFinalEntityStateAfterSimulation() { GameSystem gameSystem = new GameSystem(); gameSystem.addEntity(entity1); gameSystem.addEntity(entity2); - TransformComponent transform1 = new TransformComponent(new float[]{5.0f, 0.0f, 0.0f}, + TransformComponent Testtransform = new TransformComponent(new float[]{5.0f, 0.0f, 0.0f}, new float[]{0.0f, 45.0f, 0.0f}, new float[]{1.0f, 1.0f, 1.0f}); - entity1.setTransformComponent(transform1); + entity1.setTransformComponent(Testtransform); for (int i = 0; i < 10; i++) { gameSystem.update(1.0f / 60.0f); diff --git a/entity-component-system/src/test/java/com/iluwatar/EntityTest.java b/entity-component-system/src/test/java/com/iluwatar/EntityTest.java index 1ddf23ade371..9da954c11925 100644 --- a/entity-component-system/src/test/java/com/iluwatar/EntityTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/EntityTest.java @@ -29,7 +29,7 @@ import static org.junit.jupiter.api.Assertions.*; -public class EntityTest { + class EntityTest { private Entity entity1; private Entity entity2; @@ -45,7 +45,6 @@ void setUp() { new float[]{0.0f, 0.0f, 0.0f}, new float[]{1.0f, 1.0f, 1.0f}); transform2 = new TransformComponent(new float[]{5.0f, 0.0f, 0.0f}, new float[]{0.0f, 45.0f, 0.0f}, new float[]{1.0f, 1.0f, 1.0f}); - } @Test @@ -131,16 +130,6 @@ void testUpdate() { assertNotNull(entity1, "Entity1 should be updated."); } - @Test - void testRenderEntity() { - - Component component = new HealthComponent(100); - Entity entity = new Entity("MyEntity"); - entity.addComponent(component); - entity.renderEntity(); - - assertDoesNotThrow(() -> component.update(1.0f), "render function should not throw an exception"); - } @Test void testGetName() { @@ -220,6 +209,28 @@ void testUpdate_shouldUpdateChildEntities() { entity1.update(1.0f); assertDoesNotThrow(() -> child.update(1.0f)); } + + @Test + void testFindChildEntity() { + Entity parent = new Entity("parent"); + Entity child = new Entity("child"); + child.setParent(parent); + parent.addChild(child); + + assertEquals(parent.findChildEntity(child.getEntityId()),child, "The child object should match the one found."); + + } + + @Test + void testNotFindChildEntity() { + Entity parent = new Entity("parent"); + Entity child = new Entity("child"); + + assertNull(parent.findChildEntity(child.getEntityId()), "The child object should match the one found."); + + } + + } diff --git a/entity-component-system/src/test/java/com/iluwatar/GameSystemTest.java b/entity-component-system/src/test/java/com/iluwatar/GameSystemTest.java index 6e53b24cd07f..454526354425 100644 --- a/entity-component-system/src/test/java/com/iluwatar/GameSystemTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/GameSystemTest.java @@ -98,14 +98,5 @@ void testSortEntitiesByDistance() { assertEquals(entity2, sortedEntities.get(0), "Entity2 should be closer to the reference point than Entity1."); assertEquals(entity1, sortedEntities.get(1), "Entity1 should be farther from the reference point than Entity2."); } + } - @Test -void testRenderSystem() { - - try { - gameSystem.renderSystem(); - } catch (Exception e) { - fail("Render method should not throw any exceptions."); - } - } -} diff --git a/entity-component-system/src/test/java/com/iluwatar/HealthComponentTest.java b/entity-component-system/src/test/java/com/iluwatar/HealthComponentTest.java index 98f64b15e33b..1a8086a5f743 100644 --- a/entity-component-system/src/test/java/com/iluwatar/HealthComponentTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/HealthComponentTest.java @@ -69,45 +69,45 @@ void testUpdateFunction() { @Test void testGetMaxHealth() { - HealthComponent TesthealthComponent = new HealthComponent(100f); + HealthComponent testHealthComponent = new HealthComponent(100f); - assertEquals(100f, TesthealthComponent.getMaxHealth(), "Max health should be 100."); + assertEquals(100f, testHealthComponent.getMaxHealth(), "Max health should be 100."); } @Test void testSetMaxHealth() { - HealthComponent TesthealthComponent = new HealthComponent(100f); - TesthealthComponent.setMaxHealth(120f); + HealthComponent testHealthComponent = new HealthComponent(100f); + testHealthComponent.setMaxHealth(120f); - assertEquals(120f, TesthealthComponent.getMaxHealth(), "Max health should be updated to 120."); + assertEquals(120f, testHealthComponent.getMaxHealth(), "Max health should be updated to 120."); } @Test void testIsAlive() { - HealthComponent TesthealthComponent = new HealthComponent(100f); - assertTrue(TesthealthComponent.isAlive(), "Entity should be alive initially."); - TesthealthComponent.applyDamage(100f); + HealthComponent testHealthComponent = new HealthComponent(100f); + assertTrue( testHealthComponent.isAlive(), "Entity should be alive initially."); + testHealthComponent.applyDamage(100f); - assertFalse(TesthealthComponent.isAlive(), "Entity should be dead after taking 100 damage."); + assertFalse( testHealthComponent.isAlive(), "Entity should be dead after taking 100 damage."); } @Test void testSetAlive() { - HealthComponent TesthealthComponent = new HealthComponent(100f); - assertTrue(TesthealthComponent.isAlive(), "Entity should be alive initially."); - TesthealthComponent.setAlive(false); + HealthComponent testHealthComponent = new HealthComponent(100f); + assertTrue( testHealthComponent.isAlive(), "Entity should be alive initially."); + testHealthComponent.setAlive(false); - assertFalse(TesthealthComponent.isAlive(), "Entity should be dead after setting alive to false."); + assertFalse( testHealthComponent.isAlive(), "Entity should be dead after setting alive to false."); } @Test void testSetCurrentHealth() { - HealthComponent TesthealthComponent = new HealthComponent(100f); - TesthealthComponent.setCurrentHealth(80f); + HealthComponent testHealthComponent = new HealthComponent(100f); + testHealthComponent.setCurrentHealth(80f); - assertEquals(80f, TesthealthComponent.getCurrentHealth(), "Current health should be updated to 80."); + assertEquals(80f, testHealthComponent.getCurrentHealth(), "Current health should be updated to 80."); } @Test void testHealthCannotGoAboveMax() { diff --git a/entity-component-system/src/test/java/com/iluwatar/TransformComponentTest.java b/entity-component-system/src/test/java/com/iluwatar/TransformComponentTest.java index d806cf6ed5f2..efbb0bac5bcf 100644 --- a/entity-component-system/src/test/java/com/iluwatar/TransformComponentTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/TransformComponentTest.java @@ -42,15 +42,15 @@ void setUp() { @Test void testTransformComponentConstructor() { - TransformComponent Testtransform = new TransformComponent(); + TransformComponent testTransform = new TransformComponent(); float[] expectedPosition = new float[]{0.0f, 0.0f, 0.0f}; float[] expectedRotation = new float[]{0.0f, 0.0f, 0.0f}; float[] expectedScale = new float[]{1.0f, 1.0f, 1.0f}; - assertArrayEquals(expectedPosition, transform.getPosition(), "Position should be initialized to [0.0f, 0.0f, 0.0f]"); - assertArrayEquals(expectedRotation, transform.getRotation(), "Rotation should be initialized to [0.0f, 0.0f, 0.0f]"); - assertArrayEquals(expectedScale, transform.getScale(), "Scale should be initialized to [1.0f, 1.0f, 1.0f]"); + assertArrayEquals(expectedPosition, testTransform.getPosition(), "Position should be initialized to [0.0f, 0.0f, 0.0f]"); + assertArrayEquals(expectedRotation, testTransform.getRotation(), "Rotation should be initialized to [0.0f, 0.0f, 0.0f]"); + assertArrayEquals(expectedScale, testTransform.getScale(), "Scale should be initialized to [1.0f, 1.0f, 1.0f]"); } @Test @@ -90,9 +90,9 @@ void testGetScale() { @Test void testUpdateFunction() { - TransformComponent Testtransform = new TransformComponent(); + TransformComponent testTransform = new TransformComponent(); - assertDoesNotThrow(() -> transform.update(1.0f), "update function should not throw an exception"); + assertDoesNotThrow(() -> testTransform.update(1.0f), "update function should not throw an exception"); } @Test From cada3be4d2e1cbe110c3fc2192f3dde60c6e0d7e Mon Sep 17 00:00:00 2001 From: R00V Date: Sun, 29 Dec 2024 17:18:09 +0200 Subject: [PATCH 8/9] fixing the last issues --- .../src/main/java/com/iluwatar/Component.java | 19 ------------------- .../src/main/java/com/iluwatar/Entity.java | 3 +-- .../src/test/java/com/iluwatar/AppTest.java | 4 ++-- .../test/java/com/iluwatar/ComponentTest.java | 8 -------- 4 files changed, 3 insertions(+), 31 deletions(-) diff --git a/entity-component-system/src/main/java/com/iluwatar/Component.java b/entity-component-system/src/main/java/com/iluwatar/Component.java index ca10766197be..847a48883da9 100644 --- a/entity-component-system/src/main/java/com/iluwatar/Component.java +++ b/entity-component-system/src/main/java/com/iluwatar/Component.java @@ -33,7 +33,6 @@ public abstract class Component { private String name; private boolean isEnabled; - private Entity parent; /** * Default constructor for the component. @@ -79,24 +78,6 @@ public void setEnabled(boolean isEnabled) { this.isEnabled = isEnabled; } - /** - * Gets the parent entity of this component. - * - * @return the parent entity - */ - public Entity getParent() { - return parent; - } - - /** - * Sets the parent entity of this component. - * - * @param parent the parent entity to set - */ - public void setParent(Entity parent) { - this.parent = parent; - } - /** * Abstract method to update the component. * Subclasses must implement this method to define their update behavior. diff --git a/entity-component-system/src/main/java/com/iluwatar/Entity.java b/entity-component-system/src/main/java/com/iluwatar/Entity.java index f978a10819c0..c1427c86b350 100644 --- a/entity-component-system/src/main/java/com/iluwatar/Entity.java +++ b/entity-component-system/src/main/java/com/iluwatar/Entity.java @@ -56,7 +56,7 @@ public Entity(String entityName) { name = entityName; components = new ArrayList<>(); children = new ArrayList<>(); - final UUID entityId = UUID.randomUUID(); // Generates a unique UUID for this entity + entityId = UUID.randomUUID(); // Generates a unique UUID for this entity transform = new TransformComponent(new float[] {0.0f, 0.0f, 0.0f}, new float[] {0.0f, 0.0f, 0.0f}, new float[] {1.0f, 1.0f, 1.0f}); addComponent(transform); @@ -71,7 +71,6 @@ public void addComponent(Component component) { if (component != null) { components.add(component); component.setEnabled(isEnabled); - component.setParent(this); } } diff --git a/entity-component-system/src/test/java/com/iluwatar/AppTest.java b/entity-component-system/src/test/java/com/iluwatar/AppTest.java index b3af79458c76..3fd0adbed4e1 100644 --- a/entity-component-system/src/test/java/com/iluwatar/AppTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/AppTest.java @@ -106,9 +106,9 @@ void testFinalEntityStateAfterSimulation() { GameSystem gameSystem = new GameSystem(); gameSystem.addEntity(entity1); gameSystem.addEntity(entity2); - TransformComponent Testtransform = new TransformComponent(new float[]{5.0f, 0.0f, 0.0f}, + TransformComponent TestTransform = new TransformComponent(new float[]{5.0f, 0.0f, 0.0f}, new float[]{0.0f, 45.0f, 0.0f}, new float[]{1.0f, 1.0f, 1.0f}); - entity1.setTransformComponent(Testtransform); + entity1.setTransformComponent(TestTransform); for (int i = 0; i < 10; i++) { gameSystem.update(1.0f / 60.0f); diff --git a/entity-component-system/src/test/java/com/iluwatar/ComponentTest.java b/entity-component-system/src/test/java/com/iluwatar/ComponentTest.java index 685dedc0f7eb..8a04bf357e0f 100644 --- a/entity-component-system/src/test/java/com/iluwatar/ComponentTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/ComponentTest.java @@ -56,12 +56,4 @@ void testComponentEnabled() { assertFalse(component.getEnabled(), "The component should be disabled."); } - @Test -void testComponentParent() { - Component component = new HealthComponent(100); - Entity parentEntity = new Entity("ParentEntity"); - - component.setParent(parentEntity); - assertEquals(parentEntity, component.getParent(), "The component's parent should be set correctly."); - } } From f92c2a45fa2b71e5cb8d1185a7f100cc49b08cc4 Mon Sep 17 00:00:00 2001 From: R00V Date: Sun, 29 Dec 2024 17:35:16 +0200 Subject: [PATCH 9/9] even more issues fixed --- .../src/main/java/com/iluwatar/Entity.java | 19 ------------------- .../main/java/com/iluwatar/GameSystem.java | 2 -- .../src/test/java/com/iluwatar/AppTest.java | 4 ++-- .../test/java/com/iluwatar/EntityTest.java | 10 ---------- 4 files changed, 2 insertions(+), 33 deletions(-) diff --git a/entity-component-system/src/main/java/com/iluwatar/Entity.java b/entity-component-system/src/main/java/com/iluwatar/Entity.java index c1427c86b350..fa1e2e60fba4 100644 --- a/entity-component-system/src/main/java/com/iluwatar/Entity.java +++ b/entity-component-system/src/main/java/com/iluwatar/Entity.java @@ -40,7 +40,6 @@ public class Entity { private boolean isEnabled; private TransformComponent transform; private Entity parent; - private GameSystem gameSystem; private List components; private List children; @@ -262,24 +261,6 @@ public void setIsEnabled(boolean isEnabled) { } } - /** - * Gets the game system this entity belongs to. - * - * @return the game system the entity is part of - */ - public GameSystem getGameSystem() { - return gameSystem; - } - - /** - * Sets the game system this entity belongs to. - * - * @param gameSystem the game system to set - */ - public void setGameSystem(GameSystem gameSystem) { - this.gameSystem = gameSystem; - } - /** * Gets the parent entity of this entity. * diff --git a/entity-component-system/src/main/java/com/iluwatar/GameSystem.java b/entity-component-system/src/main/java/com/iluwatar/GameSystem.java index c28a1aa395fa..2511b5ae4706 100644 --- a/entity-component-system/src/main/java/com/iluwatar/GameSystem.java +++ b/entity-component-system/src/main/java/com/iluwatar/GameSystem.java @@ -51,8 +51,6 @@ public GameSystem() { public void addEntity(Entity entity) { if (entity != null) { entities.add(entity); - entity.setGameSystem(this); - // Recursively add children entities for (Entity child : entity.getChildren()) { addEntity(child); diff --git a/entity-component-system/src/test/java/com/iluwatar/AppTest.java b/entity-component-system/src/test/java/com/iluwatar/AppTest.java index 3fd0adbed4e1..2f427bdf7783 100644 --- a/entity-component-system/src/test/java/com/iluwatar/AppTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/AppTest.java @@ -106,9 +106,9 @@ void testFinalEntityStateAfterSimulation() { GameSystem gameSystem = new GameSystem(); gameSystem.addEntity(entity1); gameSystem.addEntity(entity2); - TransformComponent TestTransform = new TransformComponent(new float[]{5.0f, 0.0f, 0.0f}, + TransformComponent testTransform = new TransformComponent(new float[]{5.0f, 0.0f, 0.0f}, new float[]{0.0f, 45.0f, 0.0f}, new float[]{1.0f, 1.0f, 1.0f}); - entity1.setTransformComponent(TestTransform); + entity1.setTransformComponent(testTransform); for (int i = 0; i < 10; i++) { gameSystem.update(1.0f / 60.0f); diff --git a/entity-component-system/src/test/java/com/iluwatar/EntityTest.java b/entity-component-system/src/test/java/com/iluwatar/EntityTest.java index 9da954c11925..a8a0cc0ec546 100644 --- a/entity-component-system/src/test/java/com/iluwatar/EntityTest.java +++ b/entity-component-system/src/test/java/com/iluwatar/EntityTest.java @@ -154,16 +154,6 @@ void testSetIsEnabled() { assertTrue(entityChild.isEnabled(), "The entity child should be enabled after calling setIsEnabled(true)."); } - @Test - void testGetAndSetGameSystem() { - - GameSystem gameSystem = new GameSystem(); - Entity entity = new Entity("MyEntity"); - entity.setGameSystem(gameSystem); - - assertEquals(gameSystem, entity.getGameSystem(), "The game system should match the one set."); - } - @Test void testUpdate_whenEntityDisabled_shouldReturnImmediately() {