new changes
parent
289b635077
commit
e9602140e9
63
README.md
63
README.md
|
|
@ -80,48 +80,72 @@ Werden jetzt wie im vorherigen Beispiel die Lebenspunkte aller Wesen gebraucht,
|
|||
|
||||
Ein Entity-Component-System besteht aus vier Konzepten:
|
||||
|
||||
### Entities
|
||||
### Entity
|
||||
|
||||
Entities sind Spielobjekte, sie sind meist nicht mehr als eine fortlaufende ID.
|
||||
|
||||
### Components
|
||||
|
||||
### Component
|
||||
Components sind die zum Spielobjekt gehörenden Daten. Wie viele Daten jede Art von Component enthält kann verschieden sein.
|
||||
Zum Beispiel kann ein `Lebenspunkte` Component nur die derzeitigen Lebenspunkte enthalten, während ein `Kampfkraft` Component Schaden, Geschwindigkeit und Rüstung enthält.
|
||||
|
||||
### Registry
|
||||
|
||||
Die Registry ist eine Datenbank, die alle Entities ihren Components zuweist und folgende Operationen Erlaubt:
|
||||
Die Registry ist eine Datenbank, die alle Entities ihren Components zuweist und meist folgende Operationen erlaubt:
|
||||
- addComponent(entity, component) -- Füge einen neuen Component in die verwaltung hinzu.
|
||||
- removeComponent(entity, ComponentType) -- Lösche den Component diesen Types für die Entity.
|
||||
- withComponents(ComponentTypes[]) -- erstelle eine Liste aller Entities, die alle angegebenen Component Typen besitzen.
|
||||
|
||||
### Sytem
|
||||
|
||||
Systems bilden die Anwendungslogik ab. Sie können die Registry nach Entities abfragen und neue Entities oder Components hinzufügen.
|
||||
Ein System könnte zum Beispiel die Schadensberechnung für alle Einheiten durchführen und daraus Schadens-Entities erstellen und ein anderes System alle Schadens-Entities abfragen und Lebenspunkte abziehen.
|
||||
|
||||
|
||||
## Aufgabe
|
||||
|
||||
Ihre Aufgabe ist es ein Entity-Component-System zu entwickeln.
|
||||
Das ECS muss mindestens aus folgenden Klassen bestehen:
|
||||
|
||||
- class Entity -- Entities sollten unveränderbar und nach Wert vergleichbar sein.
|
||||
- die folgenden beiden Konstruktoren müssen existieren:
|
||||
- public Entity()
|
||||
- protected Entity(int)
|
||||
|
||||
- interface Component -- Ein interface zur Markierung von Components.
|
||||
- class Registry -- Die Registry soll alle Entities und Components verwalten. Sie soll folgende Operationen unterstuützen:
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ │
|
||||
│ registerComponentType(componentClass) │
|
||||
│ └─ Registriert eine neue Art von Component zur Verwaltung │
|
||||
│ └─ Registriert eine neue Art von Component zur Verwaltung.
|
||||
| Es dürfen nur Klassen akzeptiert werden, die das Interface Component implementieren │
|
||||
│ │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ addComponent(entity, component) │
|
||||
│ └─ Fügt der Entity einen neuen Component hinzu │
|
||||
│ └─ Fügt der Entity einen neuen Component hinzu.
|
||||
| Diese Methode akzeptiert alle Components, die das Interface Component implementieren.
|
||||
| Besitzt die Entity bereits einen Component dieser Klasse, wird dieser durch die neue Instanz ersetzt. │
|
||||
│ │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ removeComponent(entity, componentType) │
|
||||
│ └─ Löscht den angegebenen Component von der Entity │
|
||||
│ removeComponent(entity, componentClass) │
|
||||
│ └─ Löscht den Component der angegebenen Klasse von der Entity. │
|
||||
│ │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ hasComponent(entity, componentType) → boolean │
|
||||
│ └─ Prüft, ob die Entity einen Component diesen Types hat │
|
||||
│ hasComponent(entity, componentClass) → boolean │
|
||||
│ └─ Prüft, ob die Entity einen Component dieser Klasse hat. │
|
||||
│ │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ getComponent(entity, componentType) → component │
|
||||
│ └─ Gibt den angegebenen Component für die Entity zurück │
|
||||
│ getComponent(entity, componentClass) → component │
|
||||
│ └─ Gibt den Component der angegebenen Klasse für die Entity zurück. │
|
||||
│ │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ withComponents(componentType...) → entity[] │
|
||||
│ └─ Gibt alle Entities zurück, die alle angegebenen Components haben │
|
||||
│ withComponents(componentClass...) → entity[] │
|
||||
│ └─ Gibt alle Entities zurück, die alle angegebenen Components haben. │
|
||||
│ │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
|
|
@ -131,6 +155,13 @@ Die Registry ist eine Datenbank, die alle Entities ihren Components zuweist und
|
|||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Sytems
|
||||
Tipp:
|
||||
|
||||
Systems bilden die Anwendungslogik ab. Sie können die Registry nach Entities abfragen und neue Entities oder Components hinzufügen
|
||||
Sie können die Klasse eines Objektes mit der .class Eigenschaft ermitteln. Das damit erzeugte Class-Token kann wie jeder andere Wert in Datenstruckturen gespeichert werden.
|
||||
|
||||
```
|
||||
class App {}
|
||||
|
||||
App app = new App();
|
||||
Class<App> appClassToken = app.class;
|
||||
```
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
public record BattleWin(
|
||||
Entity winningSquad,
|
||||
Entity loosingSquad,
|
||||
boolean draw,
|
||||
) {
|
||||
|
||||
}
|
||||
|
|
@ -7,22 +7,34 @@ import com.example.ecs.Entity;
|
|||
|
||||
public class Squad implements Component {
|
||||
private String name;
|
||||
private List<Entity> units;
|
||||
private List<Entity> activeUnits;
|
||||
private List<Entity> deadUnits;
|
||||
|
||||
public Squad(String name, List<Entity> units) {
|
||||
this.name = name;
|
||||
this.units = units;
|
||||
}
|
||||
|
||||
public void removeUnit(Entity entity) {
|
||||
units.remove(entity);
|
||||
public void killUnit(Entity entity) {
|
||||
if (activeUnits.contains(entity)) {
|
||||
activeUnits.remove(entity);
|
||||
deadUnits.add(unit);
|
||||
}
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<Entity> units() {
|
||||
return units;
|
||||
public List<Entity> activeUnits() {
|
||||
return activeUnits;
|
||||
}
|
||||
|
||||
public List<Entity> deadUnits() {
|
||||
return deadUnits;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return !activeUnits.empty()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
package com.example.systems;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.example.components.Attack;
|
||||
import com.example.components.Battle;
|
||||
import com.example.components.Hero;
|
||||
import com.example.components.Squad;
|
||||
import com.example.components.Stats;
|
||||
import com.example.ecs.Entity;
|
||||
import com.example.ecs.Registry;
|
||||
import com.example.ecs.System;
|
||||
|
||||
public class SquadUpdateSystem extends System {
|
||||
|
||||
public UnitKillerSystem(Registry registry) {
|
||||
super(registry);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
for (var battleEntity : registry.getWithComponents(Battle.class)) {
|
||||
var battle = registry.getComponent(battleEntity, Battle.class);
|
||||
|
||||
var squad1 = registry.getComponent(battle.squad1(), Squad.class);
|
||||
var squad2 = registry.getComponent(battle.squad2(), Squad.class);
|
||||
|
||||
Entity battleWinEntity = new Entity();
|
||||
if (squad1.isActive() && squad2.isActive()) {
|
||||
BattleWin battleWin(battle.squad1(), battle.squad2(), true);
|
||||
registry.add(battleWinEntity, battleWin);
|
||||
} else if (squad1.isActive) {
|
||||
BattleWin battleWin(battle.squad2(), battle.squad1(), false);
|
||||
registry.add(battleWinEntity, battleWin);
|
||||
} else if (squad2.isActive()) {
|
||||
BattleWin battleWin(battle.squad1(), battle.squad2(), false);
|
||||
registry.add(battleWinEntity, battleWin);
|
||||
}
|
||||
|
||||
if (squad1.isActive() || squad2.isActive()) {
|
||||
registry.remove(battleEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package com.example.systems;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.example.components.Attack;
|
||||
import com.example.components.Battle;
|
||||
import com.example.components.Hero;
|
||||
import com.example.components.Squad;
|
||||
import com.example.components.Stats;
|
||||
import com.example.ecs.Entity;
|
||||
import com.example.ecs.Registry;
|
||||
import com.example.ecs.System;
|
||||
|
||||
public class WinSystem extends System {
|
||||
|
||||
public WinSystem(Registry registry) {
|
||||
super(registry);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
for (var battleEntity : registry.getWithComponents(Battle.class)) {
|
||||
var battle = registry.getComponent(battleEntity, Battle.class);
|
||||
|
||||
var squad1 = registry.getComponent(battle.squad1(), Squad.class);
|
||||
var squad2 = registry.getComponent(battle.squad2(), Squad.class);
|
||||
|
||||
Entity battleWinEntity = new Entity();
|
||||
if (squad1.isActive() && squad2.isActive()) {
|
||||
BattleWin battleWin(battle.squad1(), battle.squad2(), true);
|
||||
registry.add(battleWinEntity, battleWin);
|
||||
} else if (squad1.isActive) {
|
||||
BattleWin battleWin(battle.squad2(), battle.squad1(), false);
|
||||
registry.add(battleWinEntity, battleWin);
|
||||
} else if (squad2.isActive()) {
|
||||
BattleWin battleWin(battle.squad1(), battle.squad2(), false);
|
||||
registry.add(battleWinEntity, battleWin);
|
||||
}
|
||||
|
||||
if (squad1.isActive() || squad2.isActive()) {
|
||||
registry.remove(battleEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.example.ecs;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assert;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Unit test for simple App.
|
||||
*/
|
||||
public class EntityTest {
|
||||
|
||||
/**
|
||||
* Rigorous Test :-)
|
||||
*/
|
||||
@Test
|
||||
public void ShouldBeCreatable() {
|
||||
Entity entity = new Entity();
|
||||
assert()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.example.ecs;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Unit test for simple App.
|
||||
*/
|
||||
public class RegistryTest {
|
||||
|
||||
/**
|
||||
* Rigorous Test :-)
|
||||
*/
|
||||
@Test
|
||||
public void shouldAnswerWithTrue() {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue