denniskaselow / dartemis

A Dart port of the Artemis Entity System Framework
BSD 2-Clause "Simplified" License
47 stars 6 forks source link

dartemis

Build Status Coverage Status Pub

Content

About

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:

Getting started

  1. Add dartemis to your project by adding it to your pubspec.yaml:

    dependencies:
     dartemis: any
  2. Import it in your project:

    import 'package:dartemis/dartemis.dart';
  3. Create a world:

    final world = World();
  4. 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.

  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 {
     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;
     }
    }
  6. Add your system to the world:

    world.addSystem(MovementSystem());
  7. Initialize the world:

    world.initialize();   
  8. Usually your logic requires a delta, so you need to set it in your game loop:

    world.delta = delta;
  9. In your game loop you then process your systems:

    world.process();

Documentation

API

Reference Manual

Example Games using dartemis