Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --- Just a template for component
- function Component_Empty()
- local self = {
- name = "put_unique_name"
- -- properties ...
- }
- return self
- end
- function Component_Position(_x, _y)
- local self = {
- name = "position",
- x = _x or 0,
- y = _y or 0 }
- return self
- end
- function Component_Velocity(_vx, _vy)
- local s = {
- name = "velocity",
- vx = _vx or 0,
- vy = _vy or 0 }
- return s
- end
- -- Systems --
- Systems = {}
- -- This is not a template! Custom systems must be inherited from this class
- function Systems.Base()
- local self = {}
- self.name = "base"
- local subscribers = {}
- local entities = {}
- function self.subscribe(entity)
- table.insert(subscribers, entity)
- end
- function self.set_entities(_entities)
- entities = _entities
- end
- function self.get_entities()
- return {entities, subscribers}
- end
- return self
- end
- function Systems.Moving()
- local self = Systems.Base()
- self.name = "moving"
- function self.update(dt)
- local entities = self.get_entities()
- for i, e in iter_select(entities) do
- local p = e.position
- local v = e.velocity
- p.x = p.x + v.vx * dt
- p.y = p.y + v.vy * dt
- end
- end
- return self
- end
- function Systems.Handling()
- local self = Systems.Base()
- self.name = "handling"
- function self.update(dt)
- local entities = self.get_entities()
- for i, e in iter_select(entities) do
- local v = e.velocity
- v.vx, v.vy = 0, 0
- if love.keyboard.isDown("up") then v.vy = -100
- elseif love.keyboard.isDown("down") then v.vy = 100
- end
- if love.keyboard.isDown("right") then v.vx = 100
- elseif love.keyboard.isDown("left") then v.vx = -100
- end
- end
- end
- return self
- end
- function Systems.Drawing()
- local self = Systems.Base()
- self.name = "drawing"
- function self.draw()
- local entities = self.get_entities()
- for i, e in iter_select(entities) do
- local p = e.position
- love.graphics.circle("fill", p.x, p.y, 10)
- end
- end
- return self
- end
- function SystemManager()
- local self = {}
- local systems = {}
- local entities = {}
- -- registering systems
- for i, s in pairs(Systems) do
- local sys = s()
- sys.set_entities(entities)
- systems[sys.name] = sys
- end
- function self.newEntity()
- table.insert(entities, {})
- return #entities
- end
- function self.addComponent(entity, component)
- entities[entity][component.name] = component
- end
- function self.subscribe(entity, system)
- local sys = systems[system]
- sys.subscribe(entity)
- end
- function self.update(dt)
- for k, system in pairs(systems) do
- local upd = system.update
- if upd then upd(dt) end
- end
- end
- function self.draw()
- for k, system in pairs(systems) do
- local drw = system.draw
- if drw then drw(dt) end
- end
- end
- return self
- end
- --- Assembling custom entity
- function create_player(x, y, vx, vy)
- local entity = ecs.newEntity()
- ecs.addComponent(entity, Component_Position(x, y))
- ecs.addComponent(entity, Component_Velocity(vx, vy))
- ecs.subscribe(entity, "moving")
- ecs.subscribe(entity, "handling")
- ecs.subscribe(entity, "drawing")
- return entity
- end
- function create_moving_dot(x, y, vx, vy)
- local entity = ecs.newEntity()
- ecs.addComponent(entity, Component_Position(x, y))
- ecs.addComponent(entity, Component_Velocity(vx, vy))
- ecs.subscribe(entity, "moving")
- ecs.subscribe(entity, "drawing")
- return entity
- end
- function create_static_dot(x, y)
- local entity = ecs.newEntity()
- ecs.addComponent(entity, Component_Position(x, y))
- ecs.subscribe(entity, "drawing")
- return entity
- end
- -- Main --
- -- testing ECS framework
- --- Iterator for iterating _objects_ only with selected _indexes_
- -- Function takes two tables: objects and indexes
- -- Tables can be passed in one table
- function iter_select(...)
- local i = 0
- local arg = {...}
- local objects, indexes
- if #arg == 2 then
- objects, indexes = arg[1], arg[2]
- elseif #arg[1] == 2 then
- objects, indexes = arg[1][1], arg[1][2]
- end
- -- "next" element function
- return function ()
- local v, index = {}, nil
- i, index = next(indexes, i)
- while index do
- v = objects[index]
- if v then
- return index, v, nil
- end
- i, index = next(indexes, i)
- end
- return index, v, nil
- end
- end
- function love.load()
- ecs = SystemManager()
- e1 = create_player(400, 300)
- create_player(100, 100)
- create_moving_dot(200, 100, 50, 0)
- create_static_dot(500, 400)
- end
- function love.update(dt)
- ecs.update(dt)
- end
- function love.draw()
- ecs.draw()
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement