A Shape That Moves
Give a shape a life of its own. The animation loop is erase, move, draw, repeat — and a direction variable you flip at the edges makes a ball bounce. Meet the flicker that sends C64 game-writers to assembly.
Last unit the ball moved only when you pushed the stick. This unit it moves on its own. That's animation, and on the C64 it's one idea repeated forever: erase where the shape was, move it, draw it where it's going. Do that in a loop and a character comes to life — and you meet the reason the C64's famous games aren't written in BASIC.
Milestone 1 — a shape crosses the screen
Take Unit 9's screen POKE, add one to the column each pass, and erase the old cell before
drawing the new one:
10 PRINT CHR$(147)
20 POKE 53281,0
30 X=0:Y=12
40 POKE 1024+Y*40+X,32
50 X=X+1
60 IF X>39 THEN X=0
70 POKE 1024+Y*40+X,81
80 POKE 55296+Y*40+X,1
90 FOR T=1 TO 30
100 NEXT T
110 GOTO 40
Line 40 erases the ball's current cell with a space; line 50 adds one to X; line 60 wraps
it back to the left edge; lines 70–80 draw the ball at the new spot. GOTO 40 repeats it
forever. RUN it and the ball glides right, wrapping round:
Forget line 40 and the ball smears into a solid line — every old position stays drawn. Erasing the old cell is half of animation. Drawing the new one is the other half.
Milestone 2 — make it bounce
To bounce, the ball needs a direction. Keep it in a variable, DX, that's +1 for
right or -1 for left, and flip its sign at each wall:
10 PRINT CHR$(147)
20 POKE 53281,0
30 X=20:Y=12:DX=1
40 POKE 1024+Y*40+X,32
50 X=X+DX
60 IF X=0 OR X=39 THEN DX=-DX
70 POKE 1024+Y*40+X,81
80 POKE 55296+Y*40+X,1
90 FOR T=1 TO 20
100 NEXT T
110 GOTO 40
X = X + DX moves by the direction instead of always adding one. Line 60 watches for the
edges — at column 0 or 39, DX = -DX reverses it. The ball runs to the wall and comes
back:
A variable that holds which way something is heading — DX here — is in every moving
thing you'll ever write: a bullet, an enemy, a falling block.
Milestone 3 — bounce in two directions
One direction variable bounces left and right. Two — DX and DY — bounce in a full
square, off all four walls:
10 PRINT CHR$(147)
20 POKE 53281,0
30 X=20:Y=12:DX=1:DY=1
40 POKE 1024+Y*40+X,32
50 X=X+DX:Y=Y+DY
60 IF X=0 OR X=39 THEN DX=-DX
70 IF Y=0 OR Y=24 THEN DY=-DY
80 POKE 1024+Y*40+X,81
90 POKE 55296+Y*40+X,1
100 FOR T=1 TO 20
110 NEXT T
120 GOTO 40
Line 50 moves both X and Y by their directions; line 60 flips DX at the left and right
walls; line 70 flips DY at the top and bottom. The ball travels on the diagonal and bounces
off every edge — the screensaver everyone's seen:
When it doesn't work
- The ball leaves a trail. You didn't erase the old cell. Poke a space (
32) at the old position before moving — line 40, every loop. - It flickers. It does — and that's the lesson. BASIC erases and redraws one cell at a time, and it isn't fast enough to finish before the screen is drawn, so you catch the ball mid-blink. There's no fixing it in BASIC.
?ILLEGAL QUANTITY ERRORat a wall. The ball stepped past the edge before bouncing. Test the exact edge values (0and39across,0and24down) so the flip happens on the wall, not after it.- Too fast to see. Add or lengthen the
FOR T … NEXTdelay; shorten it to speed the ball up.
Before and after
You started with a ball that moved only under your hand and finished with one that moves, bounces, and travels the diagonal by itself. The idea underneath: animation is erase, move, draw, repeat — and a direction variable you flip at the edges is how anything bounces.
Try this
- A faster bounce. Use
DX = 2and watch the ball skip cells — and notice it can now step past39, so the edge test needsX >= 39, notX = 39. - A second ball. Give it its own
X2,Y2,DX2,DY2and run both in the loop. - Change colour on the bounce. Poke a new colour into the ball's colour cell each time
DXorDYflips, so it changes shade off every wall.
What's next
The flicker is real, and it's why the C64's legends wrote games in assembly: the machine has sprites — hardware shapes that move smoothly, with no erase-and-redraw — but BASIC can't reach them well. That's a later course. First, one practical thing every programmer needs: in Unit 14 we save and load your work, so a program outlives the power switch.