diff options
author | the lemons <citrons@mondecitronne.com> | 2022-12-19 18:28:46 -0600 |
---|---|---|
committer | the lemons <citrons@mondecitronne.com> | 2022-12-19 18:28:46 -0600 |
commit | 94f7fc0d3e410a7c7dc6f6cffe0ed87238608391 (patch) | |
tree | 805c7a90ed1adf9bf358868f19ef1e9a072b791d | |
parent | ba1b317b3b4de92d7f39dceb988a41840e4fc942 (diff) |
world made of chunks with objects in them
-rw-r--r-- | main.lua | 24 | ||||
-rw-r--r-- | obj.lua | 79 | ||||
-rw-r--r-- | objects/test.lua | 17 | ||||
-rw-r--r-- | util.lua | 30 | ||||
-rw-r--r-- | world.lua | 39 |
5 files changed, 186 insertions, 3 deletions
@@ -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) @@ -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 |