Arkanoid (Atari 8-Bit) by Eric Carr
A downloadable game
Arkanoid - BASIC 10Liner Contest 2026
Author: Eric Carr
Language: FastBasic 4.7
Platform: Atari 8-bit
Category: EXTREM-256
Video:
Requirements:
- Atari 8-bit 800/XL/XE or Altirra/Atari800/Fujisan emulator
- Joystick or paddle
About
<<================>>
This is a minimal take on the classic Arkanoid game, with 10 levels and 4 unique power pills.
The main ARKANOID-* entry uses the joystick so those without a paddle can play.
The ARK-PAD-* files are included for those with paddles.
Game play
<<================>>
Your goal is to direct the ball to bounce off solid blocks, which makes them dissapear. Gray blocks take two hits to be removed. Once all solid bricks are removed, you win the level and proceed to the next.
Over time, the ball will get increase in speed, until you lose a life or end the level.
If the ball falls below your ship, you lose a life.
Power Pills
<<================>>
Occasionally, a power pill may drop. Touching it with your ship gives you a benefit.
(E) - Extend your ship width
(C) - Make your ship CATCH balls
(S) - Slows the ball down
(P) - Gives you an additional player life
Input
<<================>>
- Joystick/paddle: moves ship horizontally
- Trigger: Releases caught ball, restarts at game end
- [D] : Press to die and start with a new ball. Use in rare cases where ball repeats in an endless loop
Tools Used
<<================>>
- FastBasic 4.7 Cross Compiler - Compile BASIC to XEX
https://github.com/dmsc/fastbasic/releases/tag/v4.7
- Visual Studio Code - Editing the .BAS file
https://code.visualstudio.com/download
- FastBasic Debugger for VSCode Extension (I wrote it to help debug FastBasic)
https://marketplace.visualstudio.com/items?itemName=EricCarr.fastbasic-debugger
- Atari FontMaker - Defining blocks and gamefield gfx
http://matosimi.websupport.sk/atari/atari-fontmaker/
- Altirra
https://www.virtualdub.org/altirra.html
' Arkanoid - 2026 Basic 10 Liner Contest - EXTREM256 ' <<===============================================>> ' Author : Eric Carr ' ' Input method: Joystick ' Joystick and Paddle sourcecode is identical accept using logic with STICK/STRIG vs PADDLE (PA.)/PTRIG (PT.) ' ' Memory Map ' <<===============================================>> ' $0600 - Music ' $4800 - Display list ' $4C00 - Custom charset ' $5000 - Screen ' $7000 - Levels ' $8000 - PMGraphics ' This array holds 3 sets of data: ' (1) - 11 bytes - Row based block colors (DLI) ' (11) - 11 bytes - X ball angle movement ' (22) - 11 bytes - Y ball angle movement data B() byte = ""$24$ec$86$4a$ba$16$36$56$76$b6""$00$02$02$03$04$04$05$06$06$07$07""$00$0f$0e$0e$0d$0d$0c$0b$09$08$06 dim _dx,_bdx,_bdy,_frame,_note,_vol,_pow,_powY,_lastTime,_catch,_shipExtraWidth,_angle,_speed ' Normal game DLI - colors blocks and the ship DLISET S=B INTO $D017, 12 wsync wsync into $D013 into $D014 into $D015,6 wsync into $D014, 38 into $D013 into $D015 ' Ship explosion DLI - colors blocks only DLISET C=B INTO $D017 ' Set graphics 0 to print without #6, though custom display list is being used for 32x26 graphics 0 ' Clear level so new game begins on program start _level=0 do ' New game loop / next level ' New game if not _level _score=0 _prevLevel=0 _levelP=$7000 _lives=7 endif ' Store custom charset location temporarily in _screen to reduce code size _screen=$4C00 ' Clear screen & charset memory mset _screen,3072,0 ' PROC - Update lives/score on screen proc P pos.25,8:?_lives;" "; ' Append an extra 0 to the score so we don't need to count in tens. Otherwise the score would roll over at 32768 ' since numbers are signed 16 bit integers pos.9,2:?_score;0 endproc ' Copy base character set from ROM to modify M.$E000,_screen,512 ' Move to next level inc _level ' set ball delta (velocity) proc D _bdx=sgn _bdx*b(_angle)*_speed/64 _bdy=sgn _bdy*b(11+_angle)*_speed/64 endproc ' Make alpha numeric characters a single color for this multi-color mode by removing every even bit (85 = binary 01010101) ' This is so space doesn't have to be taken up with a complete custom set of letters and numbers. FOR _screen=_screen to $4FFF:POKE _screen,PEEK _screen&85:NEXT ' At this point, _screen now points to correct location of $5000 ' Draw playfield border/fill for i=0 to 25 j=_screen+32+32*i ' Background fill. Only needs to fill 22 bytes @ j+1, but "j+1" adds 2 characters mset j,23,78+_level&3 ' Left / right edges poke j, 204+(i mod 5<3) poke j+23, peek j next ' Set background color based on level poke 710,32+48*_level&3 do ' Next life _x=102 _by=1456 _speed=92 _catchX=72 ' Clear 12 16bit variables that were DIM'd above ms.&_dx,24,0 ' h is temporary decompress location i=$6902 h=i/2 _sound=i*2 ' Set sound location, which doubles as flag to play intro music ' Start DLI DLI S '[DATA] ' Payload size: 588, Compressed size: 482, RLE from 140 to 154 MOVE &""$5C$DC$DC$92$1C$30$5F$F0$5F$F0$5F$1C$F0$3C$0F$C3$F0$3C$0F$C3$CC$33$CC$30$03$CC$03$30$C0$C0$CF$0C$0C$FC$CC$CF$CF$3C$F3$CC$33$CC$CF$33$06$81$4C$10$8D$44$10$01$F4$02$4C$01$FC$02$FF$02$58$00$00$50$21$00$48$70$70$44$00$50$04$94$84$92$04$84$8C$04$41$00$48$03$2F$02$3D$00$48$01$07$D4$80$01$1D$D0$03$01$0A$D0$00$01$6F$02$11$05$C0$02$8D$9E$0C$01$C7$02$08$20$01$56$E7$3E$FD$3C$BF$7C$E7$00$E7$7E$8C$FD$7E$E7$00$E7$3C$FD$7C$FD$3C$E7$00$E7$7C$BD$BD$7C$FD$E7$00$05$05$55$40$8C$E0$40$08$D0$85$30$8F$70$30$08$D0$86$90$FF$00$08$D0$87$C0$8F$E0$C0$18$00$50$C8$9A$C7$8E$C7$CB$05$39$50$33$23$2F$32$25$05$B9$50$2C$25$36$25$2C$05$39$51$2C$29$36$25$33$01$4D$00$00$02$54$00$05$11$18$00$06$4F$00$4F$42$42$8D$00$47$00$4F$59$00$47$4F$92$00,$69F7,238 MOVE &""$BE$00$70$E1$FF$C1$7F$81$3F$10$1F$02$00$01$C0$01$F0$01$FC$01$FF$C1$FF$D4$FF$01$0E$01$0E$01$0E$01$0E$01$0E$01$15$01$15$81$35$81$24$E1$E4$65$C4$35$84$80$31$49$4A$C1$7B$C1$7B$C1$7B$C1$7B$C1$7B$C1$7B$C1$7B$80$31$55$4A$45$40$C9$60$01$04$09$0A$88$20$01$04$01$04$88$20$01$04$09$0A$01$04$C9$60$54$40$09$11$09$0A$09$0A$05$1F$05$1F$84$35$01$0A$C5$7F$C5$7F$45$5F$45$51$45$51$05$0A$15$0A$08$FF$E2$00$02$00$00$FC$EA$03$02$00$08$FC$F0$03$C5$7F$45$40$45$5F$45$51$45$55$45$51$45$5F$45$40$D5$7F$E5$EE$A4$AA$41$44$E6$EE$85$3B$84$2A$01$11$86$3B$E5$EE$A4$AA$41$44$F4$EE$21$EA$21$8B$A1$EA$61$8A$31$8A$88$08$4E$90$AA$00$90$A8$00$90$FF$00$90$FC$00$55$8E$7F$FF$00$54$8F$FC$8D$00$FF$55$55$FF$FF$8C$00$0F$15$15$1F$1F$8C$54$00$8C$45$00$8C$54$00$8C$44$8D$00$F0$5C,i,246 '[/DATA] ' Decompress RLE data ' reuse _frame since it gets reset later f.j=0t.588 i._frame:de._frame:el.:inci:k=p.i:i.k>139a.k<155:_frame=k-138:inci:k=p.i:e.:e.:p.h+j,k n. ' Process decompressed data (copy it to destinations) WHILE PEEK h MOVE h+3,DPEEK(h+1),PEEK h h=h+PEEK h + 3 WEND ' Packed code sets the cursor location for "level" ?_level; ' Draw level if _level>_prevLevel _prevLevel=_level ' Count blocks as they are drawn ' During play, we decrease it to 0 so we know when level is finished _blocks=0 ' First screen location of potential block h=_screen+149 ' Draw level blocks REPEAT k=dpeek _levelP ' Unpack row bits j=32 for i=0 to 10 ' If bit toggled, draw block if k&j ' Draw block type using bits 3 and 4 d.h,$c2c1+257*k&12 ' If not unbreakable (bit 4), increment block counter _blocks=_blocks+not k&8 endif ' Update screen pointer h=h-2 ' Move to next bit j=j*2 next ' Update screen pointer ahead N lines based on bits 0 and 1 h=h+22+32*k&3 ' Update level data pointer _levelP=_levelP+2 UNTIL k&16 endif ' Update Display (Score + Lives) @p ' Reset sound sound 0,0,0,0 ' Main gameplay - loop until no blocks are remaining while k.<>197 and _blocks '_t=time:for _timeIndex=0 to 49 'Uncomment to show FPS ' *** JOYSTICK CODE *** ' Get joystick direction k=stick 0 k=(n.k&8)-n.k&4 if k ' Reverse direction immediately 'if sgn k <> sgn _dx then _dx = 0 ' Increase paddle movement intent '_dx=_dx+k ' Cap intent ' if _dx>6 ' _dx=6 ' elif _dx<-6 ' _dx=-6 ' endif ' Smaller one liner that does above (27 bytes smaller) _dx=_dx*(sgn k = sgn _dx)+k*(abs _dx<6) ' Move paddle _x=_x+_dx/2 ' Cap paddle left/right positions if _x>139-_shipExtraWidth _x=139-_shipExtraWidth elif _x<67 _x=67 endif else ' Joystick in neutral - clear direction so nudging paddle starts at small incremements _dx=0 endif ' Move ball horizontal position _bx=_bx+_bdx ' Get screen position to test horizontal collision of ball with playfield h=_screen+(_bx/8-63)/4+_by/64*32 ' Get screen character at position i=peek h&63 ' Check if should bounce if i<14 _bdx=-_bdx _bx=_bx+_bdx @_ endif ' Move ball vertically _by=_by+_bdy ' Check if moving downward and low enough to contact paddle/ship if _by>1448 and _bdy>0 ' Calc distance from center of paddle k=_bx/8-_x-7 ' Scale distance if ship is extended width if _shipExtraWidth then k=(k-4)*3/4 ' Shift left one to ensure there is no "0" distance, to avoid ' a pure vertical 90 degree movement direction if k<1 then dec k ' Store absolute distance i=abs k ' Close enough to hit paddle - determine new ball movement delta if i<11 ' Catch ball if power is enabled if _catch*_bdy>1 _by=1456 _bdy=0 _catchX=k*5+64 ' Clear ball mset $84d0,9,0 else ' Otherwise, send ball away _angle=11+i _bdx=k _bdy=-1 @D _note=32:_vol=9 endif elif _by>1536 ' Too far from paddle and too low -lose life exit endif elif _bdy ' Get screen position to test vertical collision of ball with playfield h=_screen+ (_bx/8-63)/4+(_by+_bdy)/64*32 ' Get screen character i=peek h&63 if i<14 ' Remove block @_ _bdy=-_bdy endif else ' If ball is not moving vertically, it is on the paddle. Move with paddle _bx=_x*8+_catchX ' Release ball if trigger pressed _bdy=not strig 0 endif ' Play/fade out current sound effect _frame=_frame&3+1 if _frame=1 and _vol dec _vol if _note<21 then dec _vol sound 0,_note,10,_vol elif _frame=3 and _note>20 sound endif ' Move power pill down if _powY inc _powY move _pow, _powY,8 ' Scrolled off screen - make available for new power to appear if _powY>$83f8 then _powY=0 ' Check if ship touched power pill if dpeek $d009&$e0e ' Clear power pill from screen and make available mset _powY,8,0 _powY=0 ' Clear collision detection poke $D01E,0 ' Powers ' 0 = (S)low ball speed ' 8 = (C)atch ball ' 16= (E)xtended size ' 24= Extra (P)layer _pow=_pow&63 if _pow=0' (S)low ball speed _speed=80 @D elif _pow=24 ' Extra (P)layer life inc _lives else ' Ship altering power ' Set current power for (C)atch _catch=_pow=8 ' 16 = (E)xtended size _shipExtraWidth=_pow&16/2 poke $d00a,_shipExtraWidth/8 endif ' Increment score _score=_score+20 ' Update player stats @p ' Play sound _note=99-_pow:_vol=7 endif endif ' If we haven't changed jiffies, pause until the next if _lastTime=time then pause _lastTime=time ' Draw ball move $5500,$8411 + _by/8,15 pmhpos 0,_bx/8 ' Update paddle/ship horizontal position PMHPOS 1, _x PMHPOS 2, _x+5 PMHPOS 3, _x+14+_shipExtraWidth ' Play level intro music 26 free if _sound ' Finish setting up sound 'poke _sound+4, 0 for k=$600 to $617 pause 4 ' Fade out note if not new if j>$a000 then j=j-256*(1+4*(k<$605)) ' New note - set tone and volume IF p.k then j=p.k+$a800 ' Play two voices, offset second by one pitch increment to give special sound dpoke _sound,j dpoke _sound+2,j+1 next _sound=0 endif 'next:_t=time-_t:pos.25,0:?2500/_t;" ";:if _by>1536 then exit ' Uncomment to test FPS 'if k.:_blocks=0:exit:endif ' Uncomment to press a key to move through levels wend ' Clear ball and powerup from screen mset $8300,512,0 ' Level complete sound and Ship die animation for i=0 to 9 sound 0,i*16,2,9-i ' Explode ship if _blocks dli c mset 705,3,9-i PMHPOS 1, _x-i PMHPOS 3, _x+14+i endif pause next ' Turn off player missle graphics to hide ship poke $d01d,0 ' Check if beat level if _blocks<1 ' On final level, end of game if _level>9 _lives=0 pos.24,18:?"CONGRATS!" else ' Otherwise, proceed= to next level exit endif endif ' Check if game ended ' Wait for trigger press if not _lives while strig 0:wend _level=0 exit endif ' Remove a life dec _lives loop ' next life loop ' next level / new game ' Check if hit a block proc _ ' Did not hit block - exit if i>6 ' Slightly speed up ball with every non breakable block hit if _speed<168 then inc _speed @D exit endif ' Cycle block if hit a "hit twice to break" block k=h-n.h&1 if i>4 ' Two hit block dpoke k,$c4c3 ' Play sound _note=15 _vol=6 else ' Remove block dpoke k,dpeek $5021 ' Play sound _note=21 _vol=9 ' Decrement blocks remaining in this level dec _blocks ' Every 4 blocks, create a random power pill that falls down, if non is currently present if not _powY + _blocks&3 _powY = $6f17+k/32*8 k=$4042+k&31*$404 _pow=$5600+rand 4*8 move _pow, _powY,9 dpoke $d004,k dpoke $d006,k+$404 endif endif ' Increase score _score=_score+5 @p endproc
Download
Install instructions
Starting the Game
<<================>>
Joystick: Start the game by booting ARKANOID.ATR or ARKANOID.XEX
Paddles: Start the game by booting ARK-PAD.ATR or ARK-PAD.XEX




Comments
Log in with itch.io to leave a comment.
Eric, You’re the final boss of 10-line-programming; nobody can take you down! :-)
Great game, thanks.
Very nice game!
very good
Very good, love Arkanoid anyway so to get it into 10 lines is great
Wow! Eric never fails to surprise with the level of polish in his entries. Arcade quality in 10 lines is quite incredible.
damn, that's impressive, 10 levels and in 10 lines of code too...