Advertisement
Guest User

ecs

a guest
Nov 13th, 2016
240
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.51 KB | None | 0 0
  1. --- Just a template for component
  2. function Component_Empty()
  3.     local self = {
  4.         name = "put_unique_name"
  5.         -- properties ...
  6.         }
  7.     return self
  8. end
  9.  
  10. function Component_Position(_x, _y)
  11.     local self = { 
  12.         name = "position",
  13.         x = _x or 0,
  14.         y = _y or 0 }
  15.     return self
  16. end
  17.  
  18. function Component_Velocity(_vx, _vy)
  19.     local s = {
  20.         name = "velocity",
  21.         vx = _vx or 0,
  22.         vy = _vy or 0 }
  23.     return s
  24. end
  25.  
  26. -- Systems --
  27.  
  28. Systems = {}
  29.  
  30. -- This is not a template! Custom systems must be inherited from this class
  31. function Systems.Base()
  32.     local self = {}
  33.     self.name = "base"
  34.     local subscribers = {}
  35.     local entities = {}
  36.    
  37.     function self.subscribe(entity)
  38.         table.insert(subscribers, entity)
  39.     end
  40.    
  41.     function self.set_entities(_entities)
  42.         entities = _entities
  43.     end
  44.    
  45.     function self.get_entities()
  46.         return {entities, subscribers}
  47.     end
  48.    
  49.     return self
  50. end
  51.  
  52. function Systems.Moving()
  53.     local self = Systems.Base()
  54.     self.name = "moving"
  55.    
  56.     function self.update(dt)
  57.         local entities = self.get_entities()
  58.         for i, e in iter_select(entities) do
  59.             local p = e.position
  60.             local v = e.velocity
  61.             p.x = p.x + v.vx * dt
  62.             p.y = p.y + v.vy * dt
  63.         end
  64.     end
  65.    
  66.     return self
  67. end
  68.  
  69. function Systems.Handling()
  70.     local self = Systems.Base()
  71.     self.name = "handling"
  72.    
  73.     function self.update(dt)
  74.         local entities = self.get_entities()
  75.         for i, e in iter_select(entities) do
  76.             local v = e.velocity
  77.             v.vx, v.vy = 0, 0
  78.             if      love.keyboard.isDown("up")      then v.vy = -100
  79.             elseif  love.keyboard.isDown("down")    then v.vy = 100
  80.             end
  81.             if      love.keyboard.isDown("right")   then v.vx = 100
  82.             elseif  love.keyboard.isDown("left")    then v.vx = -100
  83.             end
  84.         end
  85.     end
  86.    
  87.     return self
  88. end
  89.  
  90. function Systems.Drawing()
  91.     local self = Systems.Base()
  92.     self.name = "drawing"
  93.    
  94.     function self.draw()
  95.         local entities = self.get_entities()
  96.         for i, e in iter_select(entities) do
  97.             local p = e.position
  98.             love.graphics.circle("fill", p.x, p.y, 10)
  99.         end
  100.     end
  101.    
  102.     return self
  103. end
  104.  
  105. function SystemManager()
  106.     local self = {}
  107.     local systems = {}
  108.     local entities = {}
  109.    
  110.     -- registering systems
  111.     for i, s in pairs(Systems) do
  112.         local sys = s()
  113.         sys.set_entities(entities)
  114.         systems[sys.name] = sys
  115.     end
  116.    
  117.     function self.newEntity()
  118.         table.insert(entities, {})
  119.         return #entities
  120.     end
  121.    
  122.     function self.addComponent(entity, component)
  123.         entities[entity][component.name] = component
  124.     end
  125.    
  126.     function self.subscribe(entity, system)
  127.         local sys = systems[system]
  128.         sys.subscribe(entity)
  129.     end
  130.    
  131.     function self.update(dt)
  132.         for k, system in pairs(systems) do
  133.             local upd = system.update
  134.             if upd then upd(dt) end
  135.         end
  136.     end
  137.    
  138.     function self.draw()
  139.         for k, system in pairs(systems) do
  140.             local drw = system.draw
  141.             if drw then drw(dt) end
  142.         end
  143.     end
  144.    
  145.     return self
  146. end
  147.  
  148. --- Assembling custom entity
  149. function create_player(x, y, vx, vy)
  150.     local entity = ecs.newEntity()
  151.     ecs.addComponent(entity, Component_Position(x, y))
  152.     ecs.addComponent(entity, Component_Velocity(vx, vy))
  153.     ecs.subscribe(entity, "moving")
  154.     ecs.subscribe(entity, "handling")
  155.     ecs.subscribe(entity, "drawing")
  156.     return entity
  157. end
  158.  
  159. function create_moving_dot(x, y, vx, vy)
  160.     local entity = ecs.newEntity()
  161.     ecs.addComponent(entity, Component_Position(x, y))
  162.     ecs.addComponent(entity, Component_Velocity(vx, vy))
  163.     ecs.subscribe(entity, "moving")
  164.     ecs.subscribe(entity, "drawing")
  165.     return entity
  166. end
  167.  
  168. function create_static_dot(x, y)
  169.     local entity = ecs.newEntity()
  170.     ecs.addComponent(entity, Component_Position(x, y))
  171.     ecs.subscribe(entity, "drawing")
  172.     return entity
  173. end
  174.  
  175. -- Main --
  176. -- testing ECS framework
  177.  
  178. --- Iterator for iterating _objects_ only with selected _indexes_
  179. -- Function takes two tables: objects and indexes
  180. -- Tables can be passed in one table
  181. function iter_select(...)
  182.     local i = 0
  183.     local arg = {...}
  184.     local objects, indexes
  185.    
  186.     if #arg == 2 then
  187.         objects, indexes = arg[1], arg[2]
  188.     elseif #arg[1] == 2 then
  189.         objects, indexes = arg[1][1], arg[1][2]
  190.     end
  191.    
  192.     -- "next" element function
  193.     return function ()
  194.         local v, index = {}, nil
  195.         i, index = next(indexes, i)
  196.         while index do
  197.             v = objects[index]         
  198.             if v then
  199.                 return index, v, nil
  200.             end
  201.             i, index = next(indexes, i)
  202.         end
  203.         return index, v, nil
  204.     end
  205. end
  206.  
  207. function love.load()
  208.     ecs = SystemManager()
  209.     e1 = create_player(400, 300)
  210.     create_player(100, 100)
  211.     create_moving_dot(200, 100, 50, 0)
  212.     create_static_dot(500, 400)
  213. end
  214.  
  215. function love.update(dt)
  216.     ecs.update(dt)
  217. end
  218.  
  219. function love.draw()
  220.     ecs.draw()
  221. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement