dartemis is a Dart port of the Entity System Framework Artemis.
The original has been written in Java by Arni Arent and Tiago Costa and can be found here: https://gamadu.com/artemis/ (archived) with the source available here: https://code.google.com/p/artemis-framework/
Ports for other languages are also available:
Some useful links about what an Entity System/Entity Component System is:
- https://piemaster.net/2011/07/entity-component-artemis/ (archived)
- http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/
- https://www.richardlord.net/blog/what-is-an-entity-framework
-
Add dartemis to your project by adding it to your pubspec.yaml:
dependencies: dartemis: any
-
Import it in your project:
import 'package:dartemis/dartemis.dart';
-
Create a world:
final world = World();
-
Create an entity from a list of components. Entities with different components will be processed by different systems:
world.createEntity([ Position(0, 0), Velocity(1, 1), ]);
A
Component
is a pretty simple structure and should not contain any logic:class Position extends Component { num x, y; Position(this.x, this.y); }
Or if you want to use a
PooledComponent
:class Position extends PooledComponent { late num x, y; Position._(); factory Position(num x, num y) { final position = Pooled.of<Position>(() => Position._()) ..x = x ..y = y; return position; } }
By using a factory constructor and calling the static function
Pooled.of
, dartemis is able to reuse destroyed components and they will not be garbage collected. -
Define a systems that should process your entities. The
Aspect
defines which components an entity needs to have in order to be processed by the system:class MovementSystem extends EntityProcessingSystem { late Mapper<Position> positionMapper; late Mapper<Velocity> velocityMapper; MovementSystem() : super(Aspect.forAllOf([Position, Velocity])); void initialize() { // initialize your system // Mappers, Systems and Managers have to be assigned here // see dartemis_builder if you don't want to write this code positionMapper = Mapper<Position>(world); velocityMapper = Mapper<Velocity>(world); } void processEntity(Entity entity) { Position position = positionMapper[entity]; Velocity vel = velocityMapper[entity]; position ..x += vel.x * world.delta ..y += vel.y * world.delta; } }
Or using dartemis_builder
part 'filename.g.part'; @Generate( EntityProcessingSystem, allOf: [ Position, Velocity, ], ) class SimpleMovementSystem extends _$SimpleMovementSystem { @override void processEntity(Entity entity, Position position, Velocity velocity) { position ..x += velocity.x * world.delta ..y += velocity.y * world.delta; } }
-
Add your system to the world:
world.addSystem(MovementSystem());
-
Initialize the world:
world.initialize();
-
Usually your logic requires a delta, so you need to set it in your game loop:
world.delta = delta;
-
In your game loop you then process your systems:
world.process();
- darteroids - Very simple example included in the example folder of dartemis, (Source)
- Shapeocalypse - A fast paced reaction game using Angular, WebAudio and WebGL
- damacreat - An iogame similar to agar.io about creatures made of dark matter (circles) consuming dark energy (circles) and other dark matter creatures (circles), which can shoot black holes (circles)