Inspecting a basic game for Playdate

rmion

Robert Mion

Posted on February 25, 2023

Inspecting a basic game for Playdate

In the last article, I referred to Playdate's official documentation, Inside Playdate, to successfully compile the source code from a sample open-sourced game on Github.

Now I'd like to become more familiar with the source code itself.

Of course, I want to start with something simple.

Thankfully, Inside Playdate features such an example.

Studying the example main.lua file

This section of Inside Playdate features an example main.lua file.

I intend to study it one line at a time.

import "CoreLibs/object"
import "CoreLibs/graphics"
import "CoreLibs/sprites"
import "CoreLibs/timer"
Enter fullscreen mode Exit fullscreen mode

First are several core libraries. A library is a collection of code that makes doing something a lot easier than writing the code yourself.

local gfx <const> = playdate.graphics
Enter fullscreen mode Exit fullscreen mode

Next is this local constant - a variable that cannot be reassigned. It's name is gfx. The document states that this is just for convenience: writing three letters instead of 16 is always preferred.

local playerSprite = nil
Enter fullscreen mode Exit fullscreen mode

Another local variable, starting value-less.

function myGameSetUp()
  ...
end
Enter fullscreen mode Exit fullscreen mode

A function with a helpful name.

What's inside?

local playerImage = gfx.image.new("Images/playerImage")
Enter fullscreen mode Exit fullscreen mode

A local variable.
I see now why the constant gfx was a good idea.
But for full understanding, the expression is:

playdate.graphics.image.new("Images/playerImage")
Enter fullscreen mode Exit fullscreen mode

So, stored in playerImage is a literal image file located in the Images folder inside the source code's root directory.

assert( playerImage )
Enter fullscreen mode Exit fullscreen mode

Using code to validate and confirm the contents of playerImage.

playerSprite = gfx.sprite.new( playerImage )
Enter fullscreen mode Exit fullscreen mode

Again, the long form is:

playdate.graphics.sprite.new(playerImage)
Enter fullscreen mode Exit fullscreen mode

This creates a sprite from the image?

Interesting that it doesn't just use the image, but creates a sprite from it instead.

playerSprite:moveTo( 200, 120 )
Enter fullscreen mode Exit fullscreen mode

The use of the colon is new syntax to me.
It seems like moveTo is a method of playerSprite.
I'm used to a period representing accessor syntax.

This moves the center of the sprite to 200,120 - the center of the screen.

playerSprite:add()
Enter fullscreen mode Exit fullscreen mode

The comment in the documentation states This is critical!.

It seems the sprite may not appear unless this method is invoked...even though the line above technically moved it to a spot on the screen?

local backgroundImage = gfx.image.new( "Images/background" )
assert( backgroundImage )
Enter fullscreen mode Exit fullscreen mode

These two lines are identical - aside from variable and file names - to what's above for the playerImage.

gfx.sprite.setBackgroundDrawingCallback(
  function( x, y, width, height )
    backgroundImage:draw( 0, 0 )
  end
)
Enter fullscreen mode Exit fullscreen mode

It's odd that sometimes a . is used to access a method, and other times a : is used. There must be some subtle difference that I'm missing in Lua.

Anyway, this function seems to expect a function as its first argument.

The expected function seems to expect four arguments.

Inside of it, the image is rendered at the top-left of the screen.

myGameSetUp()
Enter fullscreen mode Exit fullscreen mode

The file invokes the custom function.

function playdate.update()
  ...
end
Enter fullscreen mode Exit fullscreen mode

This function is a built-in event on the playdate.

I'm familiar with it from Pulp.

if playdate.buttonIsPressed( playdate.kButtonUp ) then
  playerSprite:moveBy( 0, -2 )
end

if playdate.buttonIsPressed( playdate.kButtonRight ) then
  playerSprite:moveBy( 2, 0 )
end

if playdate.buttonIsPressed( playdate.kButtonDown ) then
  playerSprite:moveBy( 0, 2 )
end

if playdate.buttonIsPressed( playdate.kButtonLeft ) then
  playerSprite:moveBy( -2, 0 )
end
Enter fullscreen mode Exit fullscreen mode

In English:

If the current button pressed is one of the four d-pad buttons, then move the sprite by two pixels in the appropriate direction

I wonder why the button name is prefixed with a k.

There's that : again.

gfx.sprite.update()
playdate.timer.updateTimers()
Enter fullscreen mode Exit fullscreen mode

Draw sprites and keep timers updated

More questions

  • What's with the . and : syntax?
  • Why the initial k in the button names?
  • Why sprites vs. images?
  • What even is a sprite, technically?
  • How would I make one so that I could try out this game?

It seems like I need to research sprites, next.

💖 💪 🙅 🚩
rmion
Robert Mion

Posted on February 25, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related