Update 'README.md'

Changed docs description to a 'Getting Started'
This commit is contained in:
Brychan Dempsey 2021-06-10 00:13:42 +12:00
parent e00558937a
commit 0bc67fe87b

107
README.md
View File

@ -4,63 +4,66 @@
### [View the Documentation](./docs/overview.md) ### [View the Documentation](./docs/overview.md)
## *About Entity-Component-Systems* ## *About Entity-Component-Systems*
An Enity-Component-System comprises of four main parts
1. The [entity](./docs/entity/Entity.md) which is essentially just a unique ID *i.e. an integer value*
2. The [component](./docs/entity/Component.md) which is a `struct` (`class` in Java). Typically contains data, but can be empty (to be used as a flag for certain systems) or contain function definitions.
3. The [system](./docs/system/System.md) which defines two main functions: `init()` and `update()`. Systems define a filter that is used to maintain a current and relevant list of entities that the system will act on.
4. The [engine](./docs/Engine.md), which ties everything together. It exposes the functions that should be called, and methods for retrieving data correctly. The initialisation of everything required also takes place here
Traditional game-engine designs typically follow the standard functional or object-oriented design paradigms. ## About the implementation
This choice of paradigm is as important as it is in typical applications. The JavaECS project is a Maven project targeting Java SE 1.8.
It is released under the MIT licence.
It is intended to be compiled and packed into a `.jar` and referenced and imported into a project.
The Maven build script will produce a `javadoc` `.jar` with the library.
A functional-paradigm game usually focuses on a 'this-then-that' model, e.g.: ## Getting started with JavaECS
Initialise the library like so:
``` java
Engine gameEngine = new Engine(/* desired number of entities */);
```
Next, the known components should be added.
***Simple Driving Game*** Use the reflective component type:
``` java
``` py gameEngine.registerComponent(ExampleComponent.class);
turn = GetTurn()
TurnCar(turn)
if IsCollided(): # and other checks
GameOver()
else:
DrawNextFrame()
turn = GetTurn()
``` ```
Such a system works well for some game-designs; it is simplistic and follows a deterministic sequence of steps. But it lacks scalability and extensibility. Next, register the systems that are required.
Each system must be constructed, and passed as a parameter to the Engine.
An Object-Oriented approach could be used instead: - *If the system shall be invoked elsewhere, then you can petition the engine for the instance of the system.*
``` py ``` java
# Create a base-class that is a vehicle, with basic properties: ExampleSystem exampleSystem = new ExampleSystem(gameEngine);
class Vehicle: gameEngine.registerSystem(ExampleSystem.class, exampleSystem);
position = [x,y]
IsCrashed = False
def CalcTurn():
pass
def IsCollided():
pass
# Create the PlayerVehicle class which extends Vehicle to include the player input method
class PlayerVehicle(Vehicle):
def GetPlayerInput():
pass
def GameLoop():
vehicles[] = GetAllVehichles()
allCollided = False
while not allCollided:
for v in vehicles:
turnAmount
if v is PlayerVehicle:
turnAmount = v.GetPlayerInput()
else:
turnAmount = v.CalcTurn()
v.TurnVehicle()
if v.IsCollided():
v.IsCrashed = True
anyNotCollided = False
for v in vehicles:
if v.IsCrashed = False:
anyNotCollided = True
break
``` ```
Which allows the instancing of objects. Each action also results in an objective state, which can be simply compared to determine the result. Next, create the entities that are needed as required.
``` java
Entity newEntity = gameEngine.createEntity();
```
ECS are typically built on object-oriented ideas, but make specfic attempts to reduce overheads that come from object-oriented ideas. Assign the components to the entity:
The primary reduction made in ECS is to eliminate or otherwise minimise inhertance cycles to reduce the amount of virtual calls required. ``` java
gameEngine.addComponent(newEntity, ExampleComponent.class, new ExampleComponent());
```
Be sure to call `init()` on each system, before the logical loop of the program
``` java
exampleSystem.init();
```
Finally, the engine is ready to enter the logical loop, e.g.:
``` java
while (true){
exampleSystem.update();
}
```
* note systems are *not* required to perform their `update()` in the normal logical loop.
* the update can also be performed at a factored rate. E.g. physics can be performed at a different rate to the renderer, in order to improve physics accuracy
* when using your own implmentation of a system, you may leave `init()` empty. Therefore, it isn't necessary to call `init()` before the game loop. **However**, It is recommended that you call `init()` to maintain consistency with all systems in the engine.
* Entities, components, and systems can be created at any time in the program lifecycle.
* Entities can be destroyed.
* Components and systems cannot be destroyed.
* Be aware that component registrations are contained via [BitSet](https://docs.oracle.com/javase/8/docs/api/java/util/BitSet.html). As the array is extended as bits are needed, note that the order of the set bits may impact performance with a large number of component types.
### Example:
[App.java](/BrychanD/JavaECS-Examples/src/branch/master/demo1/src/main/java/nz/ac/massey/javaecs/examples/App.java#line=29-128)