111 lines
3.9 KiB
Markdown
111 lines
3.9 KiB
Markdown
*| [JavaECS](../../README.md) | [docs](../overview.md) | [system](./dir.md) | System[]().md*
|
|
# System
|
|
| **In this section** |
|
|
|-|
|
|
| [About](#about) |
|
|
| [Implementation](#implementation)|
|
|
| [Examples](#examples)|
|
|
| [Notes](#notes) |
|
|
|
|
## About
|
|
>A system is a functionality that is executed regularly by the game engine.
|
|
|
|
The [SystemManager](./SystemManager.md) ensures that the system has an up-to-date list of entities that the system would act upon. This is performed by comparing the system's declared required components with the components of a potential entity. An entity containing all required components is added to the system's list.
|
|
|
|
A system does not explicitly require any entities to be registered; but it can make more sense to directly perform such operations in the game loop.
|
|
|
|
`TODO`
|
|
There is a single layer of inheritence in this design, which is the overriden `init()` and `update()` functions.
|
|
This allows each system's `update()` to be called in a uniform way.
|
|
|
|
## Implementation
|
|
|
|
All systems should extend [ECSSystem](./ECSSystem.md), which implements the entities list as a simple set.
|
|
|
|
This can be overriden if there are certain requirements for the order of the entities (e.g. a Render System might require the further-most elements to be drawn first, to ensure the correct z-ordering)
|
|
|
|
``` java
|
|
class ECSSystem{
|
|
Set<Integer> entities = new HashSet<>();
|
|
}
|
|
```
|
|
``` java
|
|
class NewSystem extends ECSSystem{
|
|
void init() {}
|
|
void update(/* any required parameters*/){
|
|
/* implementation */
|
|
}
|
|
}
|
|
```
|
|
|
|
## Examples
|
|
### System that operates on entities with <span style="color:white">multiple components</span>
|
|
``` java
|
|
public class PhysicsSystem extends ECSSystem{
|
|
ECS gameEngine;
|
|
public PhysicsSystem(ECS gameEngine){
|
|
this.gameEngine = gameEngine;
|
|
}
|
|
|
|
void init() {}
|
|
|
|
void update(double dt){
|
|
for (Integer entity : entities) {
|
|
// Get entity components
|
|
Vec2D pos = (Vec2D)gameEngine.getComponentData(entity, Vec2D.class.getName());
|
|
RidgidBody ridgidBody = (RidgidBody)gameEngine.getComponentData(entity, RidgidBody.class.getName());
|
|
Gravity gravity = (Gravity)gameEngine.getComponentData(entity, Gravity.class.getName());
|
|
// Add the result of the accelerative forces to the ridgidbody's velocity
|
|
ridgidBody.xdot += ridgidBody.xAcc * dt;
|
|
ridgidBody.ydot += ridgidBody.yAcc * dt;
|
|
|
|
// Gravity is a force of acceleration as above, but is generally considered to be constant.
|
|
if (gravity.terminalX < 0 || Math.abs(ridgidBody.xdot) < gravity.terminalX){
|
|
ridgidBody.xdot += gravity.x * dt;
|
|
}
|
|
if (gravity.terminalY < 0 || Math.abs(ridgidBody.ydot) < gravity.terminalY){
|
|
ridgidBody.ydot += gravity.y * dt;
|
|
}
|
|
|
|
// Finally, move the vec2d by the new velocity
|
|
pos.x += ridgidBody.xdot * dt;
|
|
pos.y += ridgidBody.ydot * dt;
|
|
}
|
|
}
|
|
}
|
|
```
|
|
### System that operates on a <span style="color:white">single component</span>
|
|
``` java
|
|
public class LogVec2DSystem extends ECSSystem{
|
|
ECS gameEngine;
|
|
public LogVec2DSystem(ECS gameEngine){
|
|
this.gameEngine = gameEngine;
|
|
}
|
|
|
|
void init() {}
|
|
|
|
void update(double dt){
|
|
for (Integer entity : entities) {
|
|
Vec2D pos = (Vec2D)gameEngine.getComponentData(entity, Vec2D.class.getName());
|
|
System.out.println(String.format("X: %.6g, Y: %.6g", pos.x, pos.y));
|
|
}
|
|
}
|
|
}
|
|
```
|
|
### System that operates on <span style="color:white">no components</span>
|
|
Note that it does not require a reference the the `gameEngine`; no component data is accessed.
|
|
``` java
|
|
public class FrameRateSystem extends ECSSystem{
|
|
void init() {}
|
|
|
|
void update(double dt, double idleTime){
|
|
System.out.print(String.format("dt: %.3g (%.3g idle) ", dt, idleTime));
|
|
}
|
|
}
|
|
```
|
|
|
|
## Notes
|
|
|
|
|
|
|