GithubHelp home page GithubHelp logo

rickwong / encosy Goto Github PK

View Code? Open in Web Editor NEW

This project forked from cyclonic-games/encosy

0.0 3.0 0.0 76 KB

Lightweight Entity/ Component/ System implementation in JavaScript

License: MIT License

JavaScript 100.00%

encosy's Introduction

     ______/           ______/           ______/
    /                 /                 /
   _____/   ____  /  /         ____  / ____  /  /      /
  /        /     /  /         /     /       /  /      /
_______/ _/    _/ ________/ _______/ ______/ ______  /
                                                    /
          (c) 2018 Cyclonic Games             _____/

Lightweight Entity/ Component/ System implementation in JavaScript

// Installation

npm install cyclone-games/encosy --save

// Introduction

Entity/ Component/ System architectures are an alternative to OOP for game development. The main idea is to help prevent having massive hierarchal trees of inheritance when dealing with game entities.

Entities

Entities are essentially just a unique identifier that components can reference in order to, as a group, describe an 'object'.

Components

Components are strictly data. They contain properties that systems can act upon.

Systems

Systems are where your actual logic lives. They validate whether or not an entity contains all of the required components, and then acts accordingly.

// Usage

The API is very lightweight and simple to use

Component

new Component(String, Object<String, Function>)

The Component class is used to define the data model for a component. The available types are as follows:

Example (~/components/position.js)

import { Component } from 'encosy';

export default new Component('position', {
    x: Number,
    y: Number
});

If you need to dynamically add to a component's model, you may extend it:

import position from '~/components/position';

position.extend({
    z: Number
});

Entity

new Entity(String, Array<Component>)

The Entity class is a factory that accepts a dictionary of an accessor string, and a component class, It's what creates the unique ID that is the entity, and creates a relationship between it and components.

Example (~/entities/character.js)

import { Entity } from 'encosy';
import position from '~/components/position';
import sprite from '~/components/sprite';

export default new Entity('character', [
    position,
    sprite
]);

Then, to create a character, you would do:

import character from '~/entities/character';

const char = character.create({
    position: {
        x: 0,
        y: 0
    },
    sprite: { ... }
});

If you need to dynamically add components to an entity, you can extend it:

import character from '~/entities/character';
import health from '~/components/health';

character.extend([
    health
]);

If you'd like to then delete a character, which would then also allow its components to be garbage collected (if you have no other strong references), you would do:

character.destroy(char)

System

new System(String, Array<Component>, Function)

The System class is used to define the actual logic that brings the components of an entity together. The first argument is an array containing the required components that an entity must have in order for the system to act upon it. The second argument is a callback that is the actual system's code. It should accept the world and a single entity.

Example (~/systems/render.js)

import { System } from 'encosy';
import position from '~/components/position';
import sprite from '~/components/sprite';

export default new System('render', [ position, sprite ], entity => {
    const { x, y } = position.of(entity);
    const { data } = sprite.of(entity);

    // render character using data from components...
});

As you can see, to get a position of an entity, you would use the of method. This works similarly in concept to reflection, though it's not totally the same thing.

Then, to run the render system, you would call its run method:

import character from '~/entities/character';
import render from '~/systems/render';

character.forEach(char => render.run(char));

If you'd like to dynamically add more code to a system, you can extend it:

import render from '~/systems/render';

render.extend(entity => {
    // do more to the entity
});

encosy's People

Contributors

timvanscherpenzeel avatar

Watchers

 avatar  avatar  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.