Skip to content

Game Over

noooway edited this page Jan 24, 2017 · 28 revisions

So far, one important component has been missing - the game over condition.

The mechanics is simple: it is necessary to add a lives counter and remove one life if the ball escapes through the bottom border of the screen. If the amount of lives becomes less than zero, the game over screen is shown.

I define a separate table lives_display, similar to the ball and the platform. The lives are stored in the lives field; on start there are 5 of them.

local lives_display = {}
lives_display.lives = 5

The update function is empty, draw displays the remaining lives in the bottom-right corner of the screen defined by lives_display.position = vector( 680, 500 ).

function lives_display.update( dt )
end

function lives_display.draw()
   love.graphics.print( "Lives: " .. tostring( lives_display.lives ),
                        lives_display.position.x,
                        lives_display.position.y )
end

The lives_display has to be required from the main.lua:

.....
local walls = require "walls"
local lives_display = require "lives_display"
local collisions = require "collisions"
.....

After that, it is necessary to make changes in the love.draw() callback to display the lives counter:

function love.draw()
   .....
   elseif gamestate == "game" then
      .....
      walls.draw()
      lives_display.draw()                 --(*1)
   elseif gamestate == "gamepaused" then
      .....
      lives_display.draw()                 --(*1)
      love.graphics.print(
         "Game is paused. Press Enter to continue or Esc to quit",
         50, 50)
   elseif 
   .....
end

(*1): lives counter is displayed in the "game" and "gamepaused" states.
I make similar changes to love.update even though the lives_display.update does nothing.

Now to the lives decreasing. It is possible to implement it by monitoring the ball collision with the currently existing bottom wall. Alternatively it is possible to monitor ball y-coordinate: if it becomes greater than screen height, the ball is considered lost. I'll use the second method and remove the bottom wall.

function ball.update( dt )
   ball.position = ball.position + ball.speed * dt
   ball.check_escape_from_screen()                   --(*1)
end

function ball.check_escape_from_screen()
   local x, y = ball.position:unpack()
   local ball_top = y - ball.radius
   if ball_top > love.graphics.getHeight() then
      ball.escaped_screen = true                     --(*2)
   end
end

function walls.construct_walls()
   .....
   walls.current_level_walls["left"] = left_wall
   walls.current_level_walls["right"] = right_wall
   walls.current_level_walls["top"] = top_wall       --(*3)
end

(*1): ball presence on the screen is checked each update cycle.
(*2): if ball goes through the bottom border of the screen, a corresponding flag is raised. This flag is monitored by check_no_more_balls function defined further.
(*3): bottom wall is not created.

If the ball leaves the screen, lives counter is decreased. If the amount of remaining lives drops below zero, the game switches to gameover screen.

function love.update( dt )
   .....
   elseif gamestate == "game" then
      .....
      check_no_more_balls( ball, lives_display )       --(*1)
      switch_to_next_level( bricks, ball, levels )
   elseif gamestate == "gamepaused" then
   .....
end

function check_no_more_balls( ball, lives_display )
   if ball.escaped_screen then
      lives_display.lose_life()                        --(*2)
      if lives_display.lives < 0 then
         gamestate = "gameover"
      else
         ball.reposition()       
      end
   end
end

function lives_display.lose_life()                     --(*3)
   lives_display.lives = lives_display.lives - 1
end

(*1): check_no_more_balls monitors ball.escaped_screen flag.
(*2): if the ball is lost, lives counter is decreased. If there are still some lives, the ball is repositioned; if there are none, "gameover" state is activated.
(*3): function to decrease lives counter.

The "gameover" gamestate is similar to the "gamepaused" state, except the "Game Over!" message and reaction on 'Enter' key: the game is restarted from the first level.

function gameover:update( dt )
end

function gameover:draw()
   for _,obj in pairs( game_objects ) do
      if type(obj) == "table" and obj.draw then
         obj:draw()
      end
   end
   self:cast_shadow()
   love.graphics.print(
      "Game over. Press Enter to continue or Esc to quit",
      50, 50)
end

function gameover:keyreleased( key, code )
   if key == 'return' then      
      Gamestate.switch( game, { level_counter = 1 } )
   elseif  key == 'escape' then
      love.event.quit()
   end    
end

function restart_from_first_level()
   levels.current_level = 1
   level = levels.require_current_level()
   bricks.clear_current_level_bricks()
   bricks.construct_level( level )
   ball.reposition()
   lives_display.reset()
   music:rewind()
   gamestate = "game"   
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