I have one small suggestion. If you store AABBs as a midpoint and a half-width and half-height, some of your code and calculations can be simplified quite a bit. This also means balls being stored as a center point and radius will be more in line with bricks and paddles.
For example, the cyclomatic complexity of the "check_rectangles_overlap" function can be reduced to 1, with half the LOC.
Before:
Code: Select all
function collisions.check_rectangles_overlap( a, b )
local overlap = false
local shift_b_x, shift_b_y = 0, 0
if not( a.x + a.width < b.x or b.x + b.width < a.x or
a.y + a.height < b.y or b.y + b.height < a.y ) then
overlap = true
if ( a.x + a.width / 2 ) < ( b.x + b.width / 2 ) then
shift_b_x = ( a.x + a.width ) - b.x --(*1a)
else
shift_b_x = a.x - ( b.x + b.width ) --(*1b)
end
if ( a.y + a.height / 2 ) < ( b.y + b.height / 2 ) then
shift_b_y = ( a.y + a.height ) - b.y --(*2)
else
shift_b_y = a.y - ( b.y + b.height ) --(*2)
end
end
return overlap, shift_b_x, shift_b_y --(*3)
end
Code: Select all
function collisions.check_rectangles_overlap( a, b )
local x_diff, y_diff = b.x - a.x, b.y - a.y
local x_dist, y_dist = math.abs(x_diff), math.abs(y_diff)
local x_overlap = a.width + b.width - x_dist
local y_overlap = a.height + b.height - y_dist
return x_overlap > 0 and y_overlap > 0,
x_diff / x_dist * x_overlap,
y_diff / y_dist * y_overlap
end
You could also create a separate function to get overlap and "shift" on a single axis. This should be even easier to read, and could be a step toward getting rid of those temporary tables created by ball_platform_collision (probably best not to create temporary tables every time you check for a collision).
Code: Select all
local function get_overlap( a_pos, b_pos, a_size, b_size )
local diff = b_pos - a_pos
local dist = math.abs(diff)
local overlap = a_size + b_size - dist
return overlap, diff / dist * overlap
end
function collisions.check_rectangles_overlap( a, b )
local x_overlap, x_shift = get_overlap(a.x, b.x, a.width, b.width)
local y_overlap, y_shift = get_overlap(a.y, b.y, a.height, b.height)
return x_overlap > 0 and y_overlap > 0, x_shift, y_shift
end