--- title: "Anti-Aircraft Gunner" id: 57511 type: "computer_media" slug: "anti-aircraft-gunner" url: "http://localhost/computer_media/anti-aircraft-gunner/" markdown_url: "http://localhost/computer_media/anti-aircraft-gunner.md" published_at: "2024-10-05T21:16:49+00:00" modified_at: "2026-03-30T21:17:35+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/266_AAG.png" excerpt: "Shoot a sliding target in this gallery game that uses block graphics, random speed changes, and a 20-shot limit to test your reflexes." 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 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_contents: - id: 56737 title: "Timex Sinclair Public Domain Library Tape 1006" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1006/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/10/266_AAG.png" media_type_tags: "Game, Software" --- This is a shooting-gallery game in which the player fires at a moving target sliding across the screen. The program uses FAST mode to fill the screen with inverse-space characters as a border effect, then switches to SLOW mode for gameplay. A target moves left to right across row 3 in steps of two columns, with a random delay (controlled by a FOR/NEXT busy-wait loop seeded by RND) governing its speed. The player presses “V” to shoot, and the program checks whether the target is at column 14 for a hit; scores for shots fired and hits are maintained in variables Q and D respectively. After 20 shots the game ends with a flashing score display achieved by alternating PRINT statements in a tight loop. *** ## Program Analysis ### Program Structure The program divides into five logical phases: 1. **Initialisation (lines 3–8):** Variables `D` (hits), `Q` (shots) and `A` (loop counter) are zeroed; FAST mode is entered. 2. **Screen fill (lines 10–20):** A `FOR`-less loop prints rows of inverse-space characters 21 times to build a border/background, then falls through to line 25. 3. **Target animation (lines 25–80):** The target slides from column 0 to column 29 in steps of 2, with a random speed delay regenerated each pass. 4. **Shot handling (lines 90–140):** A keypress at “V” triggers shot logic, checks for a hit at column 14, updates scores, and re-enters the animation loop. 5. **Game over (lines 500–560):** After 20 shots, a flashing score is displayed, and the program saves itself and re-runs. ### Screen Fill Technique Rather than using a conventional `FOR`/`NEXT` loop, the background is drawn with an unstructured loop: lines 10–20 print a full row of inverse spaces, increment `A`, and branch back or forward depending on whether `A` has reached 21. Running in FAST mode makes this fill effectively instantaneous from the user’s perspective. The result is a screen packed with inverse-space characters serving as a dark backdrop. ### Target Movement and Speed The target is a pair of inverse-space characters printed at row 3 using `PRINT AT 3,C;"% % \.'` (an inverse space, space, inverse space, and a block graphic `▞`). Column `C` steps from 0 to 29 in increments of 2 inside the outer `FOR C` loop. Between each column step a busy-wait `FOR E=1 TO F … NEXT E` provides the delay, where `F=INT(RND*10)/2` produces a random integer 0–4, giving variable target speed that is re-randomised each full pass. ### Shooting Mechanic and Hit Detection Within the delay loop at line 52 the program polls `INKEY$` for “V”. On a keypress, execution jumps to line 90, which draws a “bullet” column at column 16 (rows 18 and 19) and simultaneously redraws the player sprite at row 4/18 column 16. The hit test at line 96 is simply `IF C=14 THEN GOTO 106`; because the target steps by 2 and the bullet is fixed at column 16, a hit is registered when the target occupies column 14 — meaning the graphic overlap occurs one step before the bullet column. This is a deliberate approximation rather than a true collision check. ### Hit Animation Lines 106–108 draw an explosion using block graphics centred on column 15: - Line 106 uses `\'` (▘) and `\ '` (▝) combined with `\.` (▖) and `\ .` (▗) to paint a four-quadrant burst pattern. - Line 108 overwrites with `\:'` (▛) and `\:.` (▙) variants to animate a second frame. - Both lines also reprint surrounding inverse-space characters to restore the background after the animation. ### Score Display and Game Over Shots (`Q`) and hits (`D`) are displayed with inline concatenation: `PRINT AT 18,2;Q;"% SHOTS"` and `AT 18,23;D;"% HITS"` (the `%` being an inverse space used as a separator). When `Q>20`, the game-over routine at line 500 enters a tight loop alternating between printing blank spaces and the hit count at position (18,23), creating a simple flashing effect without any explicit timing mechanism other than the loop itself. ### Save and Auto-Run Line 550 saves the program under a filename that includes inverse characters (`"1026%6"` where `%6` is an inverse digit), which on the ZX81/TS1000 encodes an auto-run flag so the program starts automatically when loaded. Line 560 immediately re-runs the program after saving, so a fresh game begins without user intervention. ### Variables Summary | Variable | Purpose | | --- | --- | | `A` | Screen-fill loop counter (0–21, then discarded) | | `C` | Current target column (FOR loop, 0–29 step 2) | | `D` | Hit counter | | `E` | Speed delay loop index | | `F` | Random delay value (0–4) | | `Q` | Shot counter | | `Y` | Short busy-wait loop at game over (lines 522–524) | ### Notable Bugs and Anomalies - After a hit (line 106–140), the outer `FOR C` loop is re-entered at line 40 with `C` reset to 0, but the `FOR` statement re-initialises `C` cleanly, so this is not a bug — it simply restarts the target from the left. - On a miss (no hit at `C=14`), line 102 jumps back into the middle of the `FOR E` loop at line 55, bypassing the `FOR` statement. On the ZX81 this reuses the existing `E` loop descriptor rather than reinitialising it, which could cause the delay to run from wherever `E` was rather than from 1. This is a subtle timing irregularity. - Line 36 prints a gun/player sprite at rows 19–20 column 16 every time a new random speed is chosen, not just once — this is harmless but redundant. - The `CLEAR` at line 540 is never reached because the game-over loop at lines 510–530 never exits. ## Source Code ``` 3 LET D=0 4 LET Q=0 6 LET A=0 8 FAST 10 PRINT "% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % " 12 LET A=A+1 14 IF A=21 THEN GOTO 25 20 GOTO 10 25 SLOW 27 PRINT AT 4,0;"% " 30 LET F=INT (RND*10)/2 36 PRINT AT 20,16;"%*";AT 19,16;"%*" 40 FOR C=0 TO 29 STEP 2 50 PRINT AT 3,C;"% % \.'" 52 IF INKEY$="V" THEN GOTO 90 55 FOR E=1 TO F 57 NEXT E 60 NEXT C 70 PRINT AT 3,30;"% " 80 GOTO 30 90 PRINT AT 18,16;" ";AT 18,16;"% ";AT 4,16;" ";AT 4,16;"% " 92 LET Q=Q+1 94 PRINT AT 18,2;Q;"% SHOTS" 96 IF C=14 THEN GOTO 106 100 IF Q>20 THEN GOTO 500 102 GOTO 55 106 PRINT AT 3,15;"% % % ";AT 2,15;"\' % \ '";AT 4,15;"\. % \ .";AT 4,15;"% % % ";AT 2,15;"% % % " 108 PRINT AT 2,15;"\:'% \':";AT 4,15;"\:.% \.:";AT 4,15;"% % % ";AT 2,15;"% % % " 120 LET D=D+1 130 PRINT AT 18,23;D;"% HITS" 135 IF Q>20 THEN GOTO 500 140 GOTO 40 500 PRINT AT 10,3;"GAME% OVER" 510 PRINT AT 18,23;"% % " 520 PRINT AT 18,23;D 522 FOR Y=1 TO 4 524 NEXT Y 530 GOTO 510 540 CLEAR 550 SAVE "1026%6" 560 RUN ```