Losing the game¶
Right now the game simply quits when we hit zero hit points, but that’s a bit unusual to say the
least. In this chapter we’re going to create a new GameState
to represent our game over
screen.
Making a gamestate¶
Navigate to the gamestates
folder and create a new file called gameoverstate.lua
with the
following contents:
--- @class GameOverState : GameState
--- @field display Display
--- @overload fun(display: Display): GameOverState
local GameOverState = spectrum.GameState:extend("GameOverState")
function GameOverState:__new(display)
self.display = display
end
function GameOverState:draw()
local midpoint = math.floor(self.display.height / 2)
self.display:clear()
self.display:putString(
1, midpoint,
"Game over!",
nil, nil, nil,
"center", self.display.width
)
self.display:draw()
end
return GameOverState
We extend the GameState
class and accept a Display
in our constructor. For
now, we just draw “Game over!” centered on the screen by using Display:putString()
’s
alignment parameters.
Replacing the exit¶
Let’s head over to gamelevelstate.lua
. First we’re going to require our new state at the top of
the file.
local GameOverState = require "gamestates.gameoverstate"
Then we’ll head back to the handleMessage
function. Replace our current handling of the Lose
message with the following.
if prism.messages.Lose:is(message) then
self.manager:enter(GameOverState(self.display))
end
Let’s boot up the game and spawn in a few kobolds. Let yourself get slapped around and you should see our new game over screen when you die!
A couple keybinds¶
Our game state still forces you to close the game manually, so let’s add a couple keybinds to
restart or close the game. In keybindingschema.lua
, add a couple entries:
{ key = "r", mode = "game-over", action = "restart", description = "Restarts the game." },
{ key = "q", mode = "game-over", action = "quit", description = "Quits the game." },
Back in gameoverstate.lua
, we’ll add a keypressed
callback to handle these:
local keybindings = require "keybindingschema"
function GameOverState:draw()
...
end
function GameOverState:keypressed(key, scancode, isrepeat)
local action = keybindings:keypressed(key, "game-over")
if action == "restart" then
love.event.restart()
elseif action == "quit" then
love.event.quit()
end
end
Don’t forget to require
our keybindings! We use a game-over
mode to differentiate from the
main game’s controls. Finally, add some instructions:
self.display:putString(
1, midpoint + 3,
"[r] to restart",
nil, nil, nil,
"center", self.display.width
)
self.display:putString(
1, midpoint + 4,
"[q] to quit",
nil, nil, nil,
"center", self.display.width
)
self.display:draw()
Next up¶
We’ve improved our death handling by using a new GameState
. In the next chapter we’ll be getting into map generation, and finally turn this into a real roguelike. The
following chapters will take you through generating a map and descending through the dungeon.