Text/dialog boxes + animated text

Okay, a few questions; first of all, I'm trying to make a classic text-box that overlays the regular gameplay. Just think like text from a Pokemon game on Gameboy or something. I can't for the life of me get the text to show on top of my sprites? Is there a z-index argument I've missed somewhere? None of the text or font functions seem to have a z-index. I feel like I'm missing something really basic here, but I couldn't find anything like this in any of the example files either.

Secondly (and this is just a dream feature probably but) I'd love to be able to animate the text being "typed" out on screen, and not just pop up all at once. I could probably split the string up into chunks (or even single letters) and put them in an array and loop through them, which shouldn't be too heavy for the CPU/memory, but if there is a simpler way that would be cool.
This all depends on me solving my first problem though.

I’m not sure how you’re attempting to do it now, but this is how I do it in my game:

  1. Set up your game sprites, probably the way you already do;
  2. Make the text box a sprite in itself. Don’t think of sprites as “game characters”; they’re a great solution to basically every piece of graphics you’re putting on screen;
  3. In the text sprite’s draw() callback, step through the characters one by one and add them to the drawn string. Add a timer to draw them with a delay.

That’s the high-level overview of it. If an example would be useful, I’ll see about making one.

3 Likes

Neven's solution is excellent and the recommended way.

I think this is an aspect of the Sprite system that is not talked about enough. Perhaps even in the docs.

The lesson is: make everything a sprite.

2 Likes

I agree, sprites are amazing and I make everything into sprites if I can. But how do I make a text or font object into a sprite?

How do I get this:

playdate.graphics.drawText(text, x, y, [fontFamily, [leadingAdjustment]])

Into a sprite?

2 Likes

You make a sprite with image big enough to fit text, lockfocus to the image used by that sprite, and then when you draw the text it will be drawn to that image (rather than the screen buffer). Finally unlockfocus and continue.

2 Likes

Matt is describing an approach where you use sprite:setImage() and either lockFocus or pushContext() to draw into that image. That's what I do most of the time. Another approach is to put your drawing calls inside the sprite:draw() function.

Here's a complete example. I tried to comment the code to explain how it all works. After launching it, press A to show the textbox. It currently draws one letter per frame; you could base it on a timer instead. I hope this helps!

typewriter.zip (9.0 KB)

9 Likes

Thanks! That worked perfectly! I really need to get better at pushing the context like that. It's still a weird concept for me.

1 Like

Note that the context pushing is not even necessary in my example—drawing inside the sprite:draw() is the real win :slightly_smiling_face:

2 Likes

I just reviewed this chain and can get the text boxes to appear on their own (I looked at the typewriter example that is referenced in this chain) but I am having a difficult time calling text boxes when certain conditions are met. For example, say instead of making the text box appear each time the "A" button is pressed (via the function in the example) I want a variable that counts how many times the "A" button get pressed, then makes the text box appear once the "A" button has been pressed 5 times. How would I go about doing that? I have tried writing a simple if statement in the main.lua update piece that adds the textbox.text and textbox:add() parts that are in the typewriter example but nothing shows up. The parameters for textbox are in my main.lua file so I am sort of stumped why nothing appears. I have never used text/dialog boxes before and decided that would be a better approach than trying to draft unique art for each message to the player.