Skip to content

Glue Bonus

noooway edited this page Apr 15, 2017 · 24 revisions

In this part I want to implement a "glue" bonus: when it's on, the ball doesn't rebound from the platform, but sticks to it until the player presses a launch button.

First it is necessary to add recognition of the "glue" bonus type in the collision detection code.

function bonuses.bonus_collected( i, bonus, ball, platform )
   .....
   elseif bonuses.is_glue( bonus ) then
      platform.react_on_glue_bonus()
   end
   .....
end

function bonuses.is_glue( single_bonus )
   local col = single_bonus.bonustype % 10
   return ( col == 2 )
end

When a "glue" bonus is caught, platform.glued flag is raised and the platform tile is changed to indicate the change visually.

function platform.react_on_glue_bonus()
   platform.glued = true
   if platform.size == "small" then
      platform.quad = love.graphics.newQuad(
         platform.small_tile_x_pos + platfrom.glued_x_pos_shift,
         platform.small_tile_y_pos,
         platform.small_tile_width,
         platform.small_tile_height,
         platform.tileset_width,
         platform.tileset_height )
   elseif platform.size == "norm" then
      platform.quad = love.graphics.newQuad(
         platform.norm_tile_x_pos + platfrom.glued_x_pos_shift,
         platform.norm_tile_y_pos,
         platform.norm_tile_width,
         platform.norm_tile_height,
         platform.tileset_width,
         platform.tileset_height )
   elseif platform.size == "large" then
      platform.quad = love.graphics.newQuad(
         platform.large_tile_x_pos + platfrom.glued_x_pos_shift,
         platform.large_tile_y_pos,
         platform.large_tile_width,
         platform.large_tile_height,
         platform.tileset_width,
         platform.tileset_height )
   end   
end

Ball-platform collision depends on the value of the glued flag.

function ball.platform_rebound( shift_ball, platform )
   ball.increase_collision_counter()
   ball.increase_speed_after_collision()
   if not platform.glued then
      ball.bounce_from_sphere( shift_ball, platform )
   else
      ball.stuck_to_platform = true
      local actual_shift = ball.determine_actual_shift( shift_ball )
      ball.position = ball.position + actual_shift
      ball.platform_launch_speed_magnitude = ball.speed:len()            --(*1)
      ball.compute_ball_platform_separation( platform )
   end
end

function ball.compute_ball_platform_separation( platform )
   local platform_center = vector(
      platform.position.x + platform.width / 2,
      platform.position.y + platform.height / 2 )
   local ball_center = ball.position:clone()           
   ball.separation_from_platform_center =
      ball_center - platform_center
   print( ball.separation_from_platform_center )   
end

(*1): On ball collision with the "glued" platform, ball speed magnitude is memorized and used later, when the ball is launched from the platform.

The ball.launch_from_platform procedure is changed. Launch speed magnitude equals to the speed magnitude before the collision and launch angle is determined from the distance between the ball and platform centers.

function ball.launch_from_platform()
   if ball.stuck_to_platform then
      ball.stuck_to_platform = false      
      local platform_halfwidth = 70       --(*1)
      local launch_direction = vector(
         ball.separation_from_platform_center.x / platform_halfwidth, -1 )
      ball.speed = launch_direction / launch_direction:len() *
         ball.platform_launch_speed_magnitude
   end
end

(*1): Half-width of the big platform is used, since it provides more diverse angles.

For ball.launch_from_platform to be applicable on the start of the level (i.e. when the ball is stuck to the platform, but the platform is not "glued"), it is necessary to initialize ball.platform_launch_speed_magnitude and ball.separation_from_platform_center with some initial values.

local initial_launch_speed_magnitude = 300
ball.platform_launch_speed_magnitude = initial_launch_speed_magnitude
local ball_platform_initial_separation = vector(
   ball_x_shift, -1 * platform_height / 2 - ball.radius - 1 )
ball.separation_from_platform_center = ball_platform_initial_separation 

The glued effect is removed if any other bonus (except another "glue" bonus) is caught.

function bonuses.bonus_collected( i, bonus, ball, platform )
   if not bonuses.is_glue( bonus ) then
      platform.remove_glued_effect()
      ball.launch_from_platform()
   end
   .....
   table.remove( bonuses.current_level_bonuses, i )
end

function platform.remove_glued_effect()
   if platform.glued then
      platform.glued = false
      if platform.size == "small" then
         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 )
      elseif platform.size == "norm" then
         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 )
      elseif platform.size == "large" then
         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 )
      end
   end
end

The effect is also removed if the ball is lost, or the next level is reached.

function game.enter( prev_state, ... )
   .....
   if args and args.current_level then
      .....
      ball.reposition()
      platform.remove_bonuses_effects()
   end      
end

function game.check_no_more_balls( ball, lives_display )
   if ball.escaped_screen then
         .....
         ball.reposition()
         platform.remove_bonuses_effects()
         .....
   end
end

function platform.remove_bonuses_effects()
   platform.remove_glued_effect()
   platform.reset_size_to_norm()
end

function ball.reposition()
   ball.escaped_screen = false
   ball.collision_counter = 0
   ball.stuck_to_platform = true
   ball.platform_launch_speed_magnitude = initial_launch_speed_magnitude
   ball.separation_from_platform_center = ball_platform_initial_separation 
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