Life and Next Level Bonuses - noooway/love2d_arkanoid_tutorial GitHub Wiki
In this part I want to implement two bonuses: one that adds a life and another that allows to finish a level skipping remaining blocks.
First it is necessary to add code to recognize "Life" and "Next Level" bonuses:
function bonuses.bonus_collected( i, bonus, balls, platform )
.....
elseif bonuses.is_life( bonus ) then
.....
elseif bonuses.is_next_level( bonus ) then
.....
end
.....
end
function bonuses.is_life( single_bonus )
local col = single_bonus.bonustype % 10
return ( col == 8 )
end
function bonuses.is_next_level( single_bonus )
local col = single_bonus.bonustype % 10
return ( col == 7 )
end
To reaction on "Add Life" bonus it is necessary to increase lives counter in the lives_display
table.
An appropriate function is implemented as lives_display.add_life()
.
I call it inside the bonuses.bonus_collected
, where currently all other reactions on bonuses are placed.
To do this, it is necessary to supply lives_display
as an argument to bonus_collected
, which requires
to pass it all the way down from the game.update
through collision-related functions (probably, not an optimal solution).
function game.update( dt )
.....
collisions.resolve_collisions( balls, platform,
walls, bricks,
bonuses, lives_display )
.....
end
function collisions.resolve_collisions( balls, platform,
walls, bricks,
bonuses, lives_display )
.....
collisions.platform_bonuses_collision( platform, bonuses,
balls, lives_display )
end
function collisions.platform_bonuses_collision( platform, bonuses,
balls, lives_display )
.....
if overlap then
bonuses.bonus_collected( i, bonus, balls, platform, lives_display )
end
.....
end
function bonuses.bonus_collected( i, bonus, balls, platform, lives_display )
.....
elseif bonuses.is_life( bonus ) then
lives_display.add_life()
elseif
.....
end
function lives_display.add_life()
lives_display.lives = lives_display.lives + 1
end
The "Next Level" bonus works the following way: when it is caught, a portal inside the right wall is activated. If the player touches the portal with the platform, transition to the next level occurs.
If the "Next Level" bonus is caught, a special flag in the right wall is activated
walls.current_level_walls["right"].next_level_bonus = true
. This is done inside the bonuses.bonus_collected
function and (again) requires to pass the walls
table as an argument through all the collision-related functions.
function collisions.resolve_collisions( balls, platform,
walls, bricks,
bonuses, lives_display )
.....
collisions.platform_bonuses_collision( platform, bonuses,
balls, walls,
lives_display )
end
function collisions.platform_bonuses_collision( platform, bonuses,
balls, walls,
lives_display )
.....
if overlap then
bonuses.bonus_collected( i, bonus,
balls, platform,
walls, lives_display )
end
.....
end
function bonuses.bonus_collected( i, bonus,
balls, platform,
walls, lives_display )
.....
elseif bonuses.is_next_level( bonus ) then
walls.current_level_walls["right"].next_level_bonus = true
end
.....
end
To indicate that a portal to the next level is open, appearance of the wall is changed.
function walls.draw_wall( single_wall )
.....
love.graphics.setColor( 255, 0, 0, 100 )
if single_wall.next_level_bonus then
love.graphics.setColor( 0, 0, 255, 100 )
end
love.graphics.rectangle( 'fill',
single_wall.position.x,
single_wall.position.y,
single_wall.width,
single_wall.height )
.....
end
If the platform touches the right wall, the game switches
to the next level. Instead of calling game.switch_to_next_level
from
collision-resolution functions, it is more convenient to raise a special flag in the
platform object and check it each update cycle.
function collisions.platform_walls_collision( platform, walls )
.....
if overlap then
platform.bounce_from_wall( shift_platform, wall )
end
.....
end
function platform.bounce_from_wall( shift_platform, wall )
platform.position.x = platform.position.x + shift_platform.x
if wall.next_level_bonus then
platform.activated_next_level_bonus = true
end
end
function game.switch_to_next_level( bricks, levels )
if bricks.no_more_bricks or platform.activated_next_level_bonus then
.....
end
end
The effect of the bonus is lost if next level is reached or all the balls are lost.
function game.enter( prev_state, ... )
.....
if args and args.current_level then
.....
platform.remove_bonuses_effects()
walls.remove_bonuses_effects()
end
end
function game.check_no_more_balls( balls, lives_display )
if balls.no_more_balls then
.....
platform.remove_bonuses_effects()
walls.remove_bonuses_effects()
.....
end
end
function platform.remove_bonuses_effects()
platform.remove_glued_effect()
platform.reset_size_to_norm()
platform.activated_next_level_bonus = false
end
function walls.remove_bonuses_effects()
walls.current_level_walls["right"].next_level_bonus = false
end