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


StatusReleased
Rating
Rated 5.0 out of 5 stars
(1 total ratings)
AuthorBASIC 10Liner
GenreAction
Tags10liner, 8-Bit, atari800, atarixl, basic

Download

Download
ARKANOID.ATR 90 kB
Download
ARKANOID.LST 2.4 kB
Download
ARKANOID.XEX 3.8 kB
Download
ARKANOID-Commented-Source.bas 11 kB
Download
ARKANOID-Readme.txt 2 kB
Download
ARK-PAD.ATR 90 kB
Download
ARK-PAD.LST 2.4 kB
Download
ARK-PAD.XEX 3.8 kB
Download
ARK-PAD-Commented-Source.bas 10 kB

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...