TUTORIAL · BREAKOUTBETA
Breakout
BRICKFALL is a brick breaker for the BBC Master, written in BBC BASIC IV with the EGFX ROM doing the drawing and EAudio doing the sound. You build it in eight stages, each one a program that runs, from a title screen to the finished game.

Download and run
Downloads arrive with the beta release.
| Sideways slot | Image | Needed by |
|---|---|---|
| 4 and 6 | EGFX.rom and EGFX2.rom (EGFX is 32 KB, so it comes as two images) | everything |
| 7 | EGASSETS.rom, the game's sprite art | stage 3 onwards |
| 5 | EAUDIO.rom | stage 8 (the finished game) |
In B-em choose Master 128, load the ROM images into those slots, switch sound on, insert breakout.ssd and press SHIFT+BREAK: the disc boots straight into the finished game. SPACE on the title screen, SPACE again to serve, Z and X to move, Q to quit. Any stage runs with CHAIN "STAGE3" and so on. Beeb-dev users can declare the same set-up in beeb-dev.ini with rom_4 to rom_7.
Build it in eight stages
The stages are cut from the finished game, not written separately, so every line you type is a line of the real game with the same line number. Each page lists the lines that are new or changed since the stage before (classic magazine type-in style), explains them, and has the whole stage underneath. A few lines arrive early in a cut-down form, for example the ball's miss line before there are any lives to lose, and come back in full later on.
- 1 · Title screen
- 2 · The bat
- 3 · The ball
- 4 · Bricks
- 5 · Strong bricks and levels
- 6 · Score and HUD
- 7 · Lives, game over and restart
- 8 · Sound
Under the hood
How the faster parts work, for when you want more than the stage pages explain.
- A · Sprites from a companion ROM
- B · Repainting only what moved
- C · The bat blit
- D · Measuring the frame
What is finished
The game has a title screen, a bat and ball, six rows of bricks taking up to three hits, score, level and lives, GAME OVER and restart, endless levels that get faster, and sound. It runs at about 5 frames a second in play, which is what interpreted BASIC on a 2 MHz 6502 can manage with this much going on. The bricks do not show their remaining strength, and the ball has no speed limit.
The complete game, ready to type in: the EGFX helpers merged and the notes stripped (93 BASIC lines)
5 MODE 1:HIMEM=&2400
20 PROCeginit:PROCegcompanion(7,&81,255):DIM E% 15:!E%=&1040:$(E%+2)="EAUD":E%?6=0:PROCe:E%?6=7:E%?8=3:PROCe
30 DIM a%(5,7):l%=1:e%=4:f%=-4:sc%=0:lv%=3:hd%=0:PROCresetlevel
40 PROCstartscreen
50 p%=152:b%=160:y%=192:sv%=1:d%=4:u%=b%:v%=y%:w%=p%:aa%=b%:bb%=y%:cc%=p%:S%=0:G%=0
60 REPEAT:IF d%>=3 PROCegbegin:PROCdrawbricks:PROCdrawhud:PROCbatdraw(p%):PROCegpresent:PROCegbegin:PROCdrawbricks:PROCdrawhud:PROCbatdraw(p%):PROCegpresent:d%=0:aa%=p%:u%=p%:bb%=192:v%=192
65 PROCegdirtybegin
75 z%=INKEY(-98):x%=INKEY(-67):sp%=INKEY(-99)
80 IF z% p%=p%-12
90 IF x% p%=p%+12
100 IF p%<8 p%=8
110 IF p%>288 p%=288
120 IF sv%=1 b%=p%+8:y%=192:IF sp% sv%=0
127 IF lv%=0 AND sp% G%=0:l%=0:sc%=0:lv%=3:PROCnextlevel:e%=4:f%=-4
130 IF sv%=0 PROCmoveball
150 IF aa%<>b% OR bb%<>y% PROCegcompact(aa%,bb%,1,0,7,&87)
155 IF cc%<>p% PROCbatclear(cc%)
160 IF d%>0 AND d%<3 PROCbe
161 IF d%>0 AND d%<3 d%=d%-1
170 IF hd% hd%=hd%-1:IF hd%<2 PROCdrawhud
175 IF G% PROCegtext("GAME OVER",120,140):PROCegtext("PRESS SPACE",112,156):G%=G%-1
180 IF cc%<>p% OR (bb%<=205 AND bb%+7>=202 AND aa%<=p%+15 AND aa%+7>=p%) PROCbatdraw(p%)
181 IF sv%<>2 PROCegcompact(b%,y%,0,0,7,&87)
185 aa%=u%:bb%=v%:cc%=w%:u%=b%:v%=y%:w%=p%:IF S% E%?6=3:E%?8=S%-1:PROCe:S%=0
190 PROCegpresent
200 UNTIL INKEY(-17)
210 MODE 7:END
220 DEF PROCstartscreen
230 PROCegbegin:FOR y%=24 TO 88 STEP 8:PROCegline(40,y%,280,y%,(y% DIV 8) MOD 4):NEXT:PROCegtext("BRICKFALL",120,48):PROCegline(64,80,256,80,3)
240 PROCegtext("PRESS SPACE",112,176):PROCegpresent
250 REPEAT:UNTIL INKEY(0)=32:*FX 15
260 ENDPROC
300 DEF PROCmoveball
310 nx%=b%+e%:ny%=y%+f%
320 IF nx%<=8 nx%=8:e%=-e%:S%=9
325 IF nx%>=288 nx%=288:e%=-e%:S%=9
330 IF ny%<24 ny%=24:f%=-f%:S%=9
340 IF ny%>240 sv%=1:f%=-4:nx%=p%+8:ny%=192:lv%=lv%-1:hd%=2:S%=3:IF lv%=0 S%=1:G%=2:sv%=2
350 IF ny%<=205 AND ny%+7>=202 AND f%>0 AND nx%+3>=p% AND nx%+3<p%+16 ny%=194:f%=-f%:e%=e%+SGN(nx%+3-p%-8):S%=5
355 IF ny%>107 OR ny%+7<40 OR nx%+7<64 OR nx%>247 GOTO 380
360 r0%=(ny%-40)DIV12:IF r0%<0 r0%=0
362 r1%=(ny%+7-40)DIV12:IF r1%>5 r1%=5
364 c0%=(nx%-64)DIV24:IF c0%<0 c0%=0
366 c1%=(nx%+7-64)DIV24:IF c1%>7 c1%=7
368 h%=0:FOR rr%=r0% TO r1%:FOR ct%=c0% TO c1%
370 IF h%=0 AND a%(rr%,ct%)>0 PROCbrickhit
372 NEXT:NEXT
380 b%=nx%:y%=ny%:ENDPROC
382 DEF PROCbrickhit
384 IF nx%>79+ct%*24 OR nx%+7<64+ct%*24 OR ny%>47+rr%*12 OR ny%+7<40+rr%*12 ENDPROC
385 IF d%=1 PROCbe
386 h%=1:hr%=rr%:hc%=ct%:d%=2
388 IF y%+7<40+rr%*12 OR y%>47+rr%*12 f%=-f% ELSE e%=-e%
390 nx%=b%+e%:ny%=y%+f%
392 IF a%(rr%,ct%)>1 a%(rr%,ct%)=a%(rr%,ct%)-1:S%=9:ENDPROC
394 a%(rr%,ct%)=0:n%=n%-1:sc%=sc%+10:hd%=4:S%=7:IF n%=0 S%=4:PROCnextlevel
396 ENDPROC
400 DEF PROCresetlevel:n%=0:FOR r%=0 TO 5:FOR c%=0 TO 7
402 s%=1:IF l%>1 s%=1+((r%+c%+l%)MOD 3)
404 a%(r%,c%)=s%:n%=n%+1:NEXT:NEXT:ENDPROC
410 DEF PROCnextlevel:l%=l%+1:e%=4+l%:f%=-e%:PROCresetlevel:sv%=1:d%=4:hd%=2:ENDPROC
420 DEF PROCdrawbricks:FOR r%=0 TO 5:egb%?8=8:FOR c%=0 TO 7:egb%?(16+c%*5)=2+r%:egb%?(17+c%*5)=(64+c%*24) AND 255:egb%?(18+c%*5)=0:egb%?(19+c%*5)=40+r%*12:egb%?(20+c%*5)=0:NEXT:PROCegcall(34):NEXT:ENDPROC
440 DEF PROCdrawhud:PROCegtext("SCORE "+RIGHT$("00000"+STR$(sc%),5)+" LEVEL "+RIGHT$("00"+STR$(l%),2)+" LIVES "+STR$(lv%),8,8):ENDPROC
500 DEF PROCbatclear(x%):bt%=&6E82+2*x%:FOR q%=0 TO 3:!bt%=0:bt%=bt%+8:NEXT:ENDPROC
510 DEF PROCbatdraw(x%):bt%=&6E82+2*x%:FOR q%=0 TO 3:!bt%=&FF0F0FFF:bt%=bt%+8:NEXT:ENDPROC
520 DEF PROCe:A%=&C0:X%=E%:Y%=E%DIV256:CALL&FFF1:ENDPROC
530 DEF PROCbe:PROCegcompact(64+hc%*24,40+hr%*12,9+SGN(a%(hr%,hc%))*(hr%-7),0,7,&81):ENDPROC
1000 DEF PROCeginit
1010 IF HIMEM>&2400 OR TOP>&2200 PRINT "EGFX MEM":END
1020 DIM egb% 63:LOCAL egi%
1025 FOR egi%=0 TO 63:egb%?egi%=0:NEXT
1040 egb%?0=64:egb%?1=8:egb%?2=69:egb%?3=71:egb%?4=1
1045 PROCegcall(0):ENDPROC
1050 DEF PROCegcall(egf%)
1070 egb%?5=egf%:egb%?7=0
1080 A%=&C0:X%=egb% MOD 256:Y%=egb% DIV 256:CALL &FFF1
1090 IF egb%?7<>&A5 PRINT "NO EGFX ROM":END
1095 IF egf%>=11 AND egf%<>22 AND egf%<>23 AND egb%?6<>0 PRINT "EG ERROR":END
1100 ENDPROC
1110 DEF PROCegxy(egx%,egy%)
1120 egb%?8=egx%:egb%?9=egx% DIV 256
1130 egb%?10=egy%:egb%?11=egy% DIV 256:ENDPROC
1140 DEF PROCegbegin:PROCegcall(1):ENDPROC
1144 DEF PROCegdirtybegin:egb%?8=255:PROCegcall(38):ENDPROC
1150 DEF PROCegpresent:PROCegcall(6):ENDPROC
1180 DEF PROCegtext(egs$,egx%,egy%)
1190 PROCegxy(egx%,egy%):$(egb%+22)=egs$+CHR$0:PROCegcall(7):ENDPROC
1260 DEF PROCegline(egx%,egy%,egex%,egey%,egc%)
1270 PROCegxy(egx%,egy%):egb%?13=egc%:egb%?16=egex% AND 255:egb%?17=(egex% AND &FFFF) DIV 256
1280 egb%?20=egey% AND 255:egb%?21=(egey% AND &FFFF) DIV 256:PROCegcall(10):ENDPROC
1820 DEF PROCegcompanion(b%,p%,h%):egb%?8=b%:egb%?9=p%:egb%?10=h%:PROCegcall(33):ENDPROC
2110 DEF PROCegcompact(x%,y%,i%,f%,b%,p%)
2120 PROCegxy(x%,y%):egb%?12=i%:egb%?14=f%:egb%?16=b%:egb%?17=p%:PROCegcall(37):ENDPROC