-
Notifications
You must be signed in to change notification settings - Fork 20
Bonus effects
In this part I want to implement four bonus effects: accelerate/decelerate the ball, and increase/decrease the platform size.
A bonus effect is applied when the player catches a falling bonus with the platform, i.e. on bonus-platform collision. So, in the first place it is necessary to detect such types of collisions.
function collisions.resolve_collisions( ball, platform,
walls, bricks, bonuses )
.....
collisions.platform_bonuses_collision( platform, bonuses, ball ) --(*1)
end
function collisions.platform_bonuses_collision( platform, bonuses, ball )
local overlap
local b = { x = platform.position.x,
y = platform.position.y,
width = platform.width,
height = platform.height }
for i, bonus in pairs( bonuses.current_level_bonuses ) do
local a = { x = bonus.position.x - bonuses.radius,
y = bonus.position.y - bonuses.radius,
width = 2 * bonuses.radius,
height = 2 * bonuses.radius }
overlap = collisions.check_rectangles_overlap( a, b )
if overlap then
bonuses.bonus_collected( i, bonus, ball, platform ) --(*2)
end
end
end
(*1): Check for bonus-platform collisions is inserted along with the other collisions checks.
(*2): A bonus-platform overlap is checked similarly to the platform-ball. If an overlap is detected,
a function bonuses.bonus_collected
that applies bonus effect is called.
Bonustypes from left to right: 11 - slowdown, 12 - glue, 13 - increase, 14 - new ball, 15 - accelerate,
16 - decrease, 17 - next level , 18 - new life.
To apply bonus effect, first it is necessary to determine the bonus type. The procedure is analogous to the bricks. Slowdown and accelerate are 11 and 15, increase and decrease are 13 and 16. The bonus has to be removed from the game after it's effect is applied.
function bonuses.bonus_collected( i, bonus, ball, platform )
if bonuses.is_slowdown( bonus ) then
.....
elseif bonuses.is_accelerate( bonus ) then
.....
elseif bonuses.is_increase( bonus ) then
.....
elseif bonuses.is_decrease( bonus ) then
.....
end
table.remove( bonuses.current_level_bonuses, i ) --(*1)
end
function bonuses.is_slowdown( single_bonus )
local col = single_bonus.bonustype % 10
return ( col == 1 )
end
function bonuses.is_accelerate( single_bonus )
local col = single_bonus.bonustype % 10
return ( col == 5 )
end
function bonuses.is_increase( single_bonus )
local col = single_bonus.bonustype % 10
return ( col == 3 )
end
function bonuses.is_decrease( single_bonus )
local col = single_bonus.bonustype % 10
return ( col == 6 )
end
(*1): Remove the bonus from the game.
To accelerate or decelerate the ball, it is necessary to insert a call to the
appropriate functions in the ball
table. For this, bonuses.bonus_collected
needs an
access to the ball
table. It becomes necessary to pass the ball
as an argument
all the way down from the collisions.platform_bonuses_collision
call.
function bonuses.bonus_collected( i, bonus, ball, platform )
if bonuses.is_slowdown( bonus ) then
ball.react_on_slow_down_bonus()
elseif bonuses.is_accelerate( bonus ) then
ball.react_on_accelerate_bonus()
elseif
.....
end
function ball.react_on_slow_down_bonus()
local slowdown = 0.7
ball.speed = ball.speed * slowdown --(*1)
end
function ball.react_on_accelerate_bonus()
local accelerate = 1.3
ball.speed = ball.speed * accelerate --(*1)
end
(*1): Acceleration or deceleration of the ball simply changes it's speed. The actual way it is done can be adjusted; I simply scale it by some constant.
- Platfrom increase-decrease
function bonuses.bonus_collected( i, bonus, ball, platform )
if
.....
elseif bonuses.is_increase( bonus ) then
platform.react_on_decrease_bonus()
elseif bonuses.is_decrease( bonus ) then
platform.react_on_increase_bonus()
end
table.remove( bonuses.current_level_bonuses, i )
end
...
platform.width = platform.norm_tile_width
platform.height = platform.norm_tile_height
platform.size = "norm"
function platform.react_on_decrease_bonus()
if platform.size == "norm" then
platform.width = platform.small_tile_width
platform.height = platform.small_tile_height
platform.quad = love.graphics.newQuad(
platform.small_tile_x_pos, platform.small_tile_y_pos,
platform.small_tile_width, platform.small_tile_height,
platform.tileset_width, platform.tileset_height )
platform.size = "small"
elseif platform.size == "large" then
platform.width = platform.norm_tile_width
platform.height = platform.norm_tile_height
platform.quad = love.graphics.newQuad(
platform.norm_tile_x_pos, platform.norm_tile_y_pos,
platform.norm_tile_width, platform.norm_tile_height,
platform.tileset_width, platform.tileset_height )
platform.size = "norm"
end
end
function platform.react_on_increase_bonus()
if platform.size == "small" then
platform.width = platform.norm_tile_width
platform.height = platform.norm_tile_height
platform.quad = love.graphics.newQuad(
platform.norm_tile_x_pos, platform.norm_tile_y_pos,
platform.norm_tile_width, platform.norm_tile_height,
platform.tileset_width, platform.tileset_height )
platform.size = "norm"
elseif platform.size == "norm" then
platform.width = platform.large_tile_width
platform.height = platform.large_tile_height
platform.quad = love.graphics.newQuad(
platform.large_tile_x_pos, platform.large_tile_y_pos,
platform.large_tile_width, platform.large_tile_height,
platform.tileset_width, platform.tileset_height )
platform.size = "large"
end
end
- Care should be taken regarding platform sizes if next level is reached or the ball is lost.
function game.enter( prev_state, ... )
.....
if args and args.current_level then
.....
ball.reposition()
platform.reset_size_to_norm()
end
end
function game.check_no_more_balls( ball, lives_display )
if ball.escaped_screen then
.....
ball.reposition()
platform.reset_size_to_norm()
.....
end
end
function platform.reset_size_to_norm()
platform.width = platform.norm_tile_width
platform.height = platform.norm_tile_height
platform.quad = love.graphics.newQuad(
platform.norm_tile_x_pos, platform.norm_tile_y_pos,
platform.norm_tile_width, platform.norm_tile_height,
platform.tileset_width, platform.tileset_height )
platform.size = "norm"
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: