-
Notifications
You must be signed in to change notification settings - Fork 1
/
collision.lua
77 lines (71 loc) · 2.06 KB
/
collision.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
-- A file holding the collision code. Checking circles and rects.
local collision = {}
function collision.makeRect(x, y, w, h)
local rect = {collision_type = "rectangle", x = x - w / 2, y = y - h / 2, width = w, height = h}
return rect
end
function collision.makeCircle(x, y, r)
local circle = {collision_type = "circle", x = x - r, y = y - r, radius = r}
return circle
end
function collision.moveTo(shape, x, y)
if shape.collision_type == "rectangle" then
shape.x = x - shape.width / 2
shape.y = y - shape.height / 2
elseif shape.collision_type == "circle" then
shape.x = x - shape.radius
shape.y = y - shape.radius
end
end
function collision.collisionTest(a, b)
if a.collision_type == "rectangle"
and b.collision_type == "rectangle" then
-- Rectangle VS Rectangle
local diffX = math.abs((a.x + a.width / 2) - (b.x + b.width / 2))
- (a.width + b.width) / 2
if diffX > 0 then return false end
local diffY = math.abs((a.y + a.height / 2) - (b.y + b.height / 2))
- (a.height + b.height) / 2
if diffY > 0 then return false end
if diffX < diffY then
return true
else
return true
end
end
if a.collision_type == "circle"
and b.collision_type == "circle" then
-- Circle VS Circle
local diffX = a.x - b.x
local diffY = a.y - b.y
local radiusSquared = (a.radius + b.radius) * (a.radius + b.radius)
return diffX * diffX + diffY * diffY < radiusSquared
end
-- Circle vs rectangle case
local rect = nil
local circle = nil
if a.collision_type == "rectangle" then
rect = a
circle = b
else
rect = b
circle = a
end
local nearestX = math.clamp(circle.x,
rect.x,
rect.x + rect.width)
local nearestY = math.clamp(circle.y,
rect.y,
rect.y + rect.height)
love.graphics.setColor(1, 1, 1)
love.graphics.circle("fill", nearestX, nearestY, 10)
local diffX = circle.x - nearestX
local diffY = circle.y - nearestY
local dSq = diffX * diffX + diffY * diffY
local rSq = circle.radius * circle.radius
return dSq < rSq
end
function math.clamp(lo, val, hi)
return math.min(math.max(lo, val), hi)
end
return collision