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:
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();