It isn’t a real ECS as I said, just a way to attach behaviours or functionality to different entity-like instances. There is no System that manages the entities (although I guess you could create one), right now I just call the component functionality inside the update() method or wherever I need.
I’m using gameobjects as a base class, so if a need a type of entity that displays a Polygon I would use Phaser.GameObjects.Graphics, or if I need an Entity that is just a trigger area that dispatches ENTER and EXIT events when another entity gets in or out of it I would extend Phaser.GameObjects.Zone.
You could create three different base classes EntitySprite, EntityPolygon, EntityWhatever, one for each variant, or you could add the Entity as a mixin too.
Something like:
class Player extends Phaser.GameObjects.Sprite {
constructor() {
super();
// Add the basic Entity as a mixin
// You can add the components here in the constructor or in the class prototype
Object.assign(this, Entity);
Object.assign(this, Controllable);
Object.assign(this, Collidable);
update() {
// Access component functionality
const userInput = this.getInput();
if(userInput.isPressingRight) {
// Move your character to the right
} else if(userInput.isPressingLeft) {
// Move to the left
}
}
}
}
// Then in Controllable.js
const Controllable = {
hasControllableComponent: true,
isPressingRight: false,
isPressingLeft: false,
// Hold Key objects from the Phaser Input manager
this._controlKeys: null,
// you can initialize the component an pass dependencies here
initControllableComponent: function(scene, someDependency) {
this._controlKeys = scene.input.keyboard.addKeys({
up: Phaser.Input.Keyboard.KeyCodes.UP,
down: Phaser.Input.Keyboard.KeyCodes.DOWN,
left: Phaser.Input.Keyboard.KeyCodes.LEFT,
right: Phaser.Input.Keyboard.KeyCodes.RIGHT,
});
},
getInput: function () {
// Process which keys is the user pressing
this.isPressingRight = this._controlKeys.right.isDown;
this.isPressingLeft = this._controlKeys.left.isDown;
},
}
};
The GameObject base class acts as a Renderable component would in a real ECS. With a little more thought a Renderable component could be implemented but I think that just would be overkill.
For my current needs (and time schedule) this approach works for me, I can create different components and add them to different “entities”, a Player, an Enemy, a MoveablePlatform.
Another thing worth mentioning is that I’m using Groups to group them and manage them per type of entity. Groups are not visual groups, they are logical groups so when I need to update the enemies I would use the enemiesGroup and execute update on each child of the group:
this.movingPlatformsGroup.children.iterate(function(child) {
child.update(time, delta);
}, this);
// or set the auto update
this.enemiesGroup = this.add.group();
this.enemiesGroup.runChildUpdate = true;
Sorry I can’t add more detail to my answer, I’m just starting with this too so trying different things to see what works best, also I have a deadline soon XD