A wall is a decision waiting to happen. For now we will draw it; next lesson we will ask the map whether a player may cross it.
Use Sinclair BASIC on a stock 48K PAL ZX Spectrum. Begin with a new program and enter this listing. Numbered lines are stored in numerical order. Colons separate statements on one line; gaps between numbers leave space for later work. Meet BASIC explains the Spectrum’s keyword entry and editing controls if you need them.
10 GO SUB 7000: GO SUB 7100: GO SUB 1000
20 STOP
1000 BORDER 0: PAPER 0: INK 7: BRIGHT 0: CLS
1010 PRINT AT 0,1; INK 5; BRIGHT 1;"NIGHT PATROL";AT 0,20;"THE ARCHIVE"
1020 FOR r=1 TO 18: PRINT AT r+1,1; INK 1; BRIGHT 1;m$(r): NEXT r
1022 PRINT AT 4,27; INK 5;CHR$ 146
1024 PRINT AT 17,3; INK 4;CHR$ 147
1050 RETURN
7000 RESTORE 7500: FOR j=0 TO 31: READ a: POKE USR "a"+j,a: NEXT j: RETURN
7100 DIM m$(18,30): RESTORE 7200
7110 FOR r=1 TO 18: READ m$(r): FOR c=1 TO 30
7120 IF m$(r,c)="#" THEN LET m$(r,c)=CHR$ 145
7130 NEXT c: NEXT r: RETURN
7200 DATA "##############################"
7210 DATA "##############################"
7220 DATA "########### ############# ###"
7230 DATA "##### ####### # ###"
7240 DATA "##### ###"
7250 DATA "##### ###### # #####"
7260 DATA "###### ######### ##### ######"
7270 DATA "###### ############ ######"
7280 DATA "###### ############ ######"
7290 DATA "###### ############## ######"
7300 DATA "#### ################ ####"
7310 DATA "#### #### ########## ####"
7320 DATA "##### ####### #####"
7330 DATA "##### #####"
7340 DATA "##### ###### # #####"
7350 DATA "## ######### ############"
7360 DATA "##############################"
7370 DATA "##############################"
7500 DATA 24,24,0,60,90,24,36,66
7510 DATA 255,128,128,255,8,8,8,255
7520 DATA 126,66,90,66,90,66,126,0
7530 DATA 126,66,66,74,66,66,126,0Enter RUN without a line number. The archive, file and entrance should appear, followed by 9 STOP statement, 20:1. That is the planned end of this drawing program. There is no player to move yet.
Read a map
Lines 7200–7370 hold eighteen quoted strings, each thirty characters long. A hash marks a wall; a space marks floor. Preserve those spaces when typing. DIM m$(18,30) makes eighteen fixed-length strings. m$(r) selects a whole row; m$(r,c) selects its character at column c. These indices start at one.
DATA stores values in the program. READ consumes the next value; RESTORE chooses where reading begins. The map routine starts at 7200 so it cannot accidentally consume the character patterns instead. Its outer FOR/NEXT loop visits each row, while the inner loop visits that row’s columns. It replaces each hash with the brick character, leaving floor as spaces.
Line 10 calls three subroutines with GO SUB: prepare graphics, read the map, draw the screen. RETURN comes back to the statement after the call. This keeps each job together, even though the routines live farther down the listing.
Make four little pictures
A user-defined graphic has eight rows of eight dots. Each DATA value supplies one row. The dot weights, left to right, are 128, 64, 32, 16, 8, 4, 2 and 1. Add the weights of the dots you want lit. The player’s first row is 24: 16 + 8, the two middle dots. The brick’s first row is 255: all eight dots.
USR "a" gives the memory address of the first graphic’s pattern. POKE stores each value there; j runs from 0 through 31 to fill four consecutive eight-byte patterns. This use of USR looks up an address. It does not call machine code. CHR$ turns a character number into a printable character: 144 is our player, 145 the brick, 146 the file and 147 the entrance.
Map coordinates and screen coordinates
We describe positions as (column, row). The map runs from column 1 to 30 and row 1 to 18. PRINT AT takes screen row, column, with screen rows starting at zero. We draw map row r at screen row r + 1, leaving room for two heading rows. Column zero remains a left margin.
| Object | Map position | PRINT AT position |
|---|---|---|
| File | (27, 3) | 4, 27 |
| Entrance | (3, 16) | 17, 3 |
BORDER sets the surrounding border; INK and PAPER select foreground and background colours. CLS clears the display. The map drawing loop prints whole rows, then draws the two objects over their floor squares.
If we print the bricks in a different colour, have we changed the corridors?
Show the explanation
No. The strings still contain exactly the same wall characters. Next lesson’s movement test will read those strings, so changing the drawing colour will leave the walls where they are.
Count the rows and columns in the DATA before moving on. A missing space can shift a passage while leaving the listing apparently tidy. If the objects appear in walls, compare their map rows with the complete source.
Sources
Steven Vickers, edited by Robin Bradbeer, ZX Spectrum BASIC Programming, second edition (Sinclair Research, 1983), chapter 6, chapter 5, chapter 12, chapter 14, chapter 15, chapter 16.
Run it here
This unit's program, built for you.
- Program
- night-patrol.tap
- Machine
- ZX Spectrum 48K (PAL)