World
Class for world.
Constructor Summary
Public Constructor | ||
public |
constructor(options: object) Constructs an instance of the world. |
Member Summary
Public Members | ||
public set |
Registers all components in an object. |
|
public get |
components: * Returns currently registered components. |
|
public set |
Sets a context object that is automatically injected into all existing and new systems. |
|
public get |
context: * Returns currently set context object. |
|
public set |
Registers additional systems, in the order specified. |
|
public get |
systems: * Returns currently added systems, in the order added. |
Method Summary
Public Methods | ||
public |
clear() Removes all entities from the world. |
|
public |
Registers a component type to the world. |
|
public |
Iterate through components and entities with all of the specified component names |
|
public |
Creates a new entity in the world |
|
public |
Calls run() on all systems. |
|
public |
Registers a system to the world. |
Public Constructors
public constructor(options: object) source
Constructs an instance of the world.
Params:
Name | Type | Attribute | Description |
options | object |
|
The initial systems, components, and context to setup in the world. Each one is optional. See below for registering these after world construction. |
Example:
const world = new World({
components: { position, velocity },
systems: [Input, Physics, Render],
context: { state },
})
Public Members
public set components source
Registers all components in an object. Merges with existing registered components.
Example:
world.components = { position: Position }
public get components: * source
Returns currently registered components.
Example:
const { position: Position } = world.components
public set context(data: Object) source
Sets a context object that is automatically injected into all existing and new systems. Calling this multiple times will overwrite any previous contexts passed. One caveat is that you can only start to use the injected context in systems starting with init(). It is not available in the constructor.
Example:
const state = { app: new PIXI.Application() }
const world = new World()
world.context = state // new and existing systems can directly use this.app
world.system(...)
public get context: * source
Returns currently set context object.
Example:
const { app } = world.context
public set systems source
Registers additional systems, in the order specified. See world.system().
Example:
world.systems = [inputSystem, movementSystem]
public get systems: * source
Returns currently added systems, in the order added.
Example:
const [inputSystem, movementSystem] = world.systems
Public Methods
public clear() source
Removes all entities from the world. Does not affect any registered systems or components.
Example:
world.clear()
public component(name: string, componentClass: function): string source
Registers a component type to the world. Components must be constructable. If the component has an onCreate(), it is passed all of the arguments from methods like entity.set(). Also, components can have an onRemove() method, which gets called when removing that component from an entity.
Example:
world.component('myComponent', class {
// It is highly recommended to use onCreate() over constructor(), because the component
// will have already been added to the entity. In the constructor(), it is not safe to use
// "entity" because it does not contain the current component while still in the constructor.
onCreate(some, args) {
this.some = some
this.args = args
this.entity.set('whatever') // this.entity is auto-injected, and this is safe to do here
}
})
// entity === the new entity object
// some === 10
// args === 500
world.entity().set('myComponent', 10, 500)
public each(args: ...Object): Entity[] source
Iterate through components and entities with all of the specified component names
Params:
Name | Type | Attribute | Description |
args | ...Object | Can pass component names, arrays of component names, and a callback, in any order. {...string}: The component names to match entities with. This checks if the entity has ALL of the specified components, but does not check for additional components. {Function}: The callback to call for each matched entity. Takes (entity.data, entity). Entity data is an object of {[componentName]: [component]}, that can be destructured with syntax shown in the examples. |
Example:
// Use a callback to process entities one-by-one
// This is the recommended way, as it is higher performance than allocating and
// returning an array
world.each('comp', ({ comp }) => { comp.value = 0 })
// Get an array of entities
const entities = world.each('comp')
for (const entity of entities) {...}
// Pass multiple components, arrays, use extra entity parameter,
// and destructure components outside the query
world.each('compA', ['more', 'comps'], 'compB', ({ entity, compA, compC }) => {
if (compC) compC.foo(compC.bar)
compA.foo = 'bar'
entity.remove('compB')
})
public run(args: ...Object) source
Calls run() on all systems. These methods can return true to cause an additional rerun of all systems. Reruns will not receive the args passed into run(), as a way to identify reruns.
Params:
Name | Type | Attribute | Description |
args | ...Object |
|
The arguments to forward to the systems' methods |
Example:
world.run(deltaTime)
// Example flow of method call order:
// Setup systems:
world.system(systemA)
world.system(systemB)
// During world.run():
// systemA.run()
// systemB.run()
public system(systemClass: Function, args: ...Object) source
Registers a system to the world. The order the systems get registered, is the order then run in.
Params:
Name | Type | Attribute | Description |
systemClass | Function | The system class to instantiate. Can contain a constructor(), init(), run(), or any other custom methods/properties. |
|
args | ...Object |
|
The arguments to forward to the system's constructor and init. Note that it is recommended to use init if using context, see world.context. Passing args here is still useful, because it can be specific to each system, where the same context is passed to all systems. |
Example:
// Movement system (basic example)
class MovementSystem {
run(dt) {
world.each('position', 'velocity', ({ position, velocity }) => {
position.x += velocity.x * dt
position.y += velocity.y * dt
})
}
}
// Input system (advanced example)
class InputSystem {
init(key) {
// Have access to this.keyboard here, but not in constructor
this.key = key
}
run(dt) {
if (this.keyboard.isPressed(this.key)) {
world.each('controlled', 'velocity', ({ velocity }, entity) => {
// Start moving all controlled entities to the right
velocity.x = 1
velocity.y = 0
// Can also use the full entity here, in this case to add a new component
entity.set('useFuel')
})
}
}
}
// Inject context (see world.context)
world.context = { keyboard: new Keyboard() }
// Register systems in order (this method)
world.system(InputSystem, 'w') // pass arguments to init/constructor
world.system(MovementSystem)
// Run systems (can get dt or frame time)
world.run(1000.0 / 60.0)