Saucers

Type: Program
Platform(s): TS 2068
Tags: Game

This program is a shoot-the-saucers game in which the player maneuvers a crosshair cursor around the screen and fires at an alien saucer before it descends far enough to trigger a “landing” and ultimately conquer Earth. The saucer is drawn using a custom UDG character (“\p”) defined at line 5000 via DATA and POKEd into USR memory, depicting a classic flying-saucer silhouette with BIN literals. The playing field is rendered entirely with PLOT/DRAW commands that outline runways, city boundaries, and a border before gameplay begins. Difficulty increases dynamically: once the score exceeds 1000, the saucer’s descent rate doubles, and after 1000 it can triple; after ten landings the game ends with an animated block-graphic alien city built line by line using Spectrum block characters. The crosshair is erased and redrawn each frame using PRINT AT with spaces followed by “+” characters, giving smooth movement without flicker-clearing the whole screen.


Program Analysis

Program Structure

The program is organized into several distinct sections accessed via GO SUB:

  1. Lines 1–9: Variable initialization — crosshair position (l, k), saucer position (m, n), score, and landing counter.
  2. Line 3: GO SUB 5000 — UDG definition routine.
  3. Line 4: GO SUB 4000 — title screen, instructions, and startup animation.
  4. Lines 10–120: One-time screen drawing using PLOT/DRAW to lay out the playfield geometry and border.
  5. Lines 125–999: Main game loop — erase crosshair, read keys, move saucer, check collisions, play tones, update display, repeat via GO TO 125.
  6. Lines 1020–1080: Hit subroutine — explosion effect, score increment, saucer reset.
  7. Lines 2000–2020: Landing subroutine — increments lan, ends game after 10 landings, resets saucer.
  8. Lines 4000–4050: Title/instructions screen with coloured text and a starfield animation.
  9. Lines 5000–5040: UDG loader — reads BIN values into the UDG slot for character \p.
  10. Lines 7000–7150: Game-over sequence with animated block-graphic city and score display.
  11. Line 9999: SAVE line for persistence.

UDG Definition

Lines 5000–5040 define a custom UDG for the saucer sprite. Eight bytes are stored with DATA BIN ... statements and read into USR "\p" (UDG “P”) via POKE in a FOR loop. The bit pattern:

ByteBIN ValuePattern
000000000blank
100011000central dot
201111110wide body
311011011hull detail
411111111full width
501100110landing legs
600000000blank
700000000blank

Note that BIN 0 is used as a shorthand for BIN 00000000, which is valid BASIC syntax on this platform.

Main Game Loop Mechanics

The crosshair is a four-character “+” pattern printed at offsets around (k, l). Each frame, it is first erased by printing spaces (lines 125–128), then movement keys are checked (lines 130–160), then the crosshair is redrawn (lines 200–230). This erase-move-redraw technique avoids clearing the whole screen and preserves the PLOT/DRAW playfield.

Key mapping uses numeric keys typical for this era:

  • "5" — move left
  • "8" — move right
  • "6" — move down
  • "7" — move up
  • "0" — fire

The saucer’s column n drifts each frame by INT (RND*3)-1 (lines 245–247), clamped to stay between 3 and 29. Its row m is a floating-point variable incremented by 0.2 per frame (line 250); INT m is used for all display and collision checks, giving smooth sub-row descent.

Difficulty Scaling

Line 252 implements a two-stage speed increase. Once score>1000, an additional +0.2 is added to m each frame. A second condition checks m>2000 — which, given m resets to 3 on each new saucer, will never actually be true during normal play. This appears to be a bug: the intended second threshold was likely score>2000.

Firing and Hit Detection

Line 240 checks INKEY$="0". If pressed, it plays a brief four-beep sound, then tests k=INT m AND l=INT n — a simple exact-match collision requiring the crosshair center to align precisely with the saucer’s character cell. On a hit, GO SUB 1000 is called; however, the subroutine actually begins at line 1020. Since GO SUB to a non-existent line jumps to the next higher line, this is intentional behavior. The hit routine prints the saucer UDG at the crosshair position, then overlays a block graphic (\.', i.e., ▞) using OVER 1 for a brief explosion flash.

Audio

Line 248 plays a random-pitch tone every frame using BEEP 0.005,(RND*35)+15, creating a continuous engine-noise effect. The fire sound (line 240) is a short 40-semitone beep repeated four times. The hit sound (line 1030) sweeps from pitch 50 down to 45 in 0.5 steps, producing a descending explosion tone. The game-over sequence (lines 7000–7075) plays five descending single notes as each row of the alien city graphic is revealed.

Game Over — Animated City

Lines 7030–7070 build an alien city using Spectrum block graphics characters (\:: = █, \:. = ▙, \.: = ▟, \: = ▌, \ : = ▐) printed row by row with a BEEP between each row, giving a dramatic construction animation. INK INT 2 at line 7030 contains a subtle bug: INT 2 evaluates to 2 (red), which happens to work, but the expression is redundant — INT of an integer literal is unnecessary.

Notable Idioms and Anomalies

  • Line 255 redraws the screen border if n goes out of range, guarding against the saucer drifting into the border area overwriting the frame.
  • PRINT AT INT m, INT n is used throughout rather than rounding, causing the saucer to appear to snap to cell positions.
  • The landing counter variable is declared as LAN (line 9) but referenced as lan (lines 2000, 2010) — BASIC on this platform treats variable names case-insensitively for numeric variables, so this is not a bug.
  • Line 4050 uses GO TO 5 instead of RETURN, bypassing the subroutine return mechanism after the title screen. This works because the title screen is always the last initialization step before the main game setup at line 5.
  • Line 3005 (FOR n=0 TO 100: BEEP 0.1,40: NEXT n) defines a long beep loop that is never called by any GO SUB or GO TO in the program — it is dead code.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

Source Code

    1 REM saucers
    3 GO SUB 5000
    4 GO SUB 4000
    5 LET l=16: LET k=11: LET pos=10
    6 LET m=3: LET n=INT (RND*26)+2
    8 LET score=0
    9 LET LAN=0
   10 PLOT 0,0: DRAW 97,50
   20 PLOT 255,0: DRAW -97,50
   30 PLOT 137,50: DRAW 50,-50
   40 PLOT 117,50: DRAW -50,-50
   50 PLOT 70,50: DRAW -70,-15
   60 PLOT 185,50: DRAW 70,-15
   70 PLOT 0,50: DRAW 255,0
   80 PLOT 127,50: DRAW 0,-50
   90 PLOT 0,40: DRAW 255,0
  100 PLOT 0,15: DRAW 255,0
  110 PLOT 0,14: DRAW 255,0
  120 INK 7: PLOT 0,0: DRAW 0,175: DRAW 255,0: DRAW 0,-175: DRAW -255,0
  125 PRINT AT k,l-1;" "
  126 PRINT AT k,l+1;" "
  127 PRINT AT k-1,l;" "
  128 PRINT AT k+1,l;" "
  130 IF INKEY$="8" AND l<29 THEN LET l=l+1
  140 IF INKEY$="5" AND l>2 THEN LET l=l-1
  150 IF INKEY$="6" AND k<13 THEN LET k=k+1
  160 IF INKEY$="7" AND k>2 THEN LET k=k-1
  180 PRINT AT INT m,INT n;" "
  200 PRINT AT k,l-1;"+"
  210 PRINT AT k-1,l;"+"
  220 PRINT AT k+1,l;"+"
  230 PRINT AT k,l+1;"+"
  240 IF INKEY$="0" THEN FOR t=0 TO 3: BEEP 0.02,40: NEXT t: IF k=INT m AND l=INT n THEN GO SUB 1000
  245 LET n=n+INT (RND*3)-1
  246 IF n<3 THEN LET n=n+1
  247 IF n>29 THEN LET n=n-1
  248 BEEP 0.005,(RND*35)+15
  250 LET m=m+0.2
  252 IF score>1000 THEN LET m=m+0.2: IF m>2000 THEN LET m=m+0.2
  255 IF n<1 OR n>31 THEN PLOT 0,0: DRAW 0,175: DRAW 255,0: DRAW 0,-175: DRAW -255,0
  260 IF m>15 THEN GO SUB 2000
  300 INK INT (RND*7)+2: PRINT AT INT m,INT n;"\p": INK 7
  310 PRINT AT 1,1;"SCORE:";score;" "
  999 GO TO 125
 1020 PRINT AT k,l;"\p": PRINT ; OVER 1;AT k,l;"\.'"
 1030 FOR h=50 TO 45 STEP -0.5: BEEP 0.01,h: NEXT h
 1040 PRINT AT k,l;" "
 1050 LET m=3: LET n=INT (RND*26)+2
 1060 LET score=score+100
 1080 RETURN 
 2000 LET lan=lan+1
 2010 IF lan>10 THEN GO TO 7000
 2015 LET m=3: LET n=INT (RND*26)+2
 2020 RETURN 
 3005 FOR n=0 TO 100: BEEP 0.1,40: NEXT n
 4000 PAPER 1: INK 7: BORDER 1: CLS 
 4010 PRINT AT 0,10; FLASH 1;"SAUCER"; FLASH 0
 4020 INK 6: PRINT : PRINT "Save the Earth,the aliens are   invading and are trying to buildcities on the Earth.": PRINT : PRINT "Shoot them before they build    their cities and conquer EARTH  and use you for toothpicks."
 4030 INK 7: PRINT : PRINT : PRINT "  5 FOR LEFT": PRINT : PRINT "  8 FOR RIGHT": PRINT : PRINT "  6 FOR DOWN": PRINT : PRINT "  7 FOR UP": PRINT : PRINT "  0 TO FIRE"
 4040 PRINT AT 21,1; FLASH 1;"Good Luck.......": FLASH 0
 4045 PAUSE 9999
 4050 BORDER 0: PAPER 0: INK 6: CLS : FOR n=0 TO 50: BEEP 0.005,(RND*35)+15: INK INT (RND*7)+1: PLOT INT (RND*250)+5,INT (RND*120)+50: NEXT n: INK 4: GO TO 5
 5000 DATA BIN 0,BIN 00011000,BIN 01111110,BIN 11011011,BIN 11111111,BIN 01100110,BIN 0,BIN 0
 5010 FOR n=0 TO 7: READ j
 5030 POKE USR "\p"+n,j: NEXT n
 5040 RETURN 
 7000 BEEP 0.7,1: BEEP 0.5,1: BEEP 1,6
 7010 PRINT AT 1,1;"THEY HAVE CONQUERED EARTH"
 7020 PRINT AT 2,3;"AND ARE BUILDING THEIR CITY"
 7025 PAUSE 100
 7030 INK INT 2: PRINT AT 12,10;"\::"
 7035 BEEP 0.5,5
 7040 PRINT AT 13,9;"\.:\::\:."
 7045 BEEP 0.5,4
 7050 PRINT AT 14,9;"\: \::\ :"
 7055 BEEP 0.5,3
 7060 PRINT AT 15,9;"\::\::\::"
 7065 BEEP 0.5,2
 7070 PRINT AT 16,8;"\.:\::\::\::\:."
 7075 BEEP 0.5,1
 7076 INK 6
 7080 PRINT AT 8,1;"YOU HAVE LOST EARTH, THE  "
 7090 PRINT AT 9,1;"ALIENS HAVE DOOMED MANKIND"
 7100 PRINT AT 10,1;"TO BECOME TOOTH PICKS"
 7110 PRINT AT 18,1;"ENTER 'RUN' TO GO BACK INTO "
 7120 PRINT AT 19,1;"TIME TO TRY AND SAVE THE"
 7130 PRINT AT 20,1;"EARTH AGAIN !!!!"
 7140 FLASH 1: PRINT AT 5,1;"YOUR SCORE WAS ";score: FLASH 0
 7150 STOP 
 9999 SAVE "saucers" LINE 1: BEEP 1,32

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

People

No people associated with this content.

Scroll to Top