summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthe lemons <citrons@mondecitronne.com>2022-12-21 15:46:30 -0600
committerthe lemons <citrons@mondecitronne.com>2022-12-21 17:45:51 -0600
commita06622361d858c4d9c78c15323fc0d0e17e94110 (patch)
tree52aa25c53874a4c597cf0cab0824c9ed9ccb7bcb
parent619c46c37731df55bd2f50b7bb126c016734796e (diff)
collision detection and correction
-rw-r--r--main.lua4
-rw-r--r--obj.lua40
-rw-r--r--objects/test.lua2
-rw-r--r--world.lua2
4 files changed, 39 insertions, 9 deletions
diff --git a/main.lua b/main.lua
index ebef333..392fa05 100644
--- a/main.lua
+++ b/main.lua
@@ -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
diff --git a/obj.lua b/obj.lua
index 5f35755..59a68d5 100644
--- a/obj.lua
+++ b/obj.lua
@@ -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)
diff --git a/world.lua b/world.lua
index c153a70..0607225 100644
--- a/world.lua
+++ b/world.lua
@@ -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