Asteroids

This file is part of SINCUS Exchange Tape 101 - Entertainment, and Timex Sinclair Public Domain Library Tape 2004. Download the collection to get this file.
Type: Program
Platform(s): TS 2068
Tags: Arcade, Game

This program implements a scrolling asteroid-field dodge game in which the player steers a spacecraft left and right using keys 5 and 8, and can deploy an energy screen (key 0) to destroy nearby asteroids. The spacecraft is rendered using a set of 21 User-Defined Graphics (UDGs “a” through “u”), whose bitmaps are loaded at startup via a DATA/POKE USR routine starting at line 9000. Collision detection is handled entirely through the ATTR function, checking the paper/ink color code 15 (white on white) at the three cells the ship occupies in row 8. The game tracks score as elapsed ticks, maintains a persistent best-ever score in variable e, and includes a two-letter initials entry for a Hall of Fame when the best score is beaten; a computed GO TO expression at line 405 branches to play-again, save, or quit paths.


Program Analysis

Program Structure

The program is divided into four logical phases:

  1. Introduction (line 1): Displays a flashing title, instructions, and waits for key 8 to start.
  2. Game loop (lines 4–100): Initializes variables, then repeatedly reads input, moves the ship, checks for collisions via ATTR, draws the ship and scrolling asteroids, and loops back to line 50.
  3. Death sequence and scoring (lines 400–460): Plays a three-frame explosion animation, calculates the score, handles the Hall of Fame entry, and offers play-again/save/quit.
  4. UDG loader subroutine (lines 9000–9270): RESTOREs to line 9070 and POKEs bitmap data for 21 UDGs (“a”–”u”) via POKE USR p$+n,a.

User-Defined Graphics

Twenty-one UDGs are defined, covering a rich set of spacecraft parts, asteroid fragments, and explosion frames. The loader at lines 9020–9060 iterates over each character label in p$ and writes eight bytes of bitmap data. In the game loop at line 100, CHR$ (RND*11+144) selects a random UDG from the range 144–154 (UDGs “a”–”k”) to render asteroids scrolling onto row 21. The spacecraft body and wings are drawn with UDGs \s/\t (row 7) and \p/\q/\r (row 8), while the explosion uses UDGs \n, \o, \u etc.

Collision Detection via ATTR

Rather than tracking asteroid positions in an array, collision detection exploits the display attribute system. Asteroids are printed in INK 7 on PAPER 1 (blue background), giving an attribute byte of 15. The ship occupies columns l, l+1, and l+2 on row 8. Lines 64–66 check:

  • ATTR (8,l)=15 or ATTR (8,l+2)=15 → wing hit, p=p-1
  • ATTR (8,l+1)=15 → body hit, p=p-2

This approach is compact but means any cell with attribute 15 registers as a hit, tying game logic directly to the display state.

Energy Screen Mechanic

Pressing key 0 costs one energy unit (f=f-1) and prints a three-cell energy graphic in INK 6 at ship row 8 via PRINT AT 8,l; INK 6;"\p\q\r". Because the energy screen is rendered in INK 6 (yellow) rather than INK 7, it overwrites any asteroid attribute at that cell, preventing a collision detection hit on the next iteration. The energy check appears twice — at line 50 (integrated into the movement/scroll path) and at line 62 — to handle both the normal and post-screen-flash code paths.

Scrolling Asteroid Field

Asteroids are produced by printing two random UDG characters at random column positions on row 21 each tick (line 100). The display naturally scrolls upward because the PRINT at the end of line 100 causes the screen to scroll when the cursor reaches row 21. This is a classic Sinclair BASIC scroll-by-printing idiom: AT 21,31;"" positions the cursor at the last cell; the following bare PRINT triggers the scroll, pushing all rows up by one.

Score and Hall of Fame

Score is measured as the tick counter t minus 13 (a calibration offset for setup ticks). Variable b holds the best score for the current session and e the best-ever score, both persisting across plays via GO TO 4 (not GO TO 1), which skips the initialization of b and e at line 1. When e is beaten, the player enters two-letter initials: a loop at line 403 reads INKEY$ twice with PAUSE 0 as a keypress-wait idiom, appending each letter plus a period separator into n$.

Computed GO TO

Line 405 ends with a computed branch:

GO TO (5 AND INKEY$="p")+(430 AND INKEY$="s")+(450 AND INKEY$="f")

Because PAUSE 0 precedes it, exactly one of INKEY$ comparisons will be true (evaluating to 1), so the expression yields 5, 430, or 450. A value of 0 (no matching key) would jump to a non-existent line 0, but in practice PAUSE 0 ensures a key is held when execution reaches the GO TO.

Variable Summary

VariablePurpose
tTick counter (raw score)
pHit points remaining (starts at 5)
lCurrent ship column position
l1Previous ship column (for erasing)
fEnergy screen units remaining (starts at 6)
bBest score this session
eBest-ever score across sessions
n$Player initials for Hall of Fame
m, nLoop counters (UDG loader, animation, etc.)
p$UDG character label in loader
aSingle bitmap byte in loader

Notable Anomalies

  • POKE 23692,255 at line 50 resets the scroll counter to suppress the “scroll?” prompt, a standard Sinclair BASIC technique for uninterrupted scrolling programs.
  • Line 9065 (BORDER 1: PAPER 1: CLS : INK 7: GO TO 2) is unreachable dead code — there is no line 2 and nothing branches to 9065.
  • The energy variable f is initialized to 6 at line 10 despite the instructions stating “5 energy units.” With each activation decrementing before the check (f=f-1: IF f>0), activations 1–5 succeed and activation 6 fails, so the player effectively gets exactly 5 uses — the off-by-one is intentional.
  • Lines 9998–9999 (SAVE / VERIFY) are developer utilities left in the listing and are only reachable if execution falls through from the UDG loader, which never happens during normal play.

Content

Appears On

One of a series of library tapes compiled from multiple user groups.

Related Products

Related Articles

Related Content

Image Gallery

Asteroids

Source Code

    1 BORDER 1: PAPER 1: CLS : INK 7: PRINT AT 0,8; FLASH 1;"ASTEROIDS AHEAD!": PAUSE 100: PRINT FLASH 0;''" Steer your spacecraft through   the swarm of asteroids"''"Press 5 for Left or 8 for Right."''"Press 0 to activate your craft'sEnergy Screen to destroy        asteroids you cannot avoid"''"But BEWARE - the Screen has onlya short range and you have only 5 energy units left"''" Your craft will disintegrate    after 5 hits (wings=1,body=2)"''"   HOW LONG CAN YOU SURVIVE?": GO SUB 9000: PRINT '"        Press 8 to start": PAUSE 0: LET b=0
    4 LET e=0
   10 INK 0: CLS : LET t=0: LET p=5: LET l=15: LET l1=l: LET f=6
   50 POKE 23692,255: LET l=l+(INKEY$="8" AND l<29)-(INKEY$="5" AND l>0): IF INKEY$="0" THEN LET f=f-1: IF f>0 THEN PRINT AT 8,l; INK 6;"\p\q\r": GO TO 64
   62 IF INKEY$="0" THEN LET f=f-1: IF f>0 THEN PRINT AT 8,l; INK 6;"\p\q\r"
   64 IF ATTR (8,l+2)=15 OR ATTR (8,l)=15 THEN LET p=p-1
   66 IF ATTR (8,l+1)=15 THEN LET p=p-2
   67 IF p<1 THEN GO TO 400
  100 PRINT AT 7,l1;"   ";AT 21,31;"": PRINT : PRINT AT 7,l; INK 6;"\s"; INVERSE 1;p; INVERSE 0;"\t": LET t=t+1: LET l1=l: PRINT AT 21,RND*31; INK 7;CHR$ (RND*11+144);AT 21,RND*31;CHR$ (RND*11+144): GO TO 50
  400 FOR n=1 TO 3: PRINT AT 6,l1;"   ";AT 7,l1; INK 2;" \m ";AT 8,l1;"   ": PAUSE 2: PRINT AT 6,l1; INK 6;"\o\q\u";AT 7,l1;"\n \n";AT 8,l1;"\p\q\r": PAUSE 2: NEXT n: FOR n=6 TO 8: PRINT AT n,l1;"    ": NEXT n
  402 CLS : IF b<t-13 THEN LET b=t-13
  403 INK 7: IF e<b THEN LET e=b: PRINT AT 6,0;"You have beaten the best ever   score. Enter the HALL OF FAME"''"Press the two letters of your   initials": LET n$="": FOR n=1 TO 2: PAUSE 0: LET n$=n$+INKEY$+".": NEXT n: CLS 
  405 PRINT ;"   Score=";t-13,"Best Score=";b''"   Best ever Score=";: PRINT FLASH 1;e;" by ";n$''': FOR n=1 TO 150: NEXT n: PRINT FLASH 0;"   Press P to play again"''"         s to save"''"         f to finish": PAUSE 0: GO TO (5 AND INKEY$="p")+(430 AND INKEY$="s")+(450 AND INKEY$="f")
  430 SAVE "ASTEROIDS" LINE 1
  450 PRINT ''''"  Thank you for playing.  'Bye"
  460 GO TO 460
 9000 
 9020 RESTORE 9070: FOR m=1 TO 21
 9030 READ p$
 9040 FOR n=0 TO 7
 9050 READ a: POKE USR p$+n,a
 9060 NEXT n: NEXT m: RETURN 
 9065 BORDER 1: PAPER 1: CLS : INK 7: GO TO 2
 9070 DATA "a",62,33,255,129,129,65,37,26
 9080 DATA "b",112,148,138,65,129,65,37,26
 9090 DATA "c",0,0,24,36,36,56,0,0
 9100 DATA "d",0,0,48,40,48,32,0,0
 9110 DATA "e",0,24,40,40,16,0,0,0
 9120 DATA "f",112,136,136,68,40,48,0,0
 9130 DATA "g",0,0,0,56,44,16,0,0
 9140 DATA "h",0,0,30,18,34,84,232,0
 9150 DATA "i",94,177,130,228,34,65,66,60
 9160 DATA "j",0,62,65,66,34,17,14,0
 9170 DATA "k",96,144,144,116,10,49,65,126
 9180 DATA "l",62,65,242,9,247,126,144,88
 9190 DATA "m",145,82,16,7,244,8,74,127
 9200 DATA "n",100,24,198,0,222,0,24,102
 9210 DATA "o",0,4,34,18,1,68,50,0
 9220 DATA "p",9,50,68,1,18,34,4,0
 9230 DATA "q",0,8,170,42,73,65,137,137
 9240 DATA "r",144,76,34,128,72,68,32,0
 9250 DATA "s",0,3,15,15,120,200,255,56
 9260 DATA "t",0,192,240,240,30,19,255,28
 9270 DATA "u",0,32,68,72,128,36,76,144
 9998 SAVE "Asteroids" LINE 1: BEEP .4,15
 9999 VERIFY ""

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top