Playdate 2

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.


Posted

in

,

by