Gunner

This file is part of and Timex Sinclair Public Domain Library Tape 1002. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Game

Gunner is a shooting gallery game where the player moves a cannon left and right along the bottom of the screen, firing upward at two scrolling rows of random alphabetic characters. The scrolling text is stored in a single one-dimensional string array DIM A$(1,6000), with a window into it advancing by two characters per frame to create the horizontal scroll effect. Characters are drawn from CHR$(166) to CHR$(191), corresponding to the ZX81’s block-graphic and letter characters. The player scores points based on the ASCII value of the character hit (R-165), making letters deeper in the alphabet worth more. A special “@@ ” target occasionally appears in the scroll; if it reaches the leftmost visible position without being shot, the round ends.


Program Analysis

Program Structure

The program begins with a title/instructions block (lines 500–600) before jumping back to initialization. The main game loop runs from line 60 onward, with the bullet flight handled inline rather than in a subroutine.

  1. Lines 1–2: REM header and GOTO 500 to skip to the title screen.
  2. Lines 5–15: Initialize high score, cannon height, and the large scroll buffer array.
  3. Lines 20–40: Pre-fill odd-indexed positions 1–65 of A$ with random characters (CHR$ 166–191).
  4. Lines 45–135: Main game loop — display scores, draw the two scrolling rows and the cannon, handle keyboard input.
  5. Lines 140–210: Bullet movement upward; uses PEEK of the display file to detect hits.
  6. Lines 250–310: Hit processing — calculate score, erase the hit character from the scroll buffer, reset bullet.
  7. Lines 350–470: End-of-round sequence; checks high score, prompts replay.
  8. Lines 500–600: Title screen and instructions.
  9. Lines 700–710: SAVE and RUN trailer.

Scroll Buffer Design

All scrolling data lives in DIM A$(1,6000), a single-row string array 6000 characters wide. The pointer N starts at 2 and increments by 2 each frame. The display routine prints A$(1,N TO N+31) on row 3 and A$(1,N+33 TO N+65) on row 5, giving two 32-character wide lanes. New characters are appended at A$(1,N+65) each frame, so the buffer grows rightward as the game progresses. Because N only increments, the program will eventually exhaust the 6000-character buffer after approximately 2967 frames without a round end.

Hit Detection via PEEK

Rather than tracking bullet-vs-character coordinates algebraically, the game uses a direct display-file inspection technique. Lines 155–156 place the print position at the bullet’s location, PEEK the display file address from system variables at addresses 16398–16399, read the character code already at that screen cell, then overprint with ".". If the PEEKed value R is non-zero (i.e., something other than a space was already there), a hit is registered.

  • PEEK 16398 + 256 * PEEK 16399 gives the address of the current print position in the display file.
  • A score contribution of R - 165 is calculated, so CHR$(166)=’A’ scores 1, up to CHR$(191) scoring 26.

Special Target (“@@”)

Approximately once every 40 frames (INT(RND*40)=10), the character appended to the buffer is the two-character sequence \@@ (rendered as a block-graphic pair). Line 95 checks whether A$(1,N+1) equals this token; if so, the round ends with a “got away” message. This means the special target must scroll entirely off the left edge of the visible window without being shot to trigger the loss condition.

Cannon Rendering

The cannon graphic occupies two screen rows: row 21 shows " \.: " (the barrel, using ZX81 block graphics) and row 20 shows " . " (the base). The horizontal position is controlled by variable Z, clamped between 1 and 28 by lines 110–120. Keys 5 and 8 move left and right; key 7 fires.

Bullet Flight

The bullet is a single "." character that travels from row 19 upward to row 3 in steps of 2 (H decrements by 2 per frame). Flag variable X tracks whether a bullet is in flight: X=1 means in-flight, X=0 means idle. When X<>0, keyboard input is skipped (line 105), so the player cannot move or fire again until the bullet resolves.

Score Erasure on Hit

When a hit occurs, the program attempts to blank the character in the scroll buffer at the appropriate offset. Line 280 handles a hit on row 3 (H=3) using A$(1,N+(Z-1))=" ", and line 290 handles row 5 (H=5) using A$(1,N+(32+Z))=" ". The index arithmetic is approximate and may be off by one depending on exact scroll position, which can cause occasional visual artifacts.

Notable Bugs and Anomalies

  • The odd-index pre-fill loop (lines 20–40, STEP 2) only populates positions 1, 3, 5, …, 65, leaving even positions as null bytes (CHR$ 0). This means the initial scroll contains interleaved garbage/null characters until the per-frame append (line 80) fills the buffer further right.
  • The bullet height variable H is initialized to 19 at line 8 but is reset to 19 only at line 300 (after a hit). A missed shot that reaches row 3 resets X=0 at line 200 but does not reset H, so the next shot starts from wherever H was last left (row 1 or 3), not from row 19. This is a definite bug.
  • The INPUT at line 430 accepts full words “YES”/”NO” as well as single letters, but the GOTO loop is only re-entered if none of the four options match, meaning any other input is also silently accepted and falls through — the condition logic at line 460 then treats an unrecognized answer as “no”.
  • The DIM A$(1,6000) on line 10 declares a two-index string array but is accessed throughout with single-index slice notation A$(1,…). This is valid ZX81 syntax for a 1-row string array.

Key Variables

VariableRole
A$6000-character scroll buffer
NCurrent read offset into scroll buffer
ZCannon horizontal position (column)
HBullet vertical position (row)
XBullet in-flight flag (0=idle, 1=in-flight)
SCurrent score
HSHigh score (persists across rounds)
RPEEKed character code at bullet position

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Related Content

Image Gallery

Gunner

Source Code

   1 REM ***GUNNER***
   2 GOTO 500
   5 LET HS=0
   8 LET H=19
  10 DIM A$(1,6000)
  15 LET X=0
  20 FOR N=1 TO 65 STEP 2
  30 LET A$(1,N)=CHR$ (INT (RND*26)+166)
  40 NEXT N
  45 LET N=2
  50 LET Z=0
  55 LET S=0
  60 PRINT AT 0,0;"SCORE","HIGH-SCORE";AT 1,0;S,HS
  70 PRINT AT 3,0;A$(1,N TO N+31);AT 5,0;A$(1,N+33 TO N+65);AT 21,Z;" \.: ";AT 20,Z;" . "
  80 LET A$(1,N+65)=CHR$ (INT (RND*26)+166)
  90 IF INT (RND*40)=10 THEN LET A$(1,N+65)="\@@"
  95 IF A$(1,N+1)="\@@" THEN GOTO 350
 100 LET N=N+2
 105 IF X<>0 THEN GOTO 140
 110 IF INKEY$="8" AND Z<28 THEN LET Z=Z+1
 120 IF INKEY$="5" AND Z>1 THEN LET Z=Z-1
 130 IF INKEY$="7" THEN GOTO 140
 135 GOTO 70
 140 LET H=H-2
 150 PRINT AT H,Z+1;
 155 LET R=PEEK (PEEK 16398+256*PEEK 16399)
 156 PRINT "."
 160 PRINT AT H+2,Z+1;" "
 170 LET X=1
 180 IF R<>0 THEN GOTO 250
 190 IF H<3 THEN PRINT AT H,Z+1;" "
 200 IF H<3 THEN LET X=0
 210 GOTO 70
 250 IF R-165<0 THEN LET R=165
 255 LET S=S+(R-165)
 260 LET X=0
 270 PRINT AT 1,0;S
 280 IF H=3 THEN LET A$(1,N+(Z-1))=" "
 290 IF H=5 THEN LET A$(1,N+(32+Z))=" "
 300 LET H=19
 310 GOTO 70
 350 CLS 
 360 PRINT "SCORE","HIGH-SCORE"
 370 IF S>HS THEN LET HS=S
 380 PRINT S,HS
 390 PRINT 
 400 PRINT "THE ""\@@"" GOT AWAY."
 410 PRINT 
 420 PRINT "DO YOU WANT TO TRY AGAIN(Y/N)?"
 430 INPUT Z$
 440 IF Z$<>"YES" AND Z$<>"Y" AND Z$<>"NO" AND Z$<>"N" THEN GOTO 430
 450 CLS 
 460 IF Z$="YES" OR Z$="Y" THEN GOTO 8
 470 STOP 
 500 PRINT TAB 12;"GUNNER"
 510 PRINT TAB 12;"------"
 520 PRINT 
 530 PRINT "THE POINT OF THIS GAME IS TO GET AS MANY POINTS AS POSSIBLE BY SHOOTING THE LETTERS; BUT YOU MUST NOT LET THE ""\@@"" GET AWAY."
 540 PRINT "THE FURTHER THE LETTER IS IN THE ALPHABET THE MORE ITS WORTH. FOR EXAMPLE ""%Z"" IS WORTH MORE THAN ""%A"". TO MOVE THE GUN YOU USE THE"
 550 PRINT "CURSOR KEYS AND THE UPWARD POINTING CURSOR KEY TO FIRE.",,,"GOOD LUCK"
 560 PRINT 
 570 PRINT "HIT ANY KEY TO CONTINUE."
 580 IF INKEY$="" THEN GOTO 580
 590 CLS 
 600 GOTO 5
 700 SAVE "1006%7"
 710 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top