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, the 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 existing bottom wall. Alternatively we can just monitor ball y-coordinate: if it becomes greater than screen height, we remove the ball. 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()
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
   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
end

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

function love.update( dt )
   .....
   elseif gamestate == "game" then
      .....
      check_no_more_balls( ball, lives_display )
      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()      
      if lives_display.lives < 0 then
         gamestate = "gameover"
      else
         ball.reposition()       
      end
   end
end

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

The GameOver gamestate is similar to the "Game Paused" state, except the 'Game Over!' message and reaction on 'Enter' key: the game is restarted from the first level and there is no need to pass back the game_objects table.

function gameover:enter( previous_state, ... )
   game_objects = ...
end

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

    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