Custom Components
Custom Components
Components are the building blocks of ECS. They store an entity’s state in a modular way. By creating custom components, you can:
- Encapsulate reusable data
- Expose helper methods to manipulate that data
- Keep logic separate from systems (or complement systems later)
A component should describe “what an entity has”, not “what it does.” Systems are where behavior happens — but components can have convenience methods that make life easier.
There are two ways you can build out a component:
- The traditional way
- Systemless Components (advanced)
Let's focus on traditional components first
Example: Keyboard Control
tsimport { Component, Engine } from 'excalibur';type Directions = 'Left'|'Right'|'Up'|'Down';export class PlayerMovementComponent extends Component {_enabled: boolean = true;speed = 150;heldKeys: Directions[] = [];keyboard: Keyboard;constructor(engine: Engine,speed?:number){super();if(speed) this.speed = speed;this.keyboard = engine.input.keyboard;}set enable(enable: boolean){this._enabled = enable;}get enable(){return this._enabled;}
tsimport { Component, Engine } from 'excalibur';type Directions = 'Left'|'Right'|'Up'|'Down';export class PlayerMovementComponent extends Component {_enabled: boolean = true;speed = 150;heldKeys: Directions[] = [];keyboard: Keyboard;constructor(engine: Engine,speed?:number){super();if(speed) this.speed = speed;this.keyboard = engine.input.keyboard;}set enable(enable: boolean){this._enabled = enable;}get enable(){return this._enabled;}
To add this component to your Actor that you want controlled by keypress, simply:
tsimport { Engine, Actor, Color } from 'excalibur';import { PlayerMovementComponent } from './PlayerMovementComponent';import { MovementSystem } from './MovementSystem';const engine = new Engine();const player = new Actor({ x: 100, y: 100, width: 32, height: 32, color: Color.Red });player.addComponent(new PlayerMovementComponent(engine, 100));engine.add(player);engine.start();
tsimport { Engine, Actor, Color } from 'excalibur';import { PlayerMovementComponent } from './PlayerMovementComponent';import { MovementSystem } from './MovementSystem';const engine = new Engine();const player = new Actor({ x: 100, y: 100, width: 32, height: 32, color: Color.Red });player.addComponent(new PlayerMovementComponent(engine, 100));engine.add(player);engine.start();
and to access this componet in your code you simply use:
tslet keyboardControl = player.get(PlayerMovementCompontent);// now keyboardControl has the speed, enable, and heldKeys properties on it!// also it will have the engine reference to the keyboard input
tslet keyboardControl = player.get(PlayerMovementCompontent);// now keyboardControl has the speed, enable, and heldKeys properties on it!// also it will have the engine reference to the keyboard input
We will look at the keyboard system in the next section.