GithubHelp home page GithubHelp logo

lajohnston / eco Goto Github PK

View Code? Open in Web Editor NEW
5.0 1.0 0.0 231 KB

Entity Component System for JavaScript/HTML5 games

License: MIT License

JavaScript 100.00%
game entity html5-games javascript ecs-pattern entity-component

eco's Introduction

Eco ECS (Entity Component System)

Eco is a lightweight, optimised, entity container for JavaScript/HTML5 games. It can be used within a custom game engine, or as a glue layer to keep your game logic decoupled from the game framework and libraries of your choice.

Overview of the ECS pattern

As an alternative to defining hierarchical types for in-game entities (such as "Player", "Enemy", "FlyingEnemy", "FlyingEnemyWithGun" ...), the ECS pattern has you split the aspects into components (position, movement, canFly, hasGun) then mix and match them. This allows you to assemble many variations using the same component parts, and even allows components to be added or removed to change entity behaviour at runtime.

  • Components - data structures (position, movement, appearance etc.)
  • Entities - containers that hold components; represent in-game objects
  • Systems - logic that updates entities based on their component set

Basic usage

// Create an Eco instance, specifying a list of component names
const eco = Eco.create(["position", "movement"]);

// Create an entity. Add components using dot notation
const entity = eco.entity();
entity.position = { x: 100, y: 200 };
entity.movement = { x: 1, y: 0, speed: 2 };

// Create an iterator for entities with position && movement components.
const moveable = eco.iterator(["position", "movement"]);

// Your update function in the main loop
function update(delta) {
  moveable.forEach(entity => {
    // Add movement to position
    entity.position.x += entity.movement.x * entity.movement.speed * delta;
    entity.position.y += entity.movement.y * entity.movement.speed * delta;
  });
}

Entities

// Create an empty entity
const eco = Eco.create(["position"]);
const entity = eco.entity();

// Add or replace components using standard dot notation
entity.position = { x: 100, y: 200 };
entity.position.x; // 100
entity.position.y; // 200
entity.has("position"); // true

// Remove a component
entity.position = undefined;
entity.position; // undefined
entity.has("position"); // false

// Remove all components from an entity
entity.removeAll();

You can add custom methods to the Entity class by extending it.

// Create and edit a custom Eco dependency container
const myEco = Eco.container();

// Extend the Entity class and add your own methods
myEco.Entity = class extends myEco.Entity {
  getFoo() {
    return this.foo;
  }
};

// Create an eco instance then use it as normal
const eco = myEco.create(["foo"]);
const entity = eco.entity(); // will be an instance of your entity class

Iterators

Iterators iterate over a subset of entities, similar to using Array.filter and Array.forEach. They utilise caching to ensure the filtering step is only performed when a relevant change has occurred.

// Filter only entities which have foo AND bar components
const fooBar = eco.iterator(["foo", "bar"]);

fooBar.forEach(entity => {
  entity.has("foo"); // true
  entity.has("bar"); // true
});

/**
 * An optional second parameter lets you specify a custom filter function. You
 * must still provide the array of components as the first argument as this is
 * used by the caching system to determine what changes are relevant to it
 */
const fooNoBar = eco.iterator(
  ["foo", "bar"], // relevant components
  entity => entity.has("foo") && !entity.has("bar")
);

fooNoBar.forEach(entity => {
  entity.has("foo"); // true
  entity.has("bar"); // false
});

Callbacks

Eco provides a basic callback system that is called each time a component value is set. An example use-case is if you're using a collision algorithm such as a QuadTree or Grid, and wish to update it when an entity position changes.

// Set the eco.onChange function
eco.onChange = (entity, componentName, newValue, oldValue) => {
  // this will be called whenever a component value is set
};

// Setting a component value will trigger the callback
entity.foo = "bar"; // oldValue = undefined; newValue = "bar"
entity.foo = undefined; // oldValue = "bar"; newValue = undefined

// Eco does not perform deep change detection, so the following won't trigger
// the callback
entity.position.x = 100; // will not trigger eco.onChange
entity.position = entity.position; // you'd have to do this to manually trigger

For deep change detection, you may consider read-only immutable components that return new instances of themselves when changed. The altered value will therefore have to be explicitly set back to the entity and this will trigger the onChange event.

Enable, Disable and Destroy Entities

Setting an entity's 'enabled' property to false allows you to deactivate it. This removes the entity from eco's entity list so it won't appear in any iterator results

Unless you're storing your own reference to the entity, it will eventually be garbage collected and permanently destroyed. If you do keep a reference then you can just set the enabled property back to true to re-enable it at a later time.

entity.enabled = false; // removes entity from eco
entity.enabled = true; // add entity back to eco

// You can still work with deactivated entities, but they won't invoke the
// eco.onChange callback. They operate as normal but in a detached state
entity.enabled = false;
entity.foo = "bar"; // will not invoke the eco.onChange method
entity.foo; // 'bar' - value is still set

eco's People

Contributors

lajohnston avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.