“Alien Gunner” is a ZX81/TS1000 shooting gallery game where the player fires a bullet across the screen to hit alien targets displayed at randomised row and column positions. The game uses PLOT/UNPLOT pairs to animate a scanning crosshair along row 2 and a rising bullet, with the player triggering the shot by pressing any key during the scan. Target scoring is determined by a computed GOSUB — `GOSUB (F+2)*100` — dispatching to one of four subroutines at lines 300, 400, 500, or 600 that award 1000, 500, 250, or 100 points respectively, depending on which of the four random rows the alien occupied. A miss flag variable `W` prevents a new alien from being placed until the current one is cleared, and UNPLOT removes a peg from the bottom score-bar for each of the 15 shots in the game loop.
Program Analysis
Program Structure
The program is organised into a main game loop and four small scoring subroutines:
- Initialisation (lines 5–45): Sets up a bottom border of dots using PLOT, initialises score
Kand miss-flagW. - Outer shot loop (lines 50–280): Iterates
Zfrom 0 to 14 (15 shots total), placing aliens and handling the scan/fire sequence. - Scanning crosshair (lines 90–140): Loops
Ifrom 0 to 63, PLOT/UNPLOT-ing on row 2 to simulate left-to-right movement; pressing any key exits to the fire sequence. - Bullet flight (lines 150–180): Loops
Jfrom 2 to 41, PLOT/UNPLOT-ing at columnIto animate the bullet rising. - Hit/miss resolution (lines 190–280): Removes a pip from the bottom bar, tests for a hit, branches to scoring or miss handling, and updates the display.
- Scoring subroutines (lines 300–610): Four RETURN-terminated blocks awarding 1000, 500, 250, or 100 points.
- End-of-game / save (lines 290, 620–630): Line 290 jumps to the non-existent line 700 to halt; lines 620–630 handle saving and restarting.
Computed GOSUB Dispatch
The most technically notable idiom is on line 220:
GOSUB (F+2)*100
Because F is a random integer in the range 1–4 (the alien’s row), (F+2)*100 evaluates to 300, 400, 500, or 600, jumping directly to the corresponding scoring subroutine. This is an elegant way to implement a jump table without IF/THEN chains, exploiting the ZX81’s ability to use arbitrary numeric expressions as line-number targets in GOSUB.
Scoring Table
| Row (F) | GOSUB target | Points awarded |
|---|---|---|
| 1 (highest) | 300 | 1000 |
| 2 | 400 | 500 |
| 3 | 500 | 250 |
| 4 (lowest) | 600 | 100 |
Miss Flag and Alien Persistence
Variable W acts as a miss-flag. When a shot misses (lines 205–210), W is set to 1 and the outer loop continues without calling line 55’s alien-placement block. Line 55 checks IF W<>0 THEN GOTO 90, causing subsequent shots to fire at the same alien until it is hit. W is only cleared to 0 at line 225, after a successful hit. This means a missed alien stays on screen and must be hit eventually — though the loop counter still advances, so a persistent miss consumes remaining shots.
PLOT/UNPLOT Animation
All motion — the scanning crosshair and the rising bullet — is achieved with back-to-back PLOT/UNPLOT pairs rather than PRINT AT, keeping the display manipulation at pixel level. The crosshair scans across row 2 (y-coordinate 2 in ZX81 pixel space), and the bullet travels from row 2 up to row 41 along column I, the column frozen at the moment the key was pressed.
Hit Detection
Line 200 tests IF I=2*S OR I=2*S+1. Because aliens are PRINTed at character column S-1 and each character is 2 pixels wide, the alien occupies pixel columns 2*(S-1) through 2*S+1. The check covers only the two central pixel columns 2*S and 2*S+1, making the hit window deliberately narrow (one character wide rather than the full three-character sprite).
Score Bar
Lines 10–30 draw 15 dots at even x-coordinates along y=0 by stepping I from 0 to 28 in steps of 2. Line 190 UNPLOTs (28-2*Z, 0) on each iteration, removing one pip per shot consumed — a simple graphical ammunition counter that counts down from right to left.
Notable Techniques
- Computed GOSUB as a jump table (
GOSUB (F+2)*100). - PLOT/UNPLOT pairs for flicker-free single-pixel animation without clearing the whole screen.
- Miss-flag variable
Wcontrolling alien re-placement without a dedicated subroutine. - The alien sprite uses block graphic escapes:
"\..%X\.."renders a small inverse-video alien shape; on a hit, it is replaced with"\,,\##\,,"(an explosion pattern) before being erased. - GOTO 700 at line 290 targets a non-existent line, causing the program to halt cleanly at end of game.
Potential Bugs and Anomalies
- If the player does not press a key before
Ireaches 63, the scan loop exits at line 140 viaGOTO 90, restarting the scan but not advancingZ. The shot counter is therefore not consumed on a time-out, which may be intentional as a grace mechanic but is not documented. - The hit check covers only two of the six pixel columns under the three-character sprite, making hits harder than the visual size implies.
- Score display at line 270 (
PRINT AT 21,27;K) is only updated after a successful hit, not after a miss, so the score display is never updated on a miss shot.
Content
Source Code
5 REM "ALIEN GUNNER"
10 FOR I=0 TO 28 STEP 2
20 PLOT I,0
30 NEXT I
40 LET K=0
45 LET W=0
50 FOR Z=0 TO 14
55 IF W<>0 THEN GOTO 90
60 LET F=INT (RND*4+1)
70 LET S=INT (RND*29+2)
80 PRINT AT F,S-1;"\..%X\.."
90 FOR I=0 TO 63
100 PLOT I,2
110 UNPLOT I,2
120 IF INKEY$<>"" THEN GOTO 150
130 NEXT I
140 GOTO 90
150 FOR J=2 TO 41
160 PLOT I,J
170 UNPLOT I,J
180 NEXT J
190 UNPLOT 28-2*Z,0
200 IF I=2*S OR I=2*S+1 THEN GOTO 220
205 LET W=1
210 GOTO 280
220 GOSUB (F+2)*100
225 LET W=0
230 PRINT AT F,S-1;"\,,\##\,,"
240 PAUSE 50
250 PRINT AT F,S-1;" "
260 PAUSE 50
270 PRINT AT 21,27;K
280 NEXT Z
290 GOTO 700
300 LET K=K+1000
350 RETURN
400 LET K=K+500
450 RETURN
500 LET K=K+250
550 RETURN
600 LET K=K+100
610 RETURN
620 SAVE "1023%3"
630 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
