To skip this chapter use the following link
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:
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:
- Rename
_UPDATE
toUPDATE_GAME
- Rename
_DRAW
toDRAW_GAME
- Set variables
_UPD
and_DRW
in_INIT
to point to the renamed functions. - 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
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:
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:
The ending is a bit abrupt and you hardly see the particles happening as the player dies. Lets fix that...
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!
- Good idea: Extract update and drawing code to own functions and set them dynamically during run time to switch screens or "scenes".