Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Words and fonts

A game talks: a score in the corner, a name over a door, a friend with something to tell you. You’ve met PRINT and LOCATE already. This lesson is about making words look the way you want and putting them exactly where you want them.

A font of your own

My own letters are chunky and plain. LOADFONT loads a TrueType or OpenType font from the game’s folder under a name, and SETFONT says how big to write and in which font. FONT RESET goes back to mine.

SCREEN 320, 240
LOADFONT "font.ttf", "story"
SETFONT 24, "story"
PRINT "Once upon a time"
SETFONT 12
PRINT "...in a city far, far away"
FONT RESET
PRINT "back to my letters"
Once upon a time
...in a city far, far away
back to my letters

SETFONT without a font name changes only the size, so the second line is still in "story", just smaller.

Exactly where

LOCATE counts rows and columns, which is lovely for lining things up but coarse when you want a word at a particular pixel. !! origin gives the pixel the rows and columns count from: LOCATE 1, 1 !! origin((200, 8)) puts the cursor at x 200, y 8.

COLOR sets the color of the words, and PRINT !! same_line leaves the cursor at the end of what it printed, so the next PRINT carries on along the same line. Together, they make a score with a label in one color and the number in another:

SCREEN 320, 240
score = 0
lives = 3
DO
    IF COOLDOWN(1)
        score = score + 7
        FRAME
            CLS
            LOCATE 1, 1 !! origin((8, 8))
            COLOR 14
            PRINT "SCORE " !! same_line
            COLOR 15
            PRINT score
            LOCATE 1, 1 !! origin((240, 8))
            COLOR 12
            PRINT "LIVES " !! same_line
            COLOR 15
            PRINT lives
        END FRAME
    END IF
LOOP

Crash-tan’s Tip: COLOR 15, 1 gives the words a blue background as well, which keeps them easy to read over a busy picture.

Somebody talking

Two more of PRINT’s modifiers are for conversations. words wraps a long line at the edge of the screen between words, never in the middle of one. rate types it out a letter at a time, this many milliseconds apart, the way role-playing games always have.

PRINT doesn’t wait for the typing to finish, so your game carries on while it goes. typing is TRUE until the last letter is out. Here the hero bobs up and down while I talk, and stops when I’m done:

SCREEN 320, 240
LOADIMG "hero.png", "tan"
MEMORYBUFFER "box"
    LINE (0, 172) -> (319, 239), 1 !! box fill
    LINE (0, 172) -> (319, 239), 15 !! box
END MEMORYBUFFER
PUTIMAGE (0, 0), "box"

ENABLE SPRITE 0
SET SPRITE 0 !! image("tan") x(240) y(132)
SHOW SPRITE 0

COLOR 15, 1
LOCATE 1, 1 !! origin((8, 180))
PRINT "Hi! I'm Crash-tan, and this is my city. Mind the explosions: they're mostly harmless." !! rate(40) words

bob = 0
DO WHILE typing
    IF COOLDOWN(5)
        bob = 1 - bob
        SET SPRITE 0 !! y(132 - bob * 3)
    END IF
LOOP
SET SPRITE 0 !! y(132)
LOCATE 1, 1 !! origin((200, 224))
PRINT "press a key"
PAUSE

Try a rate of 10 for somebody in a hurry, or 120 for somebody very, very sleepy.

Words you can move

Printed words stay where they’re printed. TEXTTOIMAGE writes words into a picture instead: the text, a name for the picture, and if you like, a size and a font. A picture can be stamped with PUTIMAGE, scaled, spun, or shown by a sprite, so here’s a title that drops in and then floats:

SCREEN 320, 240
LOADFONT "font.ttf", "story"
LOADIMG "city.png", "city"
PUTIMAGE (0, 0), "city" !! scale_to((320, 240))
TEXTTOIMAGE "CRASH CITY", "title", 32, "story"

ENABLE SPRITE 0
SET SPRITE 0 !! image("title") x(160) y(-20) origin((0.5, 0.5))
SHOW SPRITE 0

y = -20
t = 0
DO
    IF COOLDOWN(1)
        IF y < 90 THEN y = y + 3
        t = t + 1
        SET SPRITE 0 !! y(y + sin(t / 15) * 4)
    END IF
LOOP

The words are a sprite now, so I draw them every frame without any PRINT at all.

A screen of letters

Some games are nothing but letters: a text adventure, a roguelike, a terminal in a spaceship. SCREEN TEXT opens a screen measured in characters, columns across and rows down, in place of pixels.

SCREEN TEXT 40, 25
COLOR 14
LOCATE 2, 14
PRINT "THE DARK CAVE"
COLOR 7
LOCATE 5, 3
PRINT "You are standing at the mouth of a cave."
LOCATE 6, 3
PRINT "A cold wind blows from inside."
COLOR 10
LOCATE 9, 3
PRINT "> go north"
THE DARK CAVE
You are standing at the mouth of a cave.
A cold wind blows from inside.
> go north

!! modern swaps my plain ASCII letters for my modern character set.

A pointer of your own

SET CURSOR turns any picture into the mouse pointer, and !! hotspot says which of its pixels is the tip. SET CURSOR !! off brings the ordinary pointer back.

SCREEN 320, 240
MEMORYBUFFER "arrow", 12, 12
    POLYGON [(0, 0), (11, 5), (5, 6), (4, 11)], 15, 14
END MEMORYBUFFER
SET CURSOR "arrow" !! hotspot((0, 0))
PRINT "Move the mouse over the screen, then press a key."
PAUSE
SET CURSOR !! off

The arrow’s tip is its top-left pixel, (0, 0), so that’s the pixel the pointer is pointing at.