Skip to content

Instantly share code, notes, and snippets.

@01010111
Last active March 9, 2019 11:46
Show Gist options
  • Save 01010111/6a610f00becebd6d35897f67b30c6e10 to your computer and use it in GitHub Desktop.
Save 01010111/6a610f00becebd6d35897f67b30c6e10 to your computer and use it in GitHub Desktop.
ECS in P8 ✨
pico-8 cartridge // http://www.pico-8.com
version 16
__lua__
--pecs - pico-8 ecs
--01010111
function _init()
local rect = get_id()
add_component(rect, 'position', { x=60, y=60 })
add_component(rect, 'physics', { vx=2, vy=0, ax=0, ay=2, dx=0.9, dy=1.0 })
add_component(rect, 'drawable', { w=8, h=8, c=3 })
end
function _update()
update_physics(get_entities_with_components({'position', 'physics'}))
end
function _draw()
cls()
draw_entities(get_entities_with_components({'drawable', 'position'}))
end
function update_physics(eids)
for e in all(eids) do
local phys = components['physics'][e]
local pos = components['position'][e]
phys.vx += phys.ax
phys.vy += phys.ay
phys.ax *= phys.dx
phys.ay *= phys.dy
pos.x += phys.vx
pos.y += phys.vy
if pos.x < 0 then phys.vx = abs(phys.vx) end
if pos.x > 128 then phys.vx = abs(phys.vx) * -1 end
if pos.y > 120 then phys.vy = -20 end
end
end
function draw_entities(eids)
for e in all(eids) do
local rend = components['drawable'][e]
local pos = components['position'][e]
rectfill(pos.x, pos.y, pos.x + rend.w, pos.y + rend.h, rend.c)
end
end
-->8
-- ecs framework
-- entities
next_id = 1
function get_id()
next_id += 1
return next_id - 1
end
-- components
components = {}
function add_component(e, cid, cdata)
if (components[cid] == null) then components[cid] = {} end
components[cid][e] = cdata
end
-- systems
function get_entities_with_component(id)
local eids = {}
local n = 0
for k,v in pairs(components[id]) do
n += 1
eids[n] = k
end
return eids
end
function get_entities_with_components(ids)
local eids = get_entities_with_component(ids[1])
if (#eids == 0) return {}
for id in all(ids) do
local teids = get_entities_with_component(id)
if (#teids == 0) return {}
eids = intersection(eids, teids)
end
return eids
end
-->8
-- utilities
-- table utils
function has_element(t, e)
for o in all(t) do if (o == e) then return true end end
return false
end
function intersection(t1, t2)
local i = {}
for e in all(t1) do if has_element(t2, e) then add(i, e) end end
return i
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment