-
Notifications
You must be signed in to change notification settings - Fork 0
/
collisions.lua
126 lines (103 loc) · 3.13 KB
/
collisions.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
local QuadTree = require "quad_tree"
local Collisions = {}
local Collisions_mt = {}
Collisions_mt.__index = Collisions
function Collisions.new(x, y, w, h)
return setmetatable(
{
x = x,
y = y,
w = w,
h = h,
entities = {},
staticColliders = {},
quadtree = QuadTree.new(x,y,w,h, 0, {1,1,1})
}, Collisions_mt)
end
function Collisions:addCollider(x,y,w,h)
self.staticColliders[#self.staticColliders + 1] = {
x = x,
y = y,
w = w,
h = h,
}
end
function Collisions:setEntityTable(table)
self.entities = table
end
function Collisions:add(e)
self.entities[e] = e
end
function Collisions:remove(e)
self.entities[e] = nil
end
function Collisions:collisionCheck(e, func)
self.quadtree:collisionCheck(e, func)
end
function Collisions:collisionResolve(item, other)
local abs = math.abs
-- Returns 1 if number is positive, -1 if it's negative, or 0 if it's 0.
local function sign(n) return n>0 and 1 or n<0 and -1 or 0 end
local function nearest(x, a, b)
if abs(a - x) < abs(b - x) then return a else return b end
end
local function rect_getNearestCorner(x,y,w,h, px, py)
return nearest(px, x, x+w), nearest(py, y, y+h)
end
-- Calculates the minkowski difference between 2 rects, which is another rect
local function rect_getDiff(x1,y1,w1,h1, x2,y2,w2,h2)
return x2 - x1 - w1,
y2 - y1 - h1,
w1 + w2,
h1 + h2
end
local x,y,w,h = rect_getDiff(item.x,item.y,item.w,item.h, other.x,other.y,other.w,other.h)
local px, py = rect_getNearestCorner(x,y,w,h, 0, 0)
if abs(px) < abs(py) then py = 0 else px = 0 end
local tx, ty = item.x + px, item.y + py
return tx, ty, sign(px), sign(py)
end
function Collisions:update(dt)
self.quadtree:clear()
for _,e in ipairs(self.staticColliders) do
self.quadtree:insert(e)
end
for _,e in ipairs(self.entities) do
self.quadtree:insert(e)
end
for _,e in pairs(self.entities) do
e.marked = nil
local func = function(item, other)
item.marked = true
--other.marked = true
item.x, item.y = collisionWorld:collisionResolve(item, other)
end
collisionWorld:collisionCheck(e, e.collisionPreSolve or func)
end
end
local function drawChildren(quad)
--print(#quad.objects)
love.graphics.rectangle("line", quad.x, quad.y, quad.w, quad.h)
if not quad.children then return end
for k,v in ipairs(quad.children) do
drawChildren(v)
end
end
function Collisions:draw()
drawChildren(self.quadtree)
for _,e in ipairs(self.staticColliders) do
love.graphics.rectangle("line", e.x, e.y, e.w, e.h)
end
for _,e in pairs(self.entities) do
if e.quad and e.quad.color then
love.graphics.setColor(e.quad.color)
end
local mode = "line"
if e.marked then
mode = "fill"
end
love.graphics.rectangle(mode, e.x, e.y, e.w, e.h)
love.graphics.setColor(1,1,1,1)
end
end
return Collisions