Now the simulator’s running and we can get something on screen, let’s try for some simple pac-man like sprite controls.
First, the background image. Skipped this yesterday. Made a 400×240 black and white image, saved as a PNG in Photoshop, then called that in using the sample code:
local backgroundImage = gfx.image.new( "Images/back.png" )
assert( backgroundImage )gfx.sprite.setBackgroundDrawingCallback(
function( x, y, width, height )
-- x,y,width,height is the updated area in sprite-local coordinates
-- The clip rect is already set to this area, so we don't need to set it ourselves
backgroundImage:draw( 0, 0 )
end
)
That works – but my sprite is largely invisible. So, update the sprite to be white on transparent.
This is good, but the player can go off screen. Can test location using:
playerSprite.x
playerSprite.y
.. so add a function to move the player, and which checks for the screen edges using some very ugly logic:
function movePlayer(byX,byY)
-- check if at the edge. if not, move player
if (playerSprite.x + byX >= 15) and (playerSprite.x + byX <= 385) and (playerSprite.y + byY >= 15) and (playerSprite.y + byY <= 225) then
-- maybe use moveTo ?
playerSprite:moveBy( byX, byY )
end
-- log to console
-- print (playerSprite.x..","..playerSprite.y)
end
With that in place, my happy guy can’t disappear.
Time for pacman. Start a new file, and set up some variables to control everything:
-- vars for pacman-like control
local playerDirection = "n" -- none, up, down, left, right, initially n for none
local timerSpeed = 15 -- control the timer. start with 2x per second (updates every 30)
local playerSpeed = 16 -- how much does the player move on each action? in pixels
local timerControl = 0 -- will inc this on the loop
Borrow most of the setup function from last time. But then build a timer into the main playdate.update loop:
function playdate.update()
-- change direction if controller is pressed
-- would need to check for walls etc, but for now
if playdate.buttonIsPressed( playdate.kButtonUp ) then
playerDirection = "u"
elseif playdate.buttonIsPressed( playdate.kButtonRight ) then
playerDirection = "r"
elseif playdate.buttonIsPressed( playdate.kButtonDown ) then
playerDirection = "d"
elseif playdate.buttonIsPressed( playdate.kButtonLeft ) then
playerDirection = "l"
end
-- check timer control
timerControl = timerControl + 1
if (timerControl == timerSpeed) then
-- action
-- reset timerControl
timerControl = 0
-- move sprite
if playerDirection == "u" then
movePlayer(0,(0-playerSpeed))
elseif playerDirection == "r" then
movePlayer(playerSpeed,0)
elseif playerDirection == "d" then
movePlayer(0,playerSpeed)
elseif playerDirection == "l" then
movePlayer((0-playerSpeed),0)
end
-- update sprite
gfx.sprite.update()
end
-- should probably use this instead of my own timer?
playdate.timer.updateTimers()
end
The result: the blob moves in a jerky pacman style, in one direction only, until redirected with the D-pad.
Complete source here.
Three things I realised doing this:
1) There’s probably a better way to do the timer using the playdate.timer library rather than my own crude “increment this counter on every loop” thing, and
2) I should find out how lua handles arrays or objects. I could create some sort of simple way to lookup a direction and get the X and Y movements from it, making everything much neater
3) Maybe start looking at tile-based backgrounds – once I understand how to store the layout as an array-like thing.