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

Sound files

PLAY and its notes are perfect for blips and tunes. Some sounds, though, nobody could write as notes: an explosion, a voice, a real drum. Those come from a recording, in a file in your game’s folder, and I play them as they were recorded.

There are two kinds. A WAV is for short sounds that go off again and again, like a jump or a blast. An MP3 is for longer ones, like a voice or a whole song: it’s much smaller than a WAV of the same length.

Short sounds

LOADWAV loads a WAV under a name, once, at the start. After that, PLAYWAV plays it whenever you like, by that name. Click the screen and press Space:

SCREEN 320, 240
LOADWAV "explosion.wav", "boom"
flash = 0
was_down = FALSE
DO
    IF COOLDOWN(1)
        down = keydown("Space")
        IF down AND NOT was_down
            PLAYWAV "boom"
            flash = 40
        END IF
        was_down = down
        IF flash > 0 THEN flash = flash - 2
        MEMORYBUFFER "scene"
            IF flash > 0 THEN CIRCLE (160, 120), flash, 14, 12
        END MEMORYBUFFER
        FRAME
            CLS
            PUTIMAGE (0, 0), "scene"
            LOCATE 1, 1
            PRINT "Press Space!"
        END FRAME
    END IF
LOOP

keydown says the key is held for as long as it’s held, and holding Space shouldn’t set off sixty explosions a second. So the loop remembers whether Space was down last time, and only plays the sound when it goes down.

PLAYWAV can take two more things: whether to loop the sound, and how loud to play it, from 0 to 1. !! at((x, 0)) says where it’s heard: x runs from -1, all the way left, to 1, all the way right, and 0 is the middle.

SCREEN 320, 240
LOADWAV "explosion.wav", "boom"
PLAYWAV "boom", FALSE, 0.5 !! at((0.8, 0))
PRINT "a quieter boom, over on the right"
PAUSE
a quieter boom, over on the right

Crash-tan’s Tip: To hear a sound where something is on the screen, turn its x into that range: on a screen 320 across, x / 160 - 1 is -1 at the left edge, 0 in the middle and 1 at the right.

STOPWAV "boom" stops it, which matters most for a sound that loops. STOPWAV with no name stops every WAV that’s playing.

Crash-tan’s Tip: Load every sound before the game starts, beside the images. Loading reads a file, and a file read in the middle of a fight is a hiccup the player can feel.

Long sounds

MP3s go the same way, with their own words: LOADMP3 and PLAYMP3. My book comes with two voice clips, ready.mp3 and go.mp3, which are just what the start of a race needs:

SCREEN 320, 240
LOADMP3 "ready.mp3", "ready"
LOADMP3 "go.mp3", "go"
PLAYMP3 "ready"
ticks = 0
DO
    IF COOLDOWN(1)
        ticks = ticks + 1
        IF ticks = 60 THEN PLAYMP3 "go"
        FRAME
            CLS
            LOCATE 15, 18
            IF ticks < 60
                PRINT "READY?"
            ELSE
                PRINT "GO!"
            END IF
        END FRAME
    END IF
LOOP

ticks counts sixty to a second, so “go” comes a second after “ready”. Counting ticks is how a game says “a little later” without stopping.

PLAYMP3 also takes whether to loop and how loud, the same as PLAYWAV. That’s how background music from a file goes: PLAYMP3 "song", TRUE, 0.6.

Fading

A song that stops dead sounds like a mistake. FADEMP3 fades an MP3 out over as many seconds as you say, or fades one in, starting it from silence if it isn’t playing yet. One faded in goes round and round until it’s faded out or stopped.

FADEMP3 doesn’t wait for its fade: your program carries on at once. So this one counts ticks, sixty a second, to give each fade its time, and to hear the song in between.

SCREEN 320, 240
LOADMP3 "ready.mp3", "ready"
FADEMP3 "in", "ready", 0.5
PRINT "fading in"
ticks = 0
DO WHILE ticks < 120
    IF COOLDOWN(1) THEN ticks = ticks + 1
LOOP
FADEMP3 "out", "ready", 1
PRINT "and out again"
ticks = 0
DO WHILE ticks < 60
    IF COOLDOWN(1) THEN ticks = ticks + 1
LOOP
fading in
and out again

STOPMP3 stops one at once, by name, or every MP3 with no name.

Turning it down

SET AUDIO changes a sound while it plays: its volume, from 0 to 1, and its pan, from -1 (all the way left) to 1 (all the way right). It works on a WAV, an MP3 or the music, by name. Here a looping sound follows the mouse from one ear to the other:

SCREEN 320, 240
LOADWAV "explosion.wav", "boom"
PLAYWAV "boom", TRUE
DO
    IF COOLDOWN(1)
        side = mousex / 160 - 1
        SET AUDIO "boom" !! pan(side) volume(0.6)
        FRAME
            CLS
            LOCATE 1, 1
            PRINT "pan", fixed_str(side, 2)
        END FRAME
    END IF
LOOP

Letting go

A loaded sound stays in memory until the game ends. That’s fine for the sounds a game uses all the time. For a big one it needs only once, like the song for the title screen, FREE MP3 (or FREE WAV) stops it and lets the memory go. Here the title screen plays its song for a second, then the game starts and lets it go.

SCREEN 320, 240
LOADMP3 "ready.mp3", "title"
PLAYMP3 "title"
ticks = 0
DO WHILE ticks < 60
    IF COOLDOWN(1) THEN ticks = ticks + 1
LOOP
FREE MP3 "title"
PRINT "the title song is gone"
the title song is gone

A file or notes?

Both have their place, and most games use both.

  • A file for anything recorded: voices, real instruments, explosions, and a song somebody made in a music program.
  • Notes for sounds that should change with the game. A coin’s blip can go up a note for every coin in a row, and a song written as notes can speed up when the timer runs low. Notes take no space at all, and there’s no file to forget to put in the folder.

The next two lessons are about notes going a long way: instruments of your own, and whole songs.