This program renders an animated fireworks effect on screen using block graphics characters stored in a string variable. It first fills the entire display with a pattern of inverse-space and full-block characters to create a dark background, then draws five randomly positioned “burst” animations by expanding rings of characters outward in eight directions simultaneously. After the random bursts, a final centered explosion expands from position (10,15) with a radius of 8, before looping back to repeat. The program uses POKE 16418,0 to disable the system clock interrupt (or modify a system variable), and stores four animation-frame characters in A$ including block graphic characters for visual effect.
Program Analysis
Program Structure
The program is divided into four logical phases:
- Initialization (lines 1–6): Defines the animation character string
A$, sets a system variable viaPOKE 16418,0, and fills the screen with a dense background pattern of inverse spaces and full-block graphics. - Random burst loop (lines 7–27): Iterates five times (
C=1 TO 5), each time choosing a random screen position and animating an expanding ring of characters. - Centered explosion (lines 40–45): Performs a single large burst centered at row 10, column 15, expanding to radius 8.
- Loop (line 46): Jumps to line 2 (not line 1), reusing the background without re-initialising
A$, creating an infinite animation cycle.
Background Fill Technique
Lines 4–6 use a FOR X=0 TO 22 loop printing a long literal string at each row using PRINT AT X,0;. The string contains alternating inverse-space characters (% %) and a long run of full-block graphic characters (\''), creating a solid, patterned dark background that acts as the “night sky” for the fireworks.
Animation Frame Characters
The string A$ at line 1 contains four characters used as successive animation frames:
| Index (Y) | Escape / Character | Visual |
|---|---|---|
| 1 | \.' | ▞ (top-right + bottom-left block) |
| 2 | \:. | ▙ (three-quarter block) |
| 3 | %" | inverse quote character |
| 4 | %. | inverse period character |
Cycling through these four characters as the burst radius grows gives a crude animation effect simulating the changing density or shape of an explosion.
Eight-Direction Expansion
The core burst technique in lines 20–22 (and 42–44) prints the current frame character at eight compass positions relative to the burst centre simultaneously in a single PRINT statement:
- Left and right:
AT A,B-ZandAT A,B+Z - Up and down:
AT A-Z,BandAT A+Z,B - Four diagonals:
AT A-Z,B-Z,AT A-Z,B+Z,AT A+Z,B-Z,AT A+Z,B+Z
Using a single PRINT statement with multiple AT items is an efficiency idiom that avoids repeated PRINT AT calls and their associated overhead.
POKE 16418,0
POKE 16418,0 writes to the ZX81/TS1000 system variable FRAMES (low byte), resetting the frame counter. This has no direct visual effect on the animation but may be used to synchronise timing or simply as a housekeeping step at program start.
Loop Architecture and GOTO 40
Line 28 uses GOTO 40 to skip the SAVE command at line 30 during normal execution. Line 30 is a SAVE "1009%5" which stores the program; the %5 represents an inverse digit 5 in the filename. Line 31 redirects to line 1 if the save path were ever reached. The main loop at line 46 uses GOTO 2 rather than GOTO 1, deliberately skipping the re-initialisation of A$ and the POKE, which is correct since neither needs repeating.
Potential Anomalies
- The expanding burst in lines 20–22 does not erase previous frames — each new character simply overwrites the previous one at the same position, meaning earlier ring positions remain drawn. This is likely intentional, building up a bloom effect.
- When
Zor the random offsets place characters outside the valid screen area (rows 0–21, columns 0–31), aPRINT ATwith out-of-range coordinates will produce an error. For the random bursts, the position is constrained (A=INT(RND*15)+3,B=INT(RND*25)+3) butZruns to 3, so edge cases near borders could cause issues. The centered burst at radius 8 from (10,15) would reach column 23, still within bounds horizontally, but row 10+8=18 is safe; however row 10−8=2 and column 15−8=7 are also safe. - Line numbers jump from 9 to 14, 15 to 20, 22 to 26, and 27 to 28, leaving gaps that serve no apparent purpose other than allowing future line insertions.
Content
Source Code
1 LET A$="\.'\:.%"%."
2 POKE 16418,0
4 FOR X=0 TO 22
5 PRINT AT X,0;"% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % \''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''"
6 NEXT X
7 FOR C=1 TO 5
8 LET A=INT (RND*15)+3
9 LET B=INT (RND*25)+3
14 FOR Y=1 TO 4
15 PRINT AT A,B;A$(Y)
20 FOR Z=1 TO 3
21 PRINT AT A,B-Z;A$(Y);AT A,B+Z;A$(Y);AT A-Z,B;A$(Y);AT A+Z,B;A$(Y);AT A-Z,B-Z;A$(Y);AT A-Z,B+Z;A$(Y);AT A+Z,B-Z;A$(Y);AT A+Z,B+Z;A$(Y)
22 NEXT Z
26 NEXT Y
27 NEXT C
28 GOTO 40
30 SAVE "1009%5"
31 GOTO 1
40 FOR Y=1 TO 4
41 PRINT AT 10,15;A$(Y)
42 FOR Z=1 TO 8
43 PRINT AT 10,15-Z;A$(Y);AT 10,15+Z;A$(Y);AT 10-Z,15;A$(Y);AT 10+Z,15;A$(Y);AT 10-Z,15-Z;A$(Y);AT 10-Z,15+Z;A$(Y);AT 10+Z,15-Z;A$(Y);AT 10+Z,15+Z;A$(Y)
44 NEXT Z
45 NEXT Y
46 GOTO 2
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
