Git Product home page Git Product logo

coisa's Introduction

Cöisa

Implementation of a Entity Component System for the LÖVE framework, with some other features to speed up game development. "Coisa", meaning "thing" in portuguese, is the name it's used to refer to an entity.

Example

This example shows the simplest usage of Coisa, just adding a texture on the screen with the built-in components Position and Sprite:

require("lib.coisa.coisaCore")

function love.load()
    testScene = Scene("testScene")    -- Creates the scene "testScene"
    cCore.loadScene(testScene)        -- Loads the scene

    tile = Coisa(                     -- Creates a new coisa
        Position(200, 140),           -- At position [200,140]
        Sprite(R.texture.tile)        -- With the texture resource tile.png
end

-- forward update and draw callbacks to coisa
function love.update(dt)
    cCore.update(dt)
end
function love.draw()
    cCore.draw()
end

###Structure

Structure

CoisaCore manages everything. It keeps one scene loaded at a time, which can be a menu, loading screen, game level, etc. A Scene maintains a list of Coisas, which are game entities, and a Coisa maintains a list of Components. Everything in the game is a Coisa, the player, the enemy, walls, ground, etc. Each coisa is defined by its components, for example, a wall has a position, a texture and can't let things pass through it. For that, it needs to have the components Position, Sprite and BoxCollider. But components aren't directly responsible for these behaviors , they only store information. Acting on this information is the role of Scripts, they're the ones to manipulate Coisas. For example, the Renderer script is interested with Coisas with the Sprite component. It reads the texture info stored on the component and renders it on the screen.

A player however can be more complex:

  • It can have an animation when moving. The Animation component stores info about the animation itself, while the Animator script changes the sprite so the animation flows
  • It needs to be controlled, so a component can store stuff like his speed while a script updates its position
  • The player needs to control it via inputs, another component, another script, and so on..

Other stuff in the game will need different behavior, so this system makes it easy to create new components and scripts, which will be explained in more detail in a bit.

coisaCore

It's the system's core. It keeps track of all the scenes and scripts created, loads scenes, creates coisas in the currently loaded scene and makes the connections between components and scripts interested in said components.

cCore.loadScene(s) Load the scene s. All scripts and coisas are reseted.

  • s: The scene to be loaded (table)

cCore.update(dt) Needs to be called on update, necessary for the system to function.

  • dt: deltaTime, the time elapsed between frames

cCore.draw() Needs to be called on draw, necessary for the system to function.

Scene

Used to manage the game state. It holds a list of coisas. It can also hold game logic specific for a scene.

Scene(name) Creates a new scene and registers it on coisaCore

  • name: name of the new scene (string)

Returns a table with the new scene

Supported callbacks:

:init() Called once when the scene is first loaded

:enter() Called every time a scene is loaded

:exit() Called every time the scene is unloaded

:draw() Same as love.draw()

:update(dt) Same as love.update(dt)

:lateUpdate(dt) Called every frame after all the scripts ran their update()

Coisa

A game entity which holds components.

Coisa(...components) Creates a new coisa in the current scene ...components: any number of components for the coisa to be initialized with Returns a table of the created coisa

:addComponent(component)

:removeComponent(component)

:destroy()

Component

Defines what the coisa is, holds information that will be used by scripts

Component(handle, properties) Creates a new component handle: component identifier, will be used to access the component in a Coisa properties: Table of properties that the component can hold

Example:

Character = Component("char", {    -- Creates a new component Character
    speed = 10,                    -- with properties speed and jumpHeight
    jumpHeight = 3                 -- with default values 10 and 3
})

-- Create a coisa with the created component 
player = Coisa("player", Character({ speed = 20 }))    

-- Modify a value in the component utilizing it's handle 'char' 
player.char.jumpHeight = 4

Script

Holds the game logic. A script acts upon Coisas with specific components, which are specified when creating the script. CoisaCore handles connecting scripts with relevant Coisas, so the script itself can contain only game logic.

Script(requirements) Creates a new script and register it on cCore. requirements: Table with components required by this script

Callbacks: :init(c) Called when a new coisa c is created

:updateOnce(dt) Called once every update, unrelated to registered coisas

:update(c, dt) Called every update for every registered coisa c

:lateUpdateOnce(dt) Called once every update, unrelated to registered coisas, after all update calls are done

:lateUpdate(c, dt) Called every update for every registered coisa c, after all update calls are done

:draw(c) Called every draw for every registered coisa c

:drawBefore() Called once every draw before calling draw for every coisa

:drawAfter() Called once every draw after calling draw for every coisa

:onRemoval(c) Called when unregistering a coisa from this script, either because it was destroyed or one of the required components was removed

Example:

-- A simple renderer
Renderer = Script({ Sprite, Position })    -- We can only render a coisa if it has a Sprite component

function Renderer:draw(c)
    love.graphics.setColor(c.sprite.color:value())
    love.graphics.draw(c.sprite.texture, c.pos.x, c.pos.y)
end

Extra features

The ECS system is already explained. The features described next are general utilities for making games with it.

ResourceManager

Its role is to end the problem with redundancy when dealing with resources. For example, if the same texture is used in two different parts fo the game, each part will create its own Image resource from the texture, since they don't know about each other. What ResourceManager does is maintain a table with all the game's resources. By using ResourceMgr.get, you will make sure that a resource will be reused if possible or created if it doesn't exist yet. For syntax sugar, it's also possible to get resources by using ResourceManager.[type].[name] instead of ResourceManager.get([type], [name]), for example R.texture.bullet instead of R.get("texture", "bullet").

ResourceManager.get(type, name) Returns the resource name of type type, either a cached one or a new one

ResourceManager.add(type, name) Adds the resource name of type type if it doesn't already exist.

Supported types: texture: A image resource. It tries to find the file in the folder indicated by ResourceManager.textureFolder, which is textures by default.

animSheet: Lua file with animations info.
Structure:

->animSheet.lua
return {
    {
        name = "name",
    	texture = [spritesheet],
    	size = [amount of frames],
    	timestep = [time in seconds between frames],
    	loop = [boolean, if should return to start after ending],
    	tilewidth = [quad's width],
    	tileheight = [quad's height],
    	frames = {
    		{quad = love.graphics.newQuad(...)},
    		...
    	}
    },
    ...
}

anim: Animation created by loading a animSheet file.

scene: Lua file that returns a Scene. ResourceManager will try to find it in the folder indicated by ResourceManager.sceneFolder, which is scenes by default.

coisa's People

Contributors

raquelhl avatar luizcarlos1405 avatar

Watchers

 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.