New collision code! Minor doc changes.
[luagame.git] / base / aabb_collision.lua
blobf2970e7eb3d1eaba231ce305a27cdc6f7311a923
1 --these are functions for doing collision detection
3 --unless one wants to write their own routines, then the
4 -- collide_Object_bounds() and collide_Object_Rects() shouldn't be used
5 --
6 -- Instead, please use the check_collisions_*() functions
9 function collide_Object_bounds(a, b)
10 --this is provided as a convenience so that one can make objects invisible to collisions
11 if a.death_anim == true or b.death_anim == true then return false end
13 local x1, x2, y1, y2, x3, x4, y3, y4 = a.x, a.x + a.w, a.y, a.y + a.h, b.x, b.x + b.w, b.y, b.y + b.h
15 --fully contained
16 if ((x1 >= x3 and x2 <= x4) and (y1 >= y3 and y2 <= y4)) or
17 ((x3 >= x1 and x4 <= x2) and (y3 >= y1 and y4 <= y2)) then
18 return true
19 end
21 --top left corner
22 if ((x1 >= x3 and x1 <= x4) and (y1 >= y3 and y1 <= y4)) or
23 ((x3 >= x1 and x3 <= x2) and (y3 >= y1 and y3 <= y2)) then
24 return true
25 end
27 --top right corner
28 if ((x2 >= x3 and x2 <= x4) and (y1 >= y3 and y1 <= y4)) or
29 ((x4 >= x1 and x4 <= x2) and (y3 >= y1 and y3 <= y2)) then
30 return true
31 end
33 --bottom left corner
34 if ((x1 >= x3 and x1 <= x4) and (y2 >= y3 and y2 <= y4)) or
35 ((x3 >= x1 and x3 <= x2) and (y4 >= y1 and y4 <= y2)) then
36 return true
37 end
39 --bottom right corner
40 if ((x1 >= x3 and x1 <= x4) and (y2 >= y3 and y2 <= y4)) or
41 ((x3 >= x1 and x3 <= x2) and (y4 >= y1 and y4 <= y2)) then
42 return true
43 end
45 --top
46 if ((x1 <= x3 and x2 >= x4) and (y1 >= y3 and y1 <= y4)) or
47 ((x3 <= x1 and x4 >= x2) and (y3 >= y1 and y3 <= y2)) then
48 return true
49 end
51 --left
52 if ((x1 <= x3 and x1 >= x4) and (y1 >= y3 and y2 <= y4)) or
53 ((x3 <= x1 and x3 >= x2) and (y3 >= y1 and y4 <= y2)) then
54 return true
55 end
57 --right
58 if ((x2 <= x3 and x2 >= x4) and (y1 >= y3 and y2 <= y4)) or
59 ((x4 <= x1 and x4 >= x2) and (y3 >= y1 and y4 <= y2)) then
60 return true
61 end
63 --bottom
64 if ((x1 <= x3 and x2 >= x4) and (y2 >= y3 and y2 <= y4)) or
65 ((x3 <= x1 and x4 >= x2) and (y4 >= y1 and y4 <= y2)) then
66 return true
67 end
69 return false
70 end
73 function collide_Object_Rects(a, b)
74 if a.death_anim or b.death_anim then return false end
76 local a_ids = ObjectList:new()
77 local b_ids = ObjectList:new()
79 for r1 in a.rects:iterator() do
80 for r2 in b.rects:iterator() do
82 local flag = false
84 local x1, x2, y1, y2, x3, x4, y3, y4 = r1.x+a.x, r1.x+a.x+a.w, r1.y+a.y, r1.y+a.y+a.h, r2.x+b.x, r2.x+b.x+b.w, r2.y+b.y, r2.y+b.y+b.h
86 --fully contained
87 if ((x1 >= x3 and x2 <= x4) and (y1 >= y3 and y2 <= y4)) or
88 ((x3 >= x1 and x4 <= x2) and (y3 >= y1 and y4 <= y2)) then
89 flag = true
90 if a_ids:exists(r1.id) == false then a_ids:push_back(r1.id) end
91 if b_ids:exists(r2.id) == false then b_ids:push_back(r2.id) end
92 end
94 --top left corner
95 if flag == false and ((x1 >= x3 and x1 <= x4) and (y1 >= y3 and y1 <= y4)) or
96 ((x3 >= x1 and x3 <= x2) and (y3 >= y1 and y3 <= y2)) then
97 flag = true
98 if a_ids:exists(r1.id) == false then a_ids:push_back(r1.id) end
99 if b_ids:exists(r2.id) == false then b_ids:push_back(r2.id) end
102 --top right corner
103 if flag == false and ((x2 >= x3 and x2 <= x4) and (y1 >= y3 and y1 <= y4)) or
104 ((x4 >= x1 and x4 <= x2) and (y3 >= y1 and y3 <= y2)) then
105 flag = true
106 if a_ids:exists(r1.id) == false then a_ids:push_back(r1.id) end
107 if b_ids:exists(r2.id) == false then b_ids:push_back(r2.id) end
110 --bottom left corner
111 if flag == false and ((x1 >= x3 and x1 <= x4) and (y2 >= y3 and y2 <= y4)) or
112 ((x3 >= x1 and x3 <= x2) and (y4 >= y1 and y4 <= y2)) then
113 flag = true
114 if a_ids:exists(r1.id) == false then a_ids:push_back(r1.id) end
115 if b_ids:exists(r2.id) == false then b_ids:push_back(r2.id) end
118 --bottom right corner
119 if flag == false and ((x1 >= x3 and x1 <= x4) and (y2 >= y3 and y2 <= y4)) or
120 ((x3 >= x1 and x3 <= x2) and (y4 >= y1 and y4 <= y2)) then
121 flag = true
122 if a_ids:exists(r1.id) == false then a_ids:push_back(r1.id) end
123 if b_ids:exists(r2.id) == false then b_ids:push_back(r2.id) end
126 --top
127 if flag == false and ((x1 <= x3 and x2 >= x4) and (y1 >= y3 and y1 <= y4)) or
128 ((x3 <= x1 and x4 >= x2) and (y3 >= y1 and y3 <= y2)) then
129 flag = true
130 if a_ids:exists(r1.id) == false then a_ids:push_back(r1.id) end
131 if b_ids:exists(r2.id) == false then b_ids:push_back(r2.id) end
134 --left
135 if flag == false and ((x1 <= x3 and x1 >= x4) and (y1 >= y3 and y2 <= y4)) or
136 ((x3 <= x1 and x3 >= x2) and (y3 >= y1 and y4 <= y2)) then
137 flag = true
138 if a_ids:exists(r1.id) == false then a_ids:push_back(r1.id) end
139 if b_ids:exists(r2.id) == false then b_ids:push_back(r2.id) end
142 --right
143 if flag == false and ((x2 <= x3 and x2 >= x4) and (y1 >= y3 and y2 <= y4)) or
144 ((x4 <= x1 and x4 >= x2) and (y3 >= y1 and y4 <= y2)) then
145 flag = true
146 if a_ids:exists(r1.id) == false then a_ids:push_back(r1.id) end
147 if b_ids:exists(r2.id) == false then b_ids:push_back(r2.id) end
150 --bottom
151 if flag == false and ((x1 <= x3 and x2 >= x4) and (y2 >= y3 and y2 <= y4)) or
152 ((x3 <= x1 and x4 >= x2) and (y4 >= y1 and y4 <= y2)) then
153 flag = true
154 if a_ids:exists(r1.id) == false then a_ids:push_back(r1.id) end
155 if b_ids:exists(r2.id) == false then b_ids:push_back(r2.id) end
161 return a_ids, b_ids
165 --checks for collisions between two lists and calls the collide() function of each
166 function check_collisions_lists(list1, list2)
167 local id1, id2
168 for obj1 in list1:iterator() do
169 for obj2 in list2:iterator() do
170 if obj1 ~= obj2 and collide_Object_bounds(obj1, obj2) then
171 id1, id2 = collide_Object_Rects(obj1, obj2)
172 obj1:collide(id1, obj2.type)
173 obj2:collide(id2, obj1.type)
179 --checks for collisions between an object and a list
180 function check_collisions_obj_list(obj, list2)
181 local id1, id2
182 for obj2 in list2:iterator() do
183 if obj1 ~= obj2 and collide_Object_bounds(obj, obj2) then
184 id1, id2 = collide_Object_Rects(obj, obj2)
185 obj:collide(id1, obj2.type)
186 obj2:collide(id2, obj.type)
191 --checks for collisions between two objects
192 function check_collisions_obj_obj(obj1, obj2)
193 local id1, id2
194 if obj1 ~= obj2 and collide_Object_bounds(obj1, obj2) then
195 id1, id2 = collide_Object_Rects(obj1, obj2)
196 obj1:collide(id1, obj2.type)
197 obj2:collide(id2, obj1.type)
201 --checks for collisions between an object and a list. returns true or false.
202 function check_collisions_any(obj, list)
203 local id1, id2
204 for obj2 in list2:iterator() do
205 if collide_Object_bounds(obj, obj2) then
206 id1, id2 = collide_Object_Rects(obj, obj2)
207 if id1.size > 0 and id2.size > 0 then
208 return true
209 else
210 return false