Skip to content

Put the paddle under your control

Build a rounded character paddle and attach the ball until serving.

  • Sinclair ZX Spectrum
  • BASIC

Give the player somewhere to catch the ball. The paddle moves in character columns, while the ball keeps its pixel coordinates. We will connect the two while the ball waits to be served.

Replace lines 10, 100, 110, 1020, 1090.

Add lines 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 1080, 7000, 7020, 7230, 7240, 7250.

changes.bas
  10 GO SUB 7000
 100 LET p=14: LET x=127: LET y=40
 110 LET dx=4: LET dy=4: LET served=0: LET steps=0
 230 LET oldp=p
 240 IF k$="o" OR k$="O" THEN LET p=p-1
 250 IF k$="p" OR k$="P" THEN LET p=p+1
 260 IF p<2 THEN LET p=2
 270 IF p>26 THEN LET p=26
 280 IF p<>oldp THEN PRINT AT 18,oldp;"    ";AT 18,p; INK 7;p$
 290 IF served=1 THEN GO TO 350
 300 IF k$=" " THEN LET served=1: PRINT AT 1,2;"Watch the ball bounce. ": GO TO 350
 310 IF p=oldp THEN GO TO 200
 320 GO SUB 3000: LET x=8 *p+15: GO SUB 3000: GO TO 200
1020 PRINT AT 1,2;"SPACE serves. O/P move."
1080 PRINT AT 18,p; INK 7;p$
1090 PRINT AT 21,2; INK 5;"O/P move  R retry  Q quit";
7000 RESTORE 7230: FOR j=24 TO 47: READ v: POKE USR "a"+j,v: NEXT j
7020 LET p$=CHR$ 147 +CHR$ 148 +CHR$ 148 +CHR$ 149: RETURN
7230 DATA 63,127,127,63,0,0,0,0
7240 DATA 255,255,255,255,0,0,0,0
7250 DATA 252,254,254,252,0,0,0,0

RUN the changed program.

Complete source at this checkpoint
brick-bash.bas
  10 GO SUB 7000
 100 LET p=14: LET x=127: LET y=40
 110 LET dx=4: LET dy=4: LET served=0: LET steps=0
 130 GO SUB 1000: GO SUB 3000
 200 LET k$=INKEY$
 210 IF k$="q" OR k$="Q" THEN GO TO 9000
 220 IF k$="r" OR k$="R" THEN GO TO 100
 230 LET oldp=p
 240 IF k$="o" OR k$="O" THEN LET p=p-1
 250 IF k$="p" OR k$="P" THEN LET p=p+1
 260 IF p<2 THEN LET p=2
 270 IF p>26 THEN LET p=26
 280 IF p<>oldp THEN PRINT AT 18,oldp;"    ";AT 18,p; INK 7;p$
 290 IF served=1 THEN GO TO 350
 300 IF k$=" " THEN LET served=1: PRINT AT 1,2;"Watch the ball bounce. ": GO TO 350
 310 IF p=oldp THEN GO TO 200
 320 GO SUB 3000: LET x=8 *p+15: GO SUB 3000: GO TO 200
 350 LET nx=x+dx: LET ny=y+dy
 360 IF nx<16 THEN LET nx=32 -nx: LET dx=ABS dx
 370 IF nx>238 THEN LET nx=476 -nx: LET dx=-ABS dx
 380 IF ny>149 THEN LET ny=298 -ny: LET dy=-ABS dy
 390 IF ny<32 THEN LET e$="Ball reached the bottom.": GO TO 4000
 490 GO SUB 3000
 500 LET x=nx: LET y=ny: LET steps=steps+1
 510 GO SUB 3000: GO TO 200
1000 BORDER 0: PAPER 0: INK 7: CLS
1010 PRINT AT 0,2; INK 5;"BRICK BASH"
1020 PRINT AT 1,2;"SPACE serves. O/P move."
1030 PLOT INK 1;15,16: DRAW INK 1;0,136: DRAW INK 1;225,0: DRAW INK 1;0,-136
1080 PRINT AT 18,p; INK 7;p$
1090 PRINT AT 21,2; INK 5;"O/P move  R retry  Q quit";
1100 RETURN
3000 PLOT INK 7; OVER 1;x,y: DRAW INK 7; OVER 1;1,0: DRAW INK 7; OVER 1;0,1: DRAW INK 7; OVER 1;-1,0: RETURN
4000 PRINT AT 1,0;"                                ";AT 1,2; INK 6;e$
4010 PRINT AT 21,2; INK 7;"R plays again       Q quits   ";
4020 IF INKEY$<>"" THEN GO TO 4020
4030 LET k$=INKEY$
4040 IF k$="q" OR k$="Q" THEN GO TO 9000
4050 IF k$="r" OR k$="R" THEN GO TO 100
4060 GO TO 4030
7000 RESTORE 7230: FOR j=24 TO 47: READ v: POKE USR "a"+j,v: NEXT j
7020 LET p$=CHR$ 147 +CHR$ 148 +CHR$ 148 +CHR$ 149: RETURN
7230 DATA 63,127,127,63,0,0,0,0
7240 DATA 255,255,255,255,0,0,0,0
7250 DATA 252,254,254,252,0,0,0,0
9000 PAPER 0: INK 7: PRINT AT 21,0;"Finished. RUN to try again.     ";: STOP

Draw a rounded paddle

The paddle contains four characters: a left end, two copies of the middle and a right end. Its first four pixel rows are visible; its other four are blank. For the left end, the row bytes are 63,127,127,63,0,0,0,0:

Code
..######
.#######
.#######
..######
........
........
........
........

Across a row, the bit values are 128,64,32,16,8,4,2,1. The first row is 32+16+8+4+2+1=63. The middle uses four rows of 255; the right end mirrors the left with 252,254,254,252.

USR "a" gives the address of the first user-defined graphic. Each character needs eight consecutive bytes. Offsets 24–47 therefore hold characters d, e and f, codes 147–149. We leave a, b and c free for bricks later. This string form of USR locates graphic storage; it is not a machine-code call.

RESTORE 7230 positions the DATA reader. The loop READs each row byte and POKEs it into that storage. CHR$ turns a character code into a one-character string. Line 7020 joins four of them into p$, ready for PRINT.

Columns become pixels

The paddle begins at character column p. Its pixel left edge is 8p; four characters make it 32 pixels wide. At p=14 it covers x=112–143. The attached ball starts at 8p+15=127, so its two columns occupy the middle of the paddle’s width.

The paddle is printed at row 18. That character row spans pixel y=24–31; our four inked rows occupy its upper half. The ball waits above it at y=40.

O subtracts one from p; P adds one. Lines 260–270 clamp p to 2–26. That keeps the paddle’s full width between the side walls. We remember oldp so a change can erase the old four-character string and draw the new one. If p did not change, there is nothing to redraw.

Waiting and flying

served=0 means ready. In that state, moving the paddle toggles the old ball off, recalculates its x and draws it again. SPACE sets served to 1 and enters the movement part of the loop. Once served, line 290 bypasses the attachment code, so the paddle no longer drags the ball along.

The paddle does not catch anything yet. Serving still ends at the bottom stop from the previous lesson.

Why does one paddle step change the attached ball's x by eight rather than one?

Show the explanation

p counts character columns. Each column is eight pixels wide, so increasing p by one increases 8*p+15 by eight.

Hold O and P to reach both limits. Serve, then move the paddle while the ball flies. Try SPACE again: it should not restart the flight. R restores the centred paddle and waiting ball.

If the paddle is letters or scrambled blocks, check the three DATA lines and the offset 24 in the loading loop. If the attached ball leaves a trail, check that line 320 erases before changing x.

Sources

Steven Vickers, edited by Robin Bradbeer, ZX Spectrum BASIC Programming, second edition (Sinclair Research, 1983), chapters 6, 14–16 and 18. Chapter 14: The Character Set describes custom characters and their storage. The court dimensions, collision rules and artwork are choices made for this game.

Run it here

This unit's program, built for you.

Program
brick-bash.tap
Machine
ZX Spectrum 48K (PAL)

Download brick-bash.tap