dartemis 0.6.0 dartemis: ^0.6.0 copied to clipboard
An Entity System Framework for game development. Based on Artemis.
dartemis #
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: http://gamadu.com/artemis 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:
- http://piemaster.net/2011/07/entity-component-artemis/
- http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/
- http://www.richardlord.net/blog/what-is-an-entity-framework
Getting started #
1. Add dartemis to your project by adding it to your pubspec.yaml
2. Import it in your project:
import 'package:dartemis/dartemis.dart';
3. Create a world:
World world = new World();
4. Create entities, add components to them and finally add those entities to the world. Entities with different components will be processed by different systems:
Entity entity = world.createEntity();
entity.addComponent(new Position(world, 0, 0));
entity.addComponent(new Velocity(world, 1, 1));
entity.addToWorld();
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 ComponentPoolable
:
class Position extends ComponentPoolable {
num x, y;
Position._();
factory Position(num x, num y) {
Position position = new Poolable.of(Position, _constructor);
position.x = x;
position.y = y;
return position;
}
static Position _constructor() => new Position._();
}
By using a factory constructor and calling the factory constructor in Poolable
, dartemis is able to reuse destroyed components and they will not be garbage collected. For more information about why this is done you might want to read this article: Free Lists For Predictable Game Performance
5. 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 {
ComponentMapper<Position> positionMapper;
ComponentMapper<Velocity> velocityMapper;
MovementSystem() : super(Aspect.getAspectForAllOf([Position, Velocity]));
void initialize() {
positionMapper = new ComponentMapper<Position>(Position, world);
velocityMapper = new ComponentMapper<Velocity>(Velocity, world);
}
void processEntity(Entity entity) {
Position position = positionMapper.get(entity);
Velocity vel = velocityMapper.get(entity);
position.x += vel.x;
position.y += vel.y;
}
}
6. Add your system to the world:
world.addSystem(new MovementSystem());
7. Initialize the world:
world.initialize();
8. In your game loop you then process your systems:
world.process();
If your game logic requires a delta you can set it by calling:
world.delta = delta;
Injection #
If you want to write less code, you can use a version of dartemis that uses
mirrors to inject Managers
, EntitySystems
and ComponentMapper
. The
injection takes place when you call world.initialize()
, right before the
initialize()
method of your EntitySystem
is executed. For the injection to
work, you have to add the systems and managers with injectable fields to the
@MirrorsUsed
annotation.
To use that version of dartemis, you have to do these steps instead:
2. Import it in your project:
@MirrorsUsed(targets: const [MovementSystem, OtherSystemsOrManagersThatYouUse])
import 'dart:mirrors';
import 'package:dartemis/dartemis_mirrors.dart';
5. 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 {
// no initialize required, the objects will be injected
ComponentMapper<Position> positionMapper;
ComponentMapper<Velocity> velocityMapper;
MovementSystem() : super(Aspect.getAspectForAllOf([Position, Velocity]));
void processEntity(Entity entity) {
Position position = positionMapper.get(entity);
Velocity vel = velocityMapper.get(entity);
position.x += vel.x;
position.y += vel.y;
}
}
Documentation #
API #
Example Games using dartemis #
- VDrones - An arcade game (with weekly updates), (Source)
- GitHub Space Off - Originally created for the GitHub Game Off 2012, (Source)
- darteroids - Very simple example included in the example folder of dartemis, (Source)
Add-ons #
- dartemis_toolbox - A set of addons to use with dartemis (like EntityStateMachine, ...) and other libraries for gamedev.