- Notifications
You must be signed in to change notification settings - Fork 20
Detecting Collisions
The next step is to deal with collisions. A collision happens when two objects overlap. First we need to detect an overlap, then to react on it (i.e. resolve collision). Collisions are the part of the game, where a good piece of it's logic resigns. In this part I implement basic collision detection.
It is convenient to store all collision-related functions in a special table:
local collisions = {}
Collisions have to be detected each update cycle -- collisions.resolve_collisions
function is added into love.update
( the function is called resolve_collisions
, but currently it will be doing only detection ).
function love.update( dt ) ..... collisions.resolve_collisions() end
There are 4 types of collisions: ball-platform, ball-walls, ball-bricks and platform-walls. Each of them is checked separately:
function collisions.resolve_collisions() collisions.ball_platform_collision( ball, platform ) collisions.ball_walls_collision( ball, walls ) collisions.ball_bricks_collision( ball, bricks ) collisions.platform_walls_collision( platform, walls ) end
For simplicity, I'm going to approximate the ball by an axis-aligned square. It significantly simplifies collision detection and collision resolution and it turns out to be sufficient for the current prototype. After that, all 4 types of collisions can be treated as collisions of rectangles.
It is convenient to have a helper function that detects an overlap of two rectangles. Suppose the rectangles - a
and b
- represented by tables with the fields x
,y
,width
and height
. We can detect an overlap with (see the second answer; add an explanation here)
function collisions.check_rectangles_overlap( a, b ) local overlap = false 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 end return overlap end
This function expects two tables with fields x
,y
,width
and height
. However, our game objects have different representation. To detect an overlap, it is necessary to prepare the a
and b
rectangles first. After that it is possible to use collisions.check_rectangles_overlap
and in the case of overlap print a message in the console.
function collisions.ball_platform_collision( ball, platform ) local a = { x = platform.position_x, --(*1) y = platform.position_y, width = platform.width, height = platform.height } local b = { x = ball.position_x - ball.radius, --(*1) y = ball.position_y - ball.radius, width = 2 * ball.radius, height = 2 * ball.radius } if collisions.check_rectangles_overlap( a, b ) then --(*2) print( "ball-platform collision" ) --(*3) end end
(*1): rectangles a
and b
are constructed from the properties of the game objects.
(*2): the overlap between a
and b
is checked.
(*3): if they overlap, a message to the console is printed.
The ball-bricks, ball-walls, and platform-walls collisions are dealt with in a same fashion. The only difference is that it is necessary to iterate over all bricks and all walls. For example, for the ball-bricks case:
function collisions.ball_bricks_collision( ball, bricks ) local b = { x = ball.position_x - ball.radius, --(*1) y = ball.position_y - ball.radius, width = 2 * ball.radius, height = 2 * ball.radius } for i, brick in pairs( bricks.current_level_bricks ) do --(*2) local a = { x = brick.position_x, --(*3) y = brick.position_y, width = brick.width, height = brick.height } if collisions.check_rectangles_overlap( a, b ) then --(*4) print( "ball-brick collision" ) end end end
(*1): rectangle for the ball is constructed.
(*2): iteration over bricks starts.
(*3),(*4): for each brick, the rectangle is constructed and the overlap with the ball is checked
The last change for this part is unrelated to collisions: the love.keyreleased
callback is added, so the game exits when Esc
key is pressed (released, actually).
function love.keyreleased( key, code ) if key == 'escape' then love.event.quit() end end
← 1.3 - Bricks and Walls ↑ To the top Next section: 1.5 - Resolving Collisions →
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: