Skip to content

The Basics

FNGgames edited this page Mar 17, 2017 · 9 revisions

Group

Groups are always up-to-date and contain all entities matching the specified matcher. There is a specific Matcher Type for each context - if you're looking for entities in your Game context (i.e. GameEntities) you'll need to use a GameMatcher.

var context = contexts.game;

var movables = context.GetGroup(GameMatcher.Movable);
var count = movables.count; // count is 0, the group is empty

var entity1 = context.CreateEntity().IsMovable(true);
var entity2 = context.CreateEntity().IsMovable(true);

count = movables.count; // count is 2, the group contains the entity1 and entity2

// GetEntities() always provides an up to date list
var movableEntities = movables.GetEntities();
foreach (var e in movableEntities) {
    // Do sth
}

context.DestroyEntity(entity1);
context.DestroyEntity(entity2);

count = movables.count; // count is 0, the group is empty

Matcher

Matchers are generated by the code generator and can be combined. Matchers are usually used to get groups of entities from the context of interest.

var matcher = Matcher.Movable;

Matcher.AllOf(Matcher.Movable, Matcher.Position);

Matcher.AnyOf(Matcher.Move, Matcher.Position);

Matcher
    .AllOf(Matcher.Position)
    .AnyOf(Matcher.Health, Matcher.Interactive)
    .NoneOf(Matcher.Animating);

Systems

There are 3 different types of Systems:

  • IInitializeSystem: Executes once (system.Initialize())
  • IExecuteSystem: Executes every frame (system.Execute())
  • IReactiveSystem: Executes when the observed group changed (system.Execute(Entity[]))
public class MoveSystem : IExecuteSystem {
    public void Execute() {
        // Do sth
    }
}

public class CreateLevelSystem : IInitializeSystem {
    public void Initialize() {
        // Do sth
    }
}

public class RenderPositionSystem : IReactiveSystem {
    public TriggerOnEvent trigger {
        get { return Matcher.AllOf(Matcher.Position, Matcher.View).OnEntityAdded(); }
    }

    public void Execute(List<Entity> entities) {
        // Do sth
    }
}

You can also mix interfaces

public class UpdateBoardSystem : IInitializeSystem, IReactiveSystem, ISetPool {

    Pool _pool;
    Group _myGroup;

    public void SetPool(Pool pool) {
        _pool = pool;
        _myGroup = pool.GetGroup(Matcher.Xyz);
    }

    public void Initialize() {
        // Do sth
    }

    public TriggerOnEvent trigger {
        get { return Matcher.AllOf(Matcher.Position, Matcher.View).OnEntityAdded(); }
    }

    public void Execute(List<Entity> entities) {
        // Do sth
    }
}

There are multiple ways how to create systems. The simplest one that works for any kind of system is probably pool.CreateSystem<T>()

new MoveSystem();

// Creates a new MoveSystem instance and
// will call SetPool if ISetPool is implemented
pool.CreateSystem<MoveSystem>();


// Will call SetPool if ISetPool is implemented
pool.CreateSystem(new MoveSystem());


// Recognizes that UpdateBoardSystem is a reactive system.
// It will create a new ReactiveSystem with UpdateBoardSystem as
// the subSystem.
// Will call SetPool if ISetPool is implemented
var reactiveSystem = pool.CreateSystem<UpdateBoardSystem>();
var systems = new Systems()
    .Add(pool.CreateSystem<CreateLevelSystem>())
    .Add(pool.CreateSystem<UpdateBoardSystem>())
    .Add(pool.CreateSystem<MoveSystem>())
    .Add(pool.CreateSystem<RenderPositionSystem>());

// Call once on start
systems.Initialize();

// Call every frame
systems.Execute();

Get inspired by Match-One GameController.cs

Clone this wiki locally