Skip to content

Latest commit

 

History

History
180 lines (136 loc) · 6.2 KB

10-game-over.md

File metadata and controls

180 lines (136 loc) · 6.2 KB

10. It's Game Over, Man!

To skip this chapter use the following link

I ain't afraid of no ghost!

Okay, next up we need to get the ghosts kill the player and show a game over screen when the player is killed.

So first, killing the player, lets do the same collision check as with the cherries. When player hits a enemy, set a flag on the player that the player is dead and spawn some yellow particles in place. Lets also unspawn the enemy so it doesn't continue spamming particles:

FUNCTION _UPDATE()
 -- SNIP SNIP
FOR E IN ALL(ENEMIES) DO
 E:UPDATE()
 IF DIST(PLAYER, E) < 4 THEN
  PLAYER.DEAD=TRUE
  ADD_PARTICLES(
    20,
    PLAYER.X,
    PLAYER.Y,
    10 -- YELLOW
  )
  DEL(ENEMIES,E)
 END
 -- SNIP SNIP
END

Now when the player is dead, lets make it so that the player doesn't draw and spawn some yellow particles in place. Lets do that in the player's DRAW function:

PLAYER={
 -- SNIP SNIP
 DRAW=FUNCTION (SELF)
  IF SELF.DEAD THEN RETURN END
  SPR(1,SELF.X,SELF.Y)
 END
 --SNIP SNIP
}

When running the game it'll look something like this:

Killed

Lets add a game over screen

The ghosts are still going at it though, so we'll need to pause the updates for a little while and show a game over screen.

So first of all we need to move the particle update to the top of _UPDATE and then exit the function if the player is dead so the rest doesn't update:

FUNCTION _UPDATE()
  -- MOVE PARTICLE UPDATE TO THE TOP OF THE FUNCTION
  FOR P IN ALL(PARTICLES) DO
   P:UPDATE()
  END
  IF PLAYER.DEAD THEN
   RETURN
  END
END

LUA like most dynamic languages lets you set functions in variables. So lets create a couple of variables that determines what will be drawn and updated, e.g. _UPD and _DRW, and extract all the code from the _UPDATE and _DRAW functions. The easiest way is to:

  1. Rename _UPDATE to UPDATE_GAME
  2. Rename _DRAW to DRAW_GAME
  3. Set variables _UPD and _DRW in _INIT to point to the renamed functions.
  4. Create new _UPDATE and _DRAW function that calls _UPD and _DRW respectively.

It should end up like this:

FUNCTION _INIT()
 -- SNIP SNIP
 _UPD=UPDATE_GAME
 _DRW=DRAW_GAME
END

FUNCTION _UPDATE()
 _UPD()
END

FUNCTION _DRAW()
 CLS()
 _DRW()
END

FUNCTION UPDATE_GAME() -- PREVIOUSLY _UPDATE
 -- SNIP SNIP
END

FUNCTION DRAW_GAME()
 -- SNIP SNIP
END

Lets make the Game Over screen

To make a game over screen we need to make a separate function for drawing and updating the game over screen. For the draw function lets draw the score and GAME OVER in the middle of the screen:

FUNCTION DRAW_GAME_OVER()
 PRINTC("GAME OVER",50,10)
 PRINTC("SCORE: "..SCORE,60,10)
END

You can try it out by setting that as function for _DRW in _INIT. It should look like this:

Initialized with game over screen

We want to restart the game from the game over screen, so lets do that with a button press. We can check this with the BTNP function.

FUNCTION UPDATE_GAME_OVER()
 IF BTNP() > 0 THEN
  _INIT()
  _DRW=DRAW_GAME   -- JUST IN CASE YOU'VE CHANGED
  _UPD=UPDATE_GAME -- THESE IN _INIT FOR TESTING
 END
END

Lets now make sure the game over screen is shown when the player has died:

-- IN UPDATE_GAME
IF PLAYER.DEAD THEN
 _DRW=DRAW_GAME_OVER
 _UPD=UPDATE_GAME
 RETURN
END

When you run the program it should look like this:

A rather abrupt ending

The ending is a bit abrupt and you hardly see the particles happening as the player dies. Lets fix that...

Make the ending less abrupt

We also want to pause for a second before revealing the game over screen. So add a variable for game over timer GAMEOVER_T in the _INIT function so we have something to start with.

FUNCTION _INIT()
 GAMEOVER_T=0
 -- SNIP SNIP
END

Lets set it in with a second or so after game time with T and when that time is reached, switch the screen:

-- IN GAME_UPDATE()
IF PLAYER.DEAD THEN
 IF GAMEOVER_T==0 THEN
  GAMEOVER_T=T()+1
 END
 IF T()>GAMEOVER_T THEN
  _DRW=DRAW_GAME_OVER
  _UPD=UPDATE_GAME_OVER
 END
 RETURN
END

When running the game and trying to die again, the game should wait a bit before switching to the game over screen!

Ah, now I can see the particles!

Points to review

  • Good idea: Extract update and drawing code to own functions and set them dynamically during run time to switch screens or "scenes".