summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthe lemons <citrons@mondecitronne.com>2022-12-19 18:28:46 -0600
committerthe lemons <citrons@mondecitronne.com>2022-12-19 18:28:46 -0600
commit94f7fc0d3e410a7c7dc6f6cffe0ed87238608391 (patch)
tree805c7a90ed1adf9bf358868f19ef1e9a072b791d
parentba1b317b3b4de92d7f39dceb988a41840e4fc942 (diff)
world made of chunks with objects in them
-rw-r--r--main.lua24
-rw-r--r--obj.lua79
-rw-r--r--objects/test.lua17
-rw-r--r--util.lua30
-rw-r--r--world.lua39
5 files changed, 186 insertions, 3 deletions
diff --git a/main.lua b/main.lua
index 4e62c23..970a0fb 100644
--- a/main.lua
+++ b/main.lua
@@ -1,3 +1,10 @@
+local world = require "world"
+local obj = require "obj"
+
+obj.load_types()
+line = love.graphics.line
+set_color = love.graphics.setColor
+love.graphics.setLineWidth(0.5)
local cam = {
x = 0, y = 0,
@@ -5,6 +12,10 @@ local cam = {
panning = false,
}
+for i = 1, 100 do
+ obj.new("test", {math.random(1000), math.random(1000)})
+end
+
local function view_scale()
local w, h = love.graphics.getDimensions()
return cam.scale / math.min(w, h)
@@ -17,12 +28,19 @@ local function view_transform()
return trans
end
-
function love.draw()
love.graphics.clear(0,0,0)
love.graphics.applyTransform(view_transform())
- love.graphics.setColor(1, 1, 1)
- love.graphics.ellipse("fill", 10, 10, 1, 1)
+ for _, o in pairs(world.objects) do
+ love.graphics.setColor(1, 1, 1)
+ o:draw()
+ end
+end
+
+function love.update()
+ for _, o in pairs(world.objects) do
+ o:tick()
+ end
end
function love.mousepressed(_, _, button)
diff --git a/obj.lua b/obj.lua
new file mode 100644
index 0000000..adb9a3a
--- /dev/null
+++ b/obj.lua
@@ -0,0 +1,79 @@
+local world = require "world"
+
+local obj = {}
+
+local types = {}
+function obj.load_types()
+ for _, f in ipairs(love.filesystem.getDirectoryItems "objects") do
+ local ts = assert(love.filesystem.load("objects/"..f))()
+ for t, v in pairs(ts) do
+ types[t] = v
+ end
+ end
+end
+
+function obj.new(type, pos, ...)
+ world.last_id = world.last_id + 1
+ local o = setmetatable(
+ {id = world.last_id, data = {pos = pos}, type = type}, obj)
+ o:init(...)
+ return o
+end
+
+function obj.load(id, data)
+ local o = setmetatable({id = id, data = data, type = data.type}, obj)
+ o:init()
+ return o
+end
+
+function obj.is_obj(v)
+ return getmetatable(v) == obj
+end
+
+function obj:__index(v)
+ if obj[v] then
+ return obj[v]
+ else
+ return types[rawget(self, "type")][v]
+ end
+end
+
+function obj:overload(m, ...)
+ if types[self.type][m] then
+ return types[self.type][m](self, ...)
+ end
+end
+
+function obj:tick(...)
+ local chunk = world.chunk(unpack(self.data.pos))
+ if chunk ~= self.chunk then
+ self.chunk.objects[self.id] = nil
+ chunk.objects[self.id] = self
+ self.chunk = chunk
+ end
+ return self:overload("tick", ...)
+end
+
+function obj:draw(...)
+ love.graphics.push()
+ love.graphics.translate(unpack(self.data.pos))
+ if self.data.angle then
+ love.graphics.rotate(self.data.angle)
+ end
+ self:overload("draw", ...)
+ love.graphics.pop()
+end
+
+function obj:init(...)
+ self.chunk = world.chunk(unpack(self.data.pos))
+ world.objects[self.id] = self
+ return self:overload("init", ...)
+end
+
+function obj:unload()
+ self.chunk.objects[self.id] = nil
+ world.objects[self.id] = nil
+ return self:overload "unload"
+end
+
+return obj
diff --git a/objects/test.lua b/objects/test.lua
new file mode 100644
index 0000000..5c2cb1b
--- /dev/null
+++ b/objects/test.lua
@@ -0,0 +1,17 @@
+local test = {}
+
+function test:draw()
+ line(-4, 4, 0, -4, 4, 4, -4, 4)
+ set_color(1, 0.6, 0.7)
+ line(4, -4, 0, 4, -4, -4, 4, -4)
+end
+
+function test:init()
+ self.data.angle = math.random() * math.pi
+end
+
+function test:tick()
+ self.data.angle = self.data.angle + 0.1
+end
+
+return {test = test}
diff --git a/util.lua b/util.lua
new file mode 100644
index 0000000..a639ca2
--- /dev/null
+++ b/util.lua
@@ -0,0 +1,30 @@
+
+local M = {}
+
+function M.copy(t)
+ local c = {}
+ for k,v in pairs(t) do
+ c[k] = v
+ end
+ return c
+end
+
+function M.deepcopy(t)
+ local copied = {}
+ local function dc(t)
+ if not copied[t] then
+ local c = {}
+ copied[t] = c
+ for k,v in pairs(t) do
+ if type(v) == 'table' then
+ v = dc(v)
+ end
+ c[k] = v
+ end
+ end
+ return copied[t]
+ end
+ return dc(t)
+end
+
+return M
diff --git a/world.lua b/world.lua
new file mode 100644
index 0000000..f4fcb70
--- /dev/null
+++ b/world.lua
@@ -0,0 +1,39 @@
+local world = {}
+
+local chunk_size = 1024
+
+world.chunks = {}
+setmetatable(world.chunks, {
+ __index = function(_, bee)
+ if rawget(world.chunks, bee) == nil then
+ world.chunks[bee] = {}
+ end
+ return world.chunks[bee]
+ end,
+})
+world.objects = {}
+world.last_id = 0
+
+function world.chunk_pos(x, y)
+ return math.floor(x / chunk_size), math.floor(y / chunk_size)
+end
+
+function world.world_pos(x, y)
+ return x * chunk_size, y * chunk_size
+end
+
+function world.chunk(x, y)
+ local cx, cy = world.chunk_pos(x, y)
+ if not world.chunks[cx][cy] then
+ -- load chunk from disk if the
+ world.chunks[cx][cy] = setmetatable(
+ {pos = {cx, cy}, objects = {}}, chunk)
+ end
+ return world.chunks[cx][cy]
+end
+
+function world.get_object(id)
+end
+
+world.__index = world
+return world