--- title: "Laser Cannon" id: 57242 type: "computer_media" slug: "laser-cannon" url: "http://localhost/computer_media/laser-cannon/" markdown_url: "http://localhost/computer_media/laser-cannon.md" published_at: "2024-10-04T07:10:57+00:00" modified_at: "2026-03-30T21:19:05+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/132_LsrC.png" excerpt: "Guide your cannon with three keys and blast 21 incoming targets before five slip past — but watch your fuel supply carefully." 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: 56734 title: "Timex Sinclair Public Domain Library Tape 1003" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1003/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/10/132_LsrC.png" media_type_tags: "Arcade, Game" --- Laser Cannon is a simple shooting gallery game where the player controls a cannon along the left edge of the screen and attempts to destroy incoming targets moving from right to left. The player uses keys 5/6/7 to move the cannon vertically and key 8 to fire. The cannon character is rendered using CHR$ 130 and CHR$ 128 (Spectrum block graphics), while CHR$ 189 displays a hit explosion character. The game tracks fuel (variable J, decremented by key 5), ends in victory after destroying 21 targets, or in defeat if 5 targets get through. The target X-position is randomised each round using INT(RND*18)+2, and movement is achieved by decrementing Y by 1.5 each loop iteration without CLS between print calls to create a scrolling effect. *** ## Program Analysis ### Program Structure The program is a single-file game with no subroutines, relying entirely on `GOTO` for flow control. The main game loop runs from lines `90` to `210`, with a new target initialised at line `50` each time one is destroyed or reaches the left side. End conditions branch to either a win screen at line `260` or a loss screen at line `240`. 1. Lines 10–40: Initialise variables (score `A`, fuel `J`, cannon row `K`, targets-missed `G`) 2. Lines 50–80: Set up a new target at a random row `X`, advance target counter 3. Lines 90–210: Main display/input/movement loop 4. Lines 220–230: Hit detected — display explosion character, loop to next target 5. Lines 240–270: End-game messages (loss and win) 6. Lines 300–310: Save and restart ### Key Variables | Variable | Purpose | | --- | --- | | `A` | Target counter; game won when `A=21` | | `J` | Fuel; decremented by key 5, displayed at win screen | | `K` | Cannon row (vertical position) | | `G` | Targets missed; game lost when `G=5` | | `X` | Random row of the current target | | `Y` | Horizontal position of the target, starts at 30 | ### Display Technique The cannon is drawn using `CHR$ 130` and `CHR$ 128`, which are Spectrum block graphic characters, giving it a solid blocky appearance at column 0. The target is a plain `"X"` character placed via `AT X,Y`. There is no `CLS` inside the tightest loop — line `200` issues `CLS` only once per full loop iteration, meaning the screen is redrawn from scratch each cycle rather than using incremental updates. This causes inevitable flicker but keeps the code simple. A hit triggers display of `CHR$ 189` at the target position (line `220`), which is the copyright/explosion-style character used as a visual “bang” effect. ### Movement and Hit Detection The target moves left by decrementing `Y` by `1.5` each loop (line `150`). Because `PRINT AT` truncates to integer column positions, this gives effective movement every other iteration, producing a smoother visual step than decrementing by 1 would. Hit detection at line `190` checks that key 8 is held, the cannon row `K` equals the target row `X`, and the target column `Y` is less than 21 (i.e., within laser range). The laser itself is drawn as a string of asterisks at line `130` purely cosmetically and has no role in the hit logic. ### Notable Techniques and Anomalies - The `INKEY$` at lines `110`–`140` and `190` are all separate reads in the same loop iteration, so simultaneous key effects are not possible and there is slight timing sensitivity. - Line `100` checks `IF J<0` and skips to line `150`, bypassing all input processing when fuel is exhausted — effectively immobilising the player but not ending the game, which is an unusual design choice. - The condition `IF Y=3` at line `160` relies on `Y` landing exactly on 3 when stepping by 1.5 from 30. Starting at 30 and subtracting 1.5 repeatedly: 30, 28.5, 27, 25.5 … 4.5, 3 — this works correctly since 30 and 3 differ by 27, a multiple of 1.5. - Key 5 is labelled “move” in the REM but actually decrements fuel `J`, with movement left handled implicitly by the target approaching; the REM comment is slightly misleading. - Lines `300`–`310` save and immediately `RUN` the program, providing an auto-restart after saving. ## Source Code ``` 5 REM LASER CANNON 6 REM 5/7KEYS MOVE YOU AND 8 FIRES THE LASER 10 LET A=0 20 LET J=100 30 LET K=10 40 LET G=0 50 LET X=INT (RND*18)+2 60 LET A=A+1 70 IF A=21 THEN GOTO 260 80 LET Y=30 90 PRINT AT K,0;CHR$ 130;CHR$ 128;AT X,Y;"X" 100 IF J<0 THEN GOTO 150 110 IF INKEY$="7" THEN LET K=K-1 120 IF INKEY$="6" THEN LET K=K+1 130 IF INKEY$="8" THEN PRINT AT K,2;"********************" 140 IF INKEY$="5" THEN LET J=J-1 150 LET Y=Y-1.5 160 IF Y=3 THEN LET G=G+1 170 IF G=5 THEN GOTO 240 180 IF Y=3 THEN GOTO 50 190 IF INKEY$="8" AND K=X AND Y<21 THEN GOTO 220 200 CLS 210 GOTO 90 220 PRINT AT X,Y+1;CHR$ 189 230 GOTO 50 240 PRINT "DESTROYED" 250 STOP 260 PRINT "YOU WIN" 270 PRINT "FUEL LEFT= ";J 300 SAVE "1013%2" 310 RUN ```