-
Notifications
You must be signed in to change notification settings - Fork 20
Resolving Collisions
In this part collision detections.
fig
We detect an overlap and then react somehow.
It turns out convenient to return not only the fact of overlap but also
a displacement necessary to resolve the overlap.
I suppose that the shape b
is the one that has to be displaced, and the a
should remain
in place. If the center of a
is to the left from b
, the b
is shifted right,
in the other case - left ( shift is negative ). Same for y-axis.
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
else
shift_b_x = a.x - ( b.x + b.width )
end
if ( a.y + a.height / 2 ) < ( b.y + b.height / 2 ) then
shift_b_y = ( a.y + a.height ) - b.y
elseif a.y < b.y + b.height and a.y + a.height > b.y + b.height then
shift_b_y = a.y - ( b.y + b.height )
end
end
return overlap, shift_b_x, shift_b_y
end
Now, in collision-resolution functions we need to check for overlap, and if it happes - react on in. For platform-ball collision, there is no need to modify the platform, but it is necessary to change the ball direction.
function collisions.ball_platform_collision( ball, platform )
local overlap, shift_ball_x, shift_ball_y
local a = { x = platform.position_x,
y = platform.position_y,
width = platform.width,
height = platform.height }
local b = { x = ball.position_x - ball.radius,
y = ball.position_y - ball.radius,
width = 2 * ball.radius,
height = 2 * ball.radius }
overlap, shift_ball_x, shift_ball_y =
collisions.check_rectangles_overlap( a, b )
if overlap then
ball.rebound( shift_ball_x, shift_ball_y )
end
end
In ball.rebound
function the overlap values are passed.
I determine the minimal one of them, zero the other one and shift the ball by that value.
Besides, the speed direction along the shift axis is reversed.
function ball.rebound( shift_ball_x, shift_ball_y )
local big_enough_overlap = 0.5
local min_shift = math.min( math.abs( shift_ball_x ), math.abs( shift_ball_y ) )
if math.abs( shift_ball_x ) == min_shift then
shift_ball_y = 0
else
shift_ball_x = 0
end
ball.position_x = ball.position_x + shift_ball_x
ball.position_y = ball.position_y + shift_ball_y
if math.abs( shift_ball_x ) > big_enough_overlap then
ball.speed_x = -ball.speed_x
end
if math.abs( shift_ball_y ) > big_enough_overlap then
ball.speed_y = -ball.speed_y
end
end
Other collisions are resolved in a similar fashion. I'll mention ball-brick collision.
function collisions.ball_bricks_collision( ball, bricks )
.....
for i, brick in pairs( bricks.current_level_bricks ) do
.....
overlap, shift_ball_x, shift_ball_y =
collisions.check_rectangles_overlap( a, b )
if overlap then
ball.rebound( shift_ball_x, shift_ball_y )
bricks.brick_hit_by_ball( i, brick,
shift_ball_x, shift_ball_y )
end
end
end
The brick is removed on collision.
This is done by table.remove
function.
It is also necessary to pass the index of the brick.
function bricks.brick_hit_by_ball( i, brick,
shift_ball_x, shift_ball_y )
local big_enough_overlap = 0.5
if math.abs( shift_ball_x ) > big_enough_overlap or
math.abs( shift_ball_y ) > big_enough_overlap then
table.remove( bricks.current_level_bricks, i )
end
end
Feedback is crucial to improve the tutorial!
Let me know if you have any questions, critique, suggestions or just any other ideas.
Chapter 1: Prototype
- The Ball, The Brick, The Platform
- Game Objects as Lua Tables
- Bricks and Walls
- Detecting Collisions
- Resolving Collisions
- Levels
Appendix A: Storing Levels as Strings
Appendix B: Optimized Collision Detection (draft)
Chapter 2: General Code Structure
- Splitting Code into Several Files
- Loading Levels from Files
- Straightforward Gamestates
- Advanced Gamestates
- Basic Tiles
- Different Brick Types
- Basic Sound
- Game Over
Appendix C: Stricter Modules (draft)
Appendix D-1: Intro to Classes (draft)
Appendix D-2: Chapter 2 Using Classes.
Chapter 3 (deprecated): Details
- Improved Ball Rebounds
- Ball Launch From Platform (Two Objects Moving Together)
- Mouse Controls
- Spawning Bonuses
- Bonus Effects
- Glue Bonus
- Add New Ball Bonus
- Life and Next Level Bonuses
- Random Bonuses
- Menu Buttons
- Wall Tiles
- Side Panel
- Score
- Fonts
- More Sounds
- Final Screen
- Packaging
Appendix D: GUI Layouts
Appendix E: Love-release and Love.js
Beyond Programming: