diff options
author | the lemons <citrons@mondecitronne.com> | 2022-12-21 15:46:30 -0600 |
---|---|---|
committer | the lemons <citrons@mondecitronne.com> | 2022-12-21 17:45:51 -0600 |
commit | a06622361d858c4d9c78c15323fc0d0e17e94110 (patch) | |
tree | 52aa25c53874a4c597cf0cab0824c9ed9ccb7bcb | |
parent | 619c46c37731df55bd2f50b7bb126c016734796e (diff) |
collision detection and correction
-rw-r--r-- | main.lua | 4 | ||||
-rw-r--r-- | obj.lua | 40 | ||||
-rw-r--r-- | objects/test.lua | 2 | ||||
-rw-r--r-- | world.lua | 2 |
4 files changed, 39 insertions, 9 deletions
@@ -68,7 +68,9 @@ function love.draw() end end -- draw all possibly visible objects - for o in world.iterate(cx1 - 20, cy1 - 20, cx2 + 20, cy2 + 20) do + for o in world.in_box( + cx1 - obj.max_size, cy1 - obj.max_size, + cx2 + obj.max_size, cy2 + obj.max_size) do set_color(1, 1, 1) o:draw() end @@ -29,7 +29,6 @@ function obj.load(id, data) o:init() return o end - function obj.is_obj(v) return getmetatable(v) == obj end @@ -48,6 +47,13 @@ function obj:overload(m, ...) end end +function obj:init(...) + self.chunk = world.chunk(unpack(self.data.pos)) + self.chunk.objects[self.id] = self + world.objects[self.id] = self + return self:overload("init", ...) +end + function obj:tick(...) if self.data.vel then local vx, vy = unpack(self.data.vel) @@ -57,7 +63,32 @@ function obj:tick(...) if self.data.avel then self.data.angle = (self.data.angle or 0) + self.data.avel / pi end + + if self.hitbox then + local x, y = unpack(self.data.pos) + for o in world.in_box( + x - obj.max_size, y - obj.max_size, + x + obj.max_size, y + obj.max_size) do + if o.hitbox and o ~= self then + local dist = o.hitbox + self.hitbox + local ox, oy = unpack(o.data.pos) + local dx, dy = ox - x, oy - y + if dx*dx + dy*dy < dist*dist then + local angle = math.atan2(dy, dx) + -- reposition self outside of collided object + self.data.pos[1] = + self.data.pos[1] - math.cos(angle) * dist + dx + self.data.pos[2] = + self.data.pos[2] - math.sin(angle) * dist + dy + self:collision(o, angle) + o:collision(self, pi - angle) + end + end + end + end + self:overload("tick", ...) + local chunk = world.chunk(unpack(self.data.pos)) if chunk ~= self.chunk then self.chunk.objects[self.id] = nil @@ -76,11 +107,8 @@ function obj:draw(...) love.graphics.pop() end -function obj:init(...) - self.chunk = world.chunk(unpack(self.data.pos)) - self.chunk.objects[self.id] = self - world.objects[self.id] = self - return self:overload("init", ...) +function obj:collision(collided) + return self:overload("collision", collided) end function obj:remove() diff --git a/objects/test.lua b/objects/test.lua index d8c1a65..9d72b29 100644 --- a/objects/test.lua +++ b/objects/test.lua @@ -1,4 +1,4 @@ -local test = {radius = 4} +local test = {hitbox = 4} function test:draw() line(-4, 4, 0, -4, 4, 4, -4, 4) @@ -43,7 +43,7 @@ function world.all() end) end -function world.iterate(x1, y1, x2, y2) +function world.in_box(x1, y1, x2, y2) return coroutine.wrap(function() for x = x1, x2 + world.chunk_size, world.chunk_size do for y = y1, y2 + world.chunk_size, world.chunk_size do |