--- title: "Rear Gunner" id: 57335 type: "computer_media" slug: "rear-gunner" url: "http://localhost/computer_media/rear-gunner/" markdown_url: "http://localhost/computer_media/rear-gunner.md" published_at: "2024-10-04T08:23:47+00:00" modified_at: "2026-03-30T21:18:31+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/09/183_RGun.png" excerpt: "Move your crosshair across the screen, line up the shot, and press fire — but only a pixel-perfect hit will trigger the explosion in this deceptively simple shooter." 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: "Arcade" slug: "arcade" taxonomy: "genre" url: "http://localhost/type/arcade/" - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_contents: - id: 56735 title: "Timex Sinclair Public Domain Library Tape 1004" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1004/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/09/183_RGun.png" article_media: - id: 8617 title: "Program Printout: Rear Gunner" type: "article" url: "http://localhost/article/program-printout-rear-gunner/" media_type_tags: "Arcade, Game" --- This program implements a simple shooting gallery game called “Rear Gunner,” in which the player moves a crosshair (displayed as “+”) around the screen using the cursor keys (5, 6, 7, 8) and presses “0” to fire at a randomly placed target character. The target is rendered using the inverse-video “G” character, and a hit is detected by checking whether the crosshair’s row and column coordinates match the target’s position. On a successful hit, a small explosion graphic is drawn using block graphic characters around the target’s location before the game restarts. The program uses a split structure: lines 5–200 contain the gameplay loop, while lines 220–270 provide a title screen and instructions that feed back into the main loop via RUN. *** ## Program Analysis ### Program Structure The program is divided into two logical sections connected by `RUN` statements rather than `GO TO`: 1. **Title/instructions (lines 220–270):** Clears the screen, prints the game name and control instructions, waits for ENTER via `INPUT Z$`, then falls through to `RUN` (line 270), which restarts from the top. 2. **Gameplay loop (lines 5–200):** Initialises variables, places a random target, moves the crosshair in response to key presses, checks for a fire command, tests for a hit, draws an explosion, and then calls `RUN` again to reset. The entry point for a fresh game start is line 5 (reached via `RUN`), which includes a short `PAUSE 50` delay before play begins. ### Variables | Variable | Role | | --- | --- | | `A` | Row position of the crosshair (initially 5) | | `B` | Column position of the crosshair (initially 7) | | `C` | Random column of the target (0–25) | | `D` | Random row of the target (0–16) | | `Z$` | Dummy variable used to wait for ENTER on the title screen | ### Gameplay Loop Lines 30–40 randomise the target position each time the loop restarts. The target is drawn as an inverse-video “G” (`"%G"`) at line 50. Lines 60–80 render the crosshair as a “+” with blank lines above and below it to erase its previous position. Lines 90–130 poll `INKEY$` for the four cursor keys and the fire key; movement updates `A` or `B` directly. Line 130 branches to the hit-check on “0”, otherwise line 140 loops back to line 50. ### Hit Detection Logic Hit detection is performed in two steps. Line 150 checks whether the row (`D<>A`); if they differ, the shot missed and the loop restarts from line 50 with a new target. Line 160 checks whether the column matches (`C=B`), but there is a notable bug here: the condition branches to line 170 on a *hit*, but a miss (`C<>B`) also falls through to line 170 because there is no corresponding miss branch. In practice, any fire attempt that passes the row check will always reach the explosion code regardless of column alignment, making horizontal accuracy irrelevant. ### Explosion Animation Lines 170–190 draw a 3×4-character explosion graphic centred on the target using ZX81 block graphic characters. The pattern forms a small starburst: - Line 170 (`AT D-1,C`): top row — ▘ . ▝ (top-half block graphics) - Line 180 (`AT D,C`): middle row — blank, inverse space, two blanks - Line 190 (`AT D+1,C`): bottom row — ▖ . ▗ (bottom-half block graphics) After the explosion is displayed, `RUN` at line 200 resets all variables and restarts the game from line 5. ### Notable Techniques and Idioms - The crosshair erasure is achieved by printing three-space strings above and below the “+” on every frame (lines 70–80), avoiding a full `CLS` and preventing flicker. - Using `RUN` instead of `GO TO` for game reset is a common ZX81 idiom; it guarantees all variables are cleared, eliminating the need for explicit reinitialisation. - The title screen is placed *after* the game code in line numbering so that `RUN` from line 200 skips it and goes directly to gameplay, while the very first `RUN` from the title screen also lands at line 5 — a tidy dual-entry trick. - Polling four separate `INKEY$` checks (lines 90–120) on every frame means only the last key pressed in the ZX81’s single-key-at-a-time model is acted upon, which is consistent with the hardware’s limitations. - No boundary checking is applied to `A` or `B`, so moving the crosshair off-screen will cause a `B` error. ### Bugs and Anomalies - **Column hit check always passes:** Line 160 (`IF C=B THEN GOTO 170`) has no ELSE branch; whether the condition is true or false, execution continues to line 170. The player therefore only needs to match the target’s row to score a hit. - **No boundary clamping:**`A` and `B` are decremented/incremented freely; moving the cursor to row −1 or past column 31 will crash with a `B` (out of screen range) error. - **Explosion at edge rows:** If the target spawns at row 0 or row 16, `AT D-1` or `AT D+1` in lines 170/190 may reference an off-screen row and cause an error. ## Source Code ``` 5 PAUSE 50 10 LET A=5 20 LET B=7 30 LET C=INT (RND*26) 40 LET D=INT (RND*17) 50 PRINT AT D,C;"%G" 60 PRINT AT A,B;" + " 70 PRINT AT A-1,B;" " 80 PRINT AT A+1,B;" " 90 IF INKEY$="5" THEN LET B=B-1 100 IF INKEY$="8" THEN LET B=B+1 110 IF INKEY$="7" THEN LET A=A-1 120 IF INKEY$="6" THEN LET A=A+1 130 IF INKEY$="0" THEN GOTO 150 140 GOTO 50 150 IF D<>A THEN GOTO 50 160 IF C=B THEN GOTO 170 170 PRINT AT D-1,C;"\'. \.'" 180 PRINT AT D,C;" % " 190 PRINT AT D+1,C;"\.' \'." 200 RUN 210 SAVE "1018%3" 220 CLS 230 PRINT "REAR GUNNER" 240 PRINT ,,"USE CURSOR KEYS TO MOVE ""+"" USE ""0"" TO FIRE AT ""%G""" 250 PRINT "PRESS ENTER TO PLAY" 260 INPUT Z$ 270 RUN ```