Skip to content

Bonus effects

noooway edited this page Mar 31, 2017 · 19 revisions

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.

To implement the platform increase-decrease effects, it is also necessary to put call to the appropriate platform methods into the bonuses.bonus_collected.

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

Their actual implementation is a bit more complicated, that ball acceleration and deceleration. There are three sizes of the platform: "small", "norm", and "large". The "increase" bonus can enlarge the platform size from "norm" to "large" or from "small" to "norm". But it has no effect, if the platform is "large" already. To change the platform size, it is necessary to change it's width and change the tile that represents it.

.....
platform.width = platform.norm_tile_width
platform.height = platform.norm_tile_height
platform.size = "norm"                      --(*1)

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

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

(*1): platform current size has to be kept as an additional field inside the platform table.

  1. Apart from the width and quad, a "sphere radius" parameter used in platform-ball collision resolution also needs an adjustments.
insert some code here

If the next level is reached or the ball is lost, it is necessary to reset the platform size to normal.

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

    Home
    Acknowledgements
    Todo

Chapter 1: Prototype

  1. The Ball, The Brick, The Platform
  2. Game Objects as Lua Tables
  3. Bricks and Walls
  4. Detecting Collisions
  5. Resolving Collisions
  6. Levels

    Appendix A: Storing Levels as Strings
    Appendix B: Optimized Collision Detection (draft)

Chapter 2: General Code Structure

  1. Splitting Code into Several Files
  2. Loading Levels from Files
  3. Straightforward Gamestates
  4. Advanced Gamestates
  5. Basic Tiles
  6. Different Brick Types
  7. Basic Sound
  8. 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

  1. Improved Ball Rebounds
  2. Ball Launch From Platform (Two Objects Moving Together)
  3. Mouse Controls
  4. Spawning Bonuses
  5. Bonus Effects
  6. Glue Bonus
  7. Add New Ball Bonus
  8. Life and Next Level Bonuses
  9. Random Bonuses
  10. Menu Buttons
  11. Wall Tiles
  12. Side Panel
  13. Score
  14. Fonts
  15. More Sounds
  16. Final Screen
  17. Packaging

    Appendix D: GUI Layouts
    Appendix E: Love-release and Love.js

Beyond Programming:

  1. Game Design
  2. Minimal Marketing (draft)
  3. Finding a Team (draft)

Archive

Clone this wiki locally