-
Notifications
You must be signed in to change notification settings - Fork 19
Game Over
Ok, the game is almost complete.
It is still missing one important part - the game over condition. The mechanics is simple. We need to remove one life if all the ball escape throught the bottom part of the screen. Then we need to make changes in our life-keeping variable. If the amount of lives becomes less than zero, we show the game over screen.
Lets start from decreasing lives condition. We can implement it using existing setup with bottom wall and monitor ball collision with this 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, platform )
self.position = self.position + self.speed * dt
if self.stuck_to_platform then
self:follow_platform( platform )
end
self.collider_shape:moveTo( self.position:unpack() )
self:check_escape_from_screen()
end
function Ball:check_escape_from_screen()
local x, y = self.position:unpack()
local ball_top = y - self.radius
if ball_top > love.window.getHeight() then
self.to_destroy = true
end
end
function BallsContainer:update( dt, platform )
for i, ball in pairs( self.balls ) do
ball:update( dt, platform )
if ball.to_destroy then
ball.collider:remove( ball.collider_shape )
table.remove( self.balls, i )
end
end
end
If there are no more balls in the ballcontainer, we decrease the lives counter. If the amount of remaining lives drops below zero, we switch to gameover screen.
function game:update( dt )
platform:update( dt )
balls_container:update( dt, platform )
check_no_more_balls()
bricks_container:update( dt )
bonuses_container:update( dt )
walls_container:update( dt )
side_panel:update( dt )
resolve_collisions( dt )
switch_to_next_level()
end
function check_no_more_balls( platform )
if balls_container then
if #balls_container.balls == 0 then
side_panel:lose_life()
if side_panel.life_display.life < 0 then
Gamestate.switch( gameover,
{ level_sequence = level_sequence,
level_counter = level_counter,
level = level,
collider = collider,
balls_container = balls_container,
platform = platform,
walls_container = walls_container,
bricks_container = bricks_container,
bonuses_container = bonuses_container,
side_panel = side_panel } )
else
reposition_the_ball( platform )
end
end
end
end
function check_no_more_balls()
if #balls_container.balls == 0 then
side_panel:lose_life()
if side_panel.life_display.life < 0 then
Gamestate.switch( game, { level_counter = 1 } )
else
reposition_the_ball()
end
end
end
function reposition_the_ball( platform )
balls_container = BallsContainer:new( { collider = collider } )
balls_container:balls_follow_platform( platform )
end
function BallsContainer:balls_follow_platform( platform )
for i, ball in pairs( self.balls ) do
ball:follow_platform( platform )
end
end
function SidePanel:lose_life()
self.life_display:lose_life()
end
The draw method of GameOver gamestate just prints 'Game Over!' message.
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()
local oldfont = love.graphics.getFont()
love.graphics.setFont( bungee_font )
love.graphics.printf( "Game Over!",
158, 110, 300, "center" )
love.graphics.setFont( oldfont )
end
On left mouse button press or enter, game restarts from level 1. On RMB or Esc - quits.
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 gameover:mousereleased( x, y, button )
if button == 'l' then
Gamestate.switch( game, { level_counter = 1 } )
elseif button == 'r' then
love.event.quit()
end
end
There are no buttons in this gamestate. And I have also removed buttons from the Gamepaused gamestate to match the style.
TODO: в add new ball передавать также stick_to_platform прошлого мяча TODO: add puase on RMB from game gamestate and changes in gamepaused gamestate TODO: выход из титров по RMB TODO: упрощенный gamepause
Feedback is crucial to improve the tutorial!
Let me know if you have any questions, critique, suggestions or just any other ideas.
Chapter 1: Prototype
- The Ball, The Brick, The Platform
- Game Objects as Lua Tables
- Bricks and Walls
- Detecting Collisions
- Resolving Collisions
- Levels
Appendix A: Storing Levels as Strings
Appendix B: Optimized Collision Detection (draft)
Chapter 2: General Code Structure
- Splitting Code into Several Files
- Loading Levels from Files
- Straightforward Gamestates
- Advanced Gamestates
- Basic Tiles
- Different Brick Types
- Basic Sound
- 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
- Improved Ball Rebounds
- Ball Launch From Platform (Two Objects Moving Together)
- Mouse Controls
- Spawning Bonuses
- Bonus Effects
- Glue Bonus
- Add New Ball Bonus
- Life and Next Level Bonuses
- Random Bonuses
- Menu Buttons
- Wall Tiles
- Side Panel
- Score
- Fonts
- More Sounds
- Final Screen
- Packaging
Appendix D: GUI Layouts
Appendix E: Love-release and Love.js
Beyond Programming: