--- title: "Saucers" id: 53810 type: "computer_media" slug: "saucers-2" url: "http://localhost/computer_media/saucers-2/" markdown_url: "http://localhost/computer_media/saucers-2.md" published_at: "2024-05-13T18:56:53+00:00" modified_at: "2026-03-30T21:45:16+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "Guide a crosshair, fire at descending alien saucers, and prevent ten landings before the invaders build their city and doom mankind to become toothpicks." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" genre: - name: "Arcade" slug: "arcade" taxonomy: "genre" url: "http://localhost/type/arcade/" media_contents: - id: 53877 title: "SINCUS Exchange Tape 101 – Entertainment" type: "computer_media" url: "http://localhost/computer_media/sincus-exchange-tape-101-entertainment/" media_type: "Program" images: - url: "http://localhost/wp-content/uploads/2024/05/SCR-20260330-nkzf.png" - url: "http://localhost/wp-content/uploads/2024/05/SCR-20260330-nkvz.png" media_type_tags: "Arcade" --- # Saucers 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: | Byte | BIN Value | Pattern | | --- | --- | --- | | 0 | 00000000 | blank | | 1 | 00011000 | central dot | | 2 | 01111110 | wide body | | 3 | 11011011 | hull detail | | 4 | 11111111 | full width | | 5 | 01100110 | landing legs | | 6 | 00000000 | blank | | 7 | 00000000 | blank | 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. ## 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 ```