This program implements a King Kong arcade-style game in which the player navigates a character up a multi-level building to reach Kong at the top, avoiding gorillas that patrol the platforms. The game loads a custom character set via `LOAD “CHARACTERS” CODE USR “A”, 18*8`, replacing 18 UDG characters (A through R) used to draw Kong, the player sprite, gorillas, and decorative elements. Attribute-based collision detection uses `ATTR()` and `SCREEN$()` to distinguish solid platforms (attribute 41), enemy sprites (attribute 40), and ladders (attribute 107). The score is tracked using a timer built from the Spectrum’s frame counter at memory addresses 23672–23674, converted to seconds via `DEF FN S()`. A high-score system prompts for the player’s name when a new shortest time is recorded, persisting it in `N$` across replays within the same session.
Program Analysis
Program Structure
The program is organized into a main game loop with several subroutines handling distinct subsystems. Initialization at line 20–30 loads assets and sets variables; the screen layout is drawn by the subroutine at 1000–1160. The main loop runs from line 60 to 410 and drives movement, input, collision, and enemy animation each frame.
| Line(s) | Role |
|---|---|
| 20–50 | Asset loading, variable initialization, timer setup |
| 60–410 | Main game loop: rendering, input, collision, enemy AI |
| 420–470 | Enemy kill (crunch) death sequence and restart |
| 480–550 | Fall-through-hole death sequence |
| 560–610 | Elevator/lift ride sequence |
| 620–650 | Barrel/projectile hit tracking |
| 660–770 | King Kong appearance animation |
| 780–830 | Left and right punch/kick subroutines |
| 840–870 | Barrel clear / floor collapse subroutine |
| 880–900 | Princess rescue trigger |
| 910–970 | Kong kill sequence, score display, replay |
| 980–990 | High-score name entry |
| 1000–1160 | Screen draw subroutine (platforms, ladders, decorations) |
| 9998 | SAVE commands for both BASIC and machine code |
Custom Character Set (UDGs)
Eighteen UDG characters A–R are loaded from a separate code file into USR "A", replacing the standard UDGs. These characters are referenced throughout using zmakebas escapes \a through \r in PRINT statements. The characters represent components of Kong, the player, gorillas, elevator cars, barrels, and structural elements. The load command LOAD "CHARACTERS" CODE USR "A", 18*8 precisely sizes the block to 144 bytes.
Collision Detection
The game uses two complementary collision mechanisms:
- Attribute-based:
ATTR(M,N)andATTR(M+1,N)are compared against specific values (40 = enemy, 41 = solid platform, 107 = ladder) to detect hazards and traversable surfaces. - Character-based:
SCREEN$(M,N)checks for specific characters like"_"(elevator trigger) and"-"(barrel marker) to trigger special game events.
This dual approach is a common technique when attribute colors encode object type and character content encodes state simultaneously.
Timer Implementation
The game measures elapsed time using the system’s frame counter spread across three memory locations. Line 40 zeroes addresses 23672, 23673, and 23674, and line 50 defines a function:
DEF FN S()=INT((PEEK 23672 + PEEK 23673*256 + PEEK 23674*65535)/60)
This reconstructs a 24-bit frame count (noting that the multiplier for the third byte should strictly be 65536, making 65535 a minor off-by-one bug) and divides by 60 to convert frames to seconds. The result is used for the high-score time comparison at line 940.
Enemy AI
Two independent enemy movement modes are chosen randomly each frame at line 160 with a 75% probability of using the “tracking” branch:
- Tracking mode (lines 170–200): Gorilla positions
CandVincrementally converge on the player columnN. - Bouncing mode (lines 220–260): Gorillas traverse the screen in opposite directions, reversing at the screen edges using sign variables
EandF.
Variable Reuse and Anomalies
Line 30 assigns LET E=1 twice, with the second assignment redundant. Variable E is also used as both the horizontal direction increment for gorilla bouncing and is initially set alongside F=-1. Variable S is reused as both a loop counter (lines 540, 900) and the elapsed-time score (line 910 onward), which could cause a collision if the death sequences ran during the win sequence — though the game flow prevents this in practice.
Kong Appearance Sequence
When the player reaches position row 2, column 11 with X=0, subroutine 660 triggers a multi-stage animation drawing Kong piece by piece using UDG characters across several FOR loops. The sequence sets X=1 to prevent re-triggering. A subsequent condition at line 390 checks for X=1 to enable the princess rescue, and line 840 checks X=2 and barrel count T=8 to trigger the Kong kill sequence.
Key BASIC Idioms
- Conditional string expressions: Line
440uses(" KING KONG KILLED YOU " AND M=5)to select between two death messages based on row position — a standard Sinclair BASIC boolean-as-multiplier trick. - OVER 1 for erase: Printing a sprite with
OVER 1twice at the same position erases it, used for the punch animation at lines780–810. - Gravity simulation: Lines
480–520implement falling by looping downward, checkingSCREEN$for a non-empty cell before stopping.
Screen Layout Subroutine
The subroutine at lines 1000–1160 draws the entire game screen: vertical wall UDGs (\f = UDG F) as borders, four horizontal platform rows using INK 0 hash characters, ladder positions using OVER 1, score markers, and the initial Kong and player sprites. The BRIGHT 1 asterisks at line 1140 mark the ladder connection points between floors.
Save Block
Line 9998 saves both the BASIC program with an auto-run line and the UDG character data as a separate CODE block named "CHARACTERS", followed by two VERIFY commands to confirm both saves.
Content
Source Code
20 LOAD "CHARACTERS"CODE USR "A",18*8: BORDER 2: INK 3: PAPER 5: CLS : LET H=9999: LET N$="NICHOLAS WYRE"
30 LET X=0: LET E=1: LET F=-1: LET C=1: LET V=21: LET G=500: LET M=21: LET N=2: LET E=1: LET T=0: LET E$="\g": GO SUB 1000: LET B=2: LET D=1
40 POKE 23672,0: POKE 23673,0: POKE 23674,0
50 DEF FN S()=INT ((PEEK 23672+PEEK 23673*256+PEEK 23674*65535)/60)
60 PRINT AT M,N; INK 1; OVER 1;E$: BEEP .05,10: PRINT AT M,N; OVER 1; INK 1;E$
70 PRINT AT 2,B; INK 1;" \r ";AT 1,B;"_:_"
80 PRINT AT 9,C;" \l \l \l ";AT 13,V;" \l \l \l ";AT 17,C;" \l \l \l ";AT 21,V;" \l \l \l "
90 LET Z$=INKEY$
100 IF RND<.5 THEN PRINT AT 3,19;"\..#\''": GO TO 120
110 PRINT AT 3,19;"\a\::\c"
120 IF RND<.5 THEN PRINT AT 5,19;"\d \e": GO TO 140
130 PRINT AT 5,19;"\e\d "
140 IF B=2 THEN LET D=1
150 IF B=6 THEN LET D=-1
160 IF RND<.75 THEN GO TO 220
170 IF V>2 AND V>N THEN LET V=V-1
180 IF V<21 AND V<N THEN LET V=V+1
190 IF C<21 AND C<N THEN LET C=C+1
200 IF C>2 AND C>N THEN LET C=C-1
210 GO TO 270
220 LET C=C+E: LET V=V+F
230 IF C>21 THEN LET E=-1
240 IF C<3 THEN LET E=1
250 IF V<3 THEN LET F=1
260 IF V>21 THEN LET F=-1
270 LET B=B+D
280 IF M=2 AND N=11 AND X=0 THEN GO SUB 660
290 IF Z$="7" AND ATTR (M-1,N)=41 THEN LET E$="\n": LET M=M-1
300 IF Z$="6" AND ATTR (M+1,N)=41 THEN LET E$="\n": LET M=M+1
310 IF Z$="5" AND N>0 THEN LET N=N-1: LET E$="\k"
320 IF Z$="8" AND N<>31 THEN LET E$="\h": LET N=N+1
330 IF SCREEN$ (M,N)<>" " AND ATTR (M,N)=40 THEN GO TO 420
340 IF SCREEN$ (M,N)="_" THEN GO TO 560
350 IF SCREEN$ (M+1,N)=" " AND M<>21 THEN GO TO 480
360 IF ATTR (M+1,N)=107 THEN GO SUB 620
370 IF Z$="4" AND N>1 THEN GO SUB 780
380 IF Z$="9" AND N<30 THEN GO SUB 810
390 IF M=21 AND N=0 AND X=1 THEN GO SUB 880
400 BEEP .01,1
410 GO TO 60
420 PRINT AT M,N; FLASH 1;"\o";AT 10,13;"CRUNCH"
430 FOR N=0 TO 7: FOR X=0 TO 7: BEEP .05,N: BORDER RND*7: NEXT X: NEXT N
440 PAPER 3: INK 7: CLS : FLASH 1: PRINT AT 8,5;(" KING KONG KILLED YOU " AND M=5);AT 8,5;(" A GORILLA SQUASHED YOU " AND M<>5)
450 PRINT AT 18,1;"PRESS ANY KEY TO PLAY AGAIN !";AT 14,1;"SHORTEST TIME = ";H''"by ";N$
460 IF INKEY$="" THEN BEEP .01,RND*25: BORDER RND*7: GO TO 460
470 FLASH 0: BORDER 2: INK 3: PAPER 5: CLS : GO TO 30
480 IF SCREEN$ (M,N)<>" " THEN LET M=M-1: GO TO 530
490 PRINT AT M,N;"\g";AT M-1,N;" "
500 IF M=21 THEN GO TO 530
510 LET M=M+1: BEEP .03,M
520 GO TO 480
530 PRINT AT M,N; FLASH 1;"\o";AT 10,13;"SPLAT!"
540 FOR N=0 TO 7: FOR S=7 TO 0 STEP -1: BEEP .01,S*N: BORDER S: NEXT S: NEXT N
550 PAPER 4: INK 1: CLS : FLASH 1: PRINT AT 8,4;"YOU FELL THROUGH A HOLE";AT 10,9;" TO YOUR DEATH";AT 12,1;"AND YOU ARE NOW MUCH THINNER !": GO TO 450
560 PRINT AT 1,2;"- -";AT 2,2;"[ ]";AT 3,2;"[ ]";AT 4,2;"\r": LET N=N+(1 AND N=2)-(1 AND N=7)
570 FOR A=2 TO 5: PRINT AT A-1,N;" "
580 BEEP .04,M
590 PRINT AT A,N;"\g": NEXT A
600 LET M=5
610 GO TO 530
620 LET T=T+1: PRINT AT M+1,N;"-"
630 IF SCREEN$ (M+1,27)="-" AND N=13 THEN GO SUB 840
640 IF SCREEN$ (M+1,13)="-" AND N=27 THEN GO SUB 840
650 BEEP .01,50: RETURN
660 LET X=1
670 PRINT AT 0,8; FLASH 1;"\m\m\m\m\m\m": BEEP 1,10
680 FOR A=11 TO 13: PRINT AT 1,A;" \p";AT 2,A;" \q": BEEP .05,A: NEXT A
690 INK 1
700 PRINT AT 2,14;"\f": BEEP .05,50
710 FOR A=14 TO 25: PRINT AT 0,A;" \p";AT 1,A;"\''\q": BEEP .01,A: NEXT A
720 PRINT AT 0,13;" \f";AT 1,14;"\f"
730 FOR A=0 TO 3: PRINT AT A,26;"\f";AT A+1,26;"\p";AT A+2,26;"\q": BEEP .05,A: NEXT A
740 PRINT AT 4,26;"\f\p";AT 5,26;"\f\q": BEEP .0,50
750 FOR A=27 TO 29: PRINT AT 4,A;" \p";AT 5,A;" \q": BEEP .05,A: NEXT A
760 INK 1: PRINT AT 4,29;"\ :";AT 5,29;"\ :";I4,30; FLASH 1;"\p";AT 5,30;"\q"
770 FLASH 0: RETURN
780 PRINT AT M-1,N-1; OVER 1;"\j": BEEP .05,M: PRINT AT M-1,N-1; OVER 1;"\j": BEEP .05,M
790 IF SCREEN$ (M,N-2)<>" " AND ATTR (M,N-2)=40 THEN GO TO 420
800 LET N=N-2: RETURN
810 PRINT AT M-1,N+1; OVER 1;"\i": BEEP .05,M: PRINT AT M-1,N+1; OVER 1;"\i": BEEP .05,M
820 IF SCREEN$ (M,N+2)<>" " AND ATTR (M,N+2)=40 THEN GO TO 420
830 LET N=N+2: RETURN
840 IF T=8 AND X=2 THEN GO TO 910
850 FOR Q=M+1 TO M+4
860 BEEP .01,Q: PRINT AT Q-1,14;" ";AT Q,14;"#############": NEXT Q
870 RETURN
880 LET X=2: PRINT AT 4,30;"\::";AT 5,30;"\::";AT 3,30;"\::"
890 BEEP 1,0
900 FOR A=5 TO 2 STEP -1: PRINT AT A,29;" ";AT A-3,29;"\ :\::\: ": BEEP .1,A: NEXT A: PRINT AT 2,29;" ": BEEP .1,10: PRINT AT 1,29;" ": BEEP .1,15: PRINT AT 0,29;" ": BEEP 1,20: RETURN
910 LET S=FN S(): PRINT AT 2,20;" ";AT 3,19;"\a0\cGULP!": BEEP .5,2: PRINT AT 3,19;" ";AT 4,19;"0 ";AT 5,20;"\d": BEEP .5,3: PRINT AT 4,19;" ";AT 5,20;" ";AT 5,19;"\b0,\e": BEEP .5,3
920 FOR Q=6 TO 21: PRINT AT Q,14;"#############";;AT Q-2,19;" ";AT Q-1,14;" \bO \e ": BEEP .05,Q: NEXT Q: FOR J=-50 TO 50: BEEP .03,J: NEXT J
930 PAUSE 100: CLS : PRINT AT 2,0;"YOU HAVE KILLED KONG AND YOU HAVE SAVED THE PRINCESS."'',"TIME = ";S
940 IF S<H THEN GO SUB 980
950 PRINT AT 15,5;"THE SHORTEST TIME = ";H'"BY SIR ";N$
960 PRINT AT 18,0; FLASH 1;"PRESS ANY KEY FOR ANOTHER GAME!": BORDER RND*7: BEEP .01,RND*25: IF INKEY$="" THEN GO TO 960
970 BEEP 1,8: CLS : GO TO 30
980 LET H=S: INPUT "YOU HAVE THE SHORTEST TIME PLEASE ENTER YOUR NAME ";N$
990 RETURN
1000 FOR Q=5 TO 21: PRINT AT Q,0;; INK 1;"\f";AT Q,31;"\f": NEXT Q
1010 PRINT AT 6,1; INK 0;"###############################";AT 10,0;"# ## # ## # ################# #";AT 14,1;"### #### # ################# ##";AT 18,0;"#### ## ### ################# #"
1020 PRINT AT 11,0; OVER 1; INK 2;"["'"["
1030 FOR Q=7 TO 8: PRINT AT Q,31; OVER 1; INK 2;"]";AT Q+8,31;"]": NEXT Q
1040 PRINT AT 19,0; PAPER 4;"@"'"@"'"@"
1050 INK 1: PRINT AT 1,2;"_______"
1060 PRINT AT 4,26;"\f";AT 5,26;"\f";AT 4,1;"\f";AT 5,1;"\f"
1070 FOR Q=0 TO 3: PRINT AT Q,1;"\f";AT Q,9;"\f";AT Q,14;"\f";AT Q,26;"\f": NEXT Q
1080 PRINT AT 0,8; FLASH 1;"<HELP>"
1090 PRINT AT 3,9; INK 0;"######";AT 1,15; INK 1;"\''\''\''\''\''\''\''\''\''\''\''"
1100 PRINT AT 1,11;"\p";AT 2,11;"\q"
1110 INK 1
1120 PRINT AT 3,29;"\ :\''\: ";AT 4,29;"\ : \: ";AT 5,29;"\ : \: "; INK 6;AT 0,30;"[";AT 1,30;"[";AT 2,30;"["
1130 INK 0: PRINT AT 2,20;"\b";AT 3,19;"\a\::\c";AT 4,20;"\::";AT 5,19;"\d \e"
1140 INK 3: BRIGHT 1: PRINT AT 6,13;"*";AT 6,27;"*";AT 10,13;"*";AT 10,27;"*";AT 14,13;"*";AT 14,27;"*";AT 18,13;"*";AT 18,27;"*"
1150 BRIGHT 0: INK 0
1160 RETURN
9998 SAVE "KING-KONG" LINE 10: SAVE "CHARACTERS"CODE USR "A",18*8: VERIFY "": VERIFY ""CODE
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
