Now that we have a player and two enemies, it feels like time to turn this little demo into a (not very good) game.
Some of the needed variables were already set up, but we need some functions to set up or reset the game state:
function resetGame()
-- set map
map:setTiles(myLevel, 15)
-- start directions
playerDirection = "n" -- none, or u/d/l/r
enemyDirections = {"l","r"} -- an array
gameScore = 0 -- everyone loves a score
playerLives = 3
gameLive = true
resetSprites()
end
function resetSprites()
-- set to initial positions
playerSprite:changeState("r")
playerSprite:moveTo( (topLeft + 16), 16 )
playerSprite:add()
enemySprites[1]:moveTo( (topLeft + (9*16)), (7*16) )
enemySprites[1]:add()
enemySprites[2]:moveTo( (topLeft + (7*16)), (7*16) )
enemySprites[2]:add()
end
The resetSprites function is also used when the player loses a life, putting them back in their starting positions:
if checkCollisions() == true then
enemySprites[1]:remove()
enemySprites[2]:remove()
playerSprite:remove()
playerLives = playerLives - 1
if (playerLives > 0 ) then
resetSprites()
else
-- game over, do something?
gameLive = false
end
end
.. and we now have a game over state (gameLive is false), so need to handle that:
if gameLive == true then
(etc)
else
-- in game over state
if playdate.buttonIsPressed( playdate.kButtonA ) then
resetGame();
end
end
Finally, we need to put the score and lives up on screen. This should be easy using something like:
gfx.drawText('Score '..gameScore,280,60)
.. but I found that while I could draw text this way at the start of the program, all future updates seemed to be invisible.
I eventually figured out this is due to my using the Sprite tools – these were clearing the text off the screen. One way to handle this would be to turn the text into a sprite – I don’t yet know how – but a simpler one is to draw the text at the end of the “if game is live” loop, after the sprite work:
gfx.drawText('Score '..gameScore,280,60)
if gameLive == false then
gfx.drawText('Game Over ',280,100)
gfx.drawText('Press A',280,140)
else
gfx.drawText('Lives '..playerLives,280,100)
end
Finally, loading in custom fonts. The code is simple:
-- Font from https://github.com/BleuLlama/Playdate-Stuff
local font = gfx.font.new('Font/diamond_12')
gfx.setFont(font)
.. but note that to import a font you need both the FNT file and its accompanying PNG file. I made the mistake of copying over just diamond_12.fnt, which didn’t work.
And with that.. it works? A very simple puck-man game in around 450 lines of Lua:
It’s not much of a game, but it’s a game. And along the way it taught me how to handle sprites, collisions, tile-map graphics, basic AI and text – not too bad.
Full Lua code here. All the previous posts in this series on Playdate programming from zero are here.