Draw Text Overlayed

Hello! I'm on windows, and I'm trying to draw text by just using

function playdate.update()
    playdate.graphics.drawText("Amount: " .. waterAmount, 5, 5)
end

But anything I draw is overlayed.
image
(Also tried drawing with different draw mode and it didn't help)

Am I missing something?

1 Like

The problem is the screen is not getting cleared before each frame. The easiest way to fix this is to add clear() to the beginning of update():

local gfx <const> = playdate.graphics -- at the top of file

function playdate.update()
    gfx.clear(gfx.kColorWhite)
    gfx.drawText("Amount: " .. waterAmount, 5, 5)
end

However, this is not the most optimized way to do it, as using clear() will force the entire screen to refresh every frame. If you enable "Highlight Screen Updates" in the Simulator, you will see the entire screen is highlighted.

A more optimized way to do this is to use the gfx.sprite.setBackgroundDrawingCallback. Here is how it might look:

import 'CoreLibs/sprites' -- at the top of file
local gfx <const> = playdate.graphics -- at the top of file

function myGameSetUp()
    gfx.sprite.setBackgroundDrawingCallback(
        function( x, y, width, height )
            gfx.clear(gfx.kColorWhite)
        end
    )
end

myGameSetUp()

function playdate.update()
	gfx.sprite.update() -- this must happen before drawText()
    gfx.drawText("Amount: " .. waterAmount, 5, 5)
end

This code is based on the Basic Game Template in the documentation. Using this method, you will notice that the only thing that gets redrawn is the text region (and whatever else you are drawing). Make sure you put gfx.sprite.update() before drawing the text, or the background will just draw over it.

4 Likes

Thank you so much! This is really helpful to know.

1 Like

if I remember the code correctly, the setClipRect/clearClipRect calls are redundant, fyi--sprite draw callbacks are always clipped to the updated rect. Regardless, that is a super clever use of the sprite system! Never would have crossed my mind.. :smiley:

Hm, you're right. Removing setClipRect and clearClipRect results in the same screen updates. I was just following the code in the Basic Playdate Game in Lua. Do you know why it's used in the documentation? Do you only need to set the clip rect when you are not using the sprite system?

Nope, you don't need to set the clip rect unless you want to change how drawing is getting clipped. If you need to draw outside the sprite bounds you can call clearClipRect so it doesn't get clipped. (Tangentially: if you don't call setSize() or setBounds() on the sprite before drawing, it has an empty clip rect and nothing gets drawn. I'm planning on changing that so it doesn't set the clip rect when the sprite's size is zero.) I think in practice there aren't a lot of places you need to worry about the clip rect.

I fixed the docs, removed the setClipRect() and clearClipRect() calls there and added a note that the x,y,width,height args are just giving you the updated area of the sprite, if you need that for some reason.

3 Likes