A whole game
Time to put it together! Stars fall from the sky. Catch them in your basket for a point each, and let three hit the ground and the game’s over.
Every piece of it is something from an earlier lesson:
- the basket and the stars are sprites, showing images drawn in a
MEMORYBUFFER; - the stars fall by themselves, with a behavior;
ONCOLLISIONtells a star it’s been caught, or that it hit the ground;- the keys move the basket, and
COOLDOWNkeeps the loop’s time; CALL RENDERdraws the score every frame, under the sprites;BEEPandSOUNDsay what happened.
SCREEN 320, 240
RANDOMIZE
// --- What things look like ---------------------------------------------
MEMORYBUFFER "basket", 40, 12
LINE (0, 4) -> (39, 11), 6 !! box fill
END MEMORYBUFFER
MEMORYBUFFER "star", 11, 11
POLYGON [(5, 0), (6, 4), (10, 4), (7, 6), (8, 10), (5, 8), (2, 10), (3, 6), (0, 4), (4, 4)], 14, 14
END MEMORYBUFFER
// The ground: a star that reaches it is lost.
BOUNDARY ADD "ground", (0, 236) -> (320, 240)
// --- The score ---------------------------------------------------------
ATOMIC caught = 0
ATOMIC missed = 0
FUNCTION draw()
FRAME
CLS
LOCATE 1, 1
PRINT "caught", caught, " missed", missed, "of 3"
IF missed >= 3
LOCATE 14, 16
PRINT "GAME OVER"
END IF
END FRAME
END FUNCTION
CALL RENDER draw, "score"
// --- Falling stars ------------------------------------------------------
BEHAVIOR "fall"
VELOCITY 0, PARAM("speed", 1)
ONCOLLISION
// A star touching something touches it every tick until it's gone:
// count it only the first time, and not once the game's over.
IF spriteenabled(me) AND missed < 3
IF other_tag = "basket"
caught = caught + 1
DISABLE SPRITE me
ELSE IF other_tag = "ground"
missed = missed + 1
DISABLE SPRITE me
END IF
END IF
END ONCOLLISION
END BEHAVIOR
FUNCTION drop_star()
id = reserve_sprite()
IF id < 0 THEN RETURN
speed = 1 + rnd * 1.5 + caught / 10
SET SPRITE id !! image("star") x(10 + rnd * 290) y(0)
!! tag("star") behavior("fall") behavior_params({speed: speed})
SHOW SPRITE id
END FUNCTION
// --- The basket, and the game ------------------------------------------
basket = reserve_sprite()
x = 140
SET SPRITE basket !! image("basket") x(x) y(220) tag("basket")
SHOW SPRITE basket
DO WHILE missed < 3
// Sixty times a second: move the basket.
IF COOLDOWN(1)
IF keydown("Left") AND x > 0 THEN x = x - 4
IF keydown("Right") AND x < 280 THEN x = x + 4
SET SPRITE basket !! x(x)
END IF
// Every 45 ticks, three quarters of a second: another star.
IF COOLDOWN(45) THEN drop_star()
LOOP
SOUND 220, 0.5
Click the screen, then use the arrow keys.
The score is drawn on layer 0, the bottom one, and the sprites are drawn above it. A layer of its own would have to be cleared to see-through rather than to black, or it would hide the sprites under it.
Make it yours
It’s yours now. Some things to try:
- Faster. Drop a star every 30 ticks instead of 45, or make them fall faster as the score goes up.
- A sound for a catch. Put a
BEEPin theONCOLLISIONwhere a star is caught. - Bad stars. Drop a red one now and then, with a tag of its own, that costs you a point if you catch it.
- A best score. When the game’s over, save
caughtwithSAVETEXTif it’s better than whatloadtextgives back. - A sky. Draw something on layer 0 before the game starts: it stays put under everything, the way the sun did in Drawing on the screen.