Wall Collisions
Check the map array before moving to prevent walking through walls.
The player can walk anywhere — including through walls. That needs fixing. Before moving, check whether the target cell is a wall by reading the map array.
The Program
10 BORDER 0: PAPER 0: INK 7: CLS
20 DIM m$(8, 16)
30 FOR i = 1 TO 8
40 READ m$(i)
50 NEXT i
60 REM draw map
70 FOR r = 1 TO 8
80 FOR c = 1 TO 16
90 IF m$(r)(c TO c) = "#" THEN PRINT AT r + 2, c + 2; INK 1; CHR$ 143
100 NEXT c
110 NEXT r
120 LET r = 6: LET c = 2
130 REM game loop
140 PRINT AT r + 2, c + 2; INK 7; BRIGHT 1; "@"
150 LET k$ = INKEY$
160 IF k$ = "" THEN GO TO 150
170 LET u = r: LET z = c
180 IF k$ = "q" THEN LET u = r - 1
190 IF k$ = "a" THEN LET u = r + 1
200 IF k$ = "o" THEN LET z = c - 1
210 IF k$ = "p" THEN LET z = c + 1
220 IF u < 1 OR u > 8 OR z < 1 OR z > 16 THEN GO TO 140
230 IF m$(u)(z TO z) = "#" THEN GO TO 140
240 PRINT AT r + 2, c + 2; " "
250 LET r = u: LET c = z
260 GO TO 140
500 DATA "################"
510 DATA "# #"
520 DATA "# ## #### # #"
530 DATA "# # # #"
540 DATA "# #### # #"
550 DATA "# # # #"
560 DATA "# ## # #"
570 DATA "################"
How It Works
Lines 130-170 calculate the proposed position in u and z, same as before. But now the player doesn’t move yet — first come the checks.
Line 175 checks the map boundaries. If the proposed position is outside the 8x16 grid, skip the move.
Line 176 is the wall check. m$(u)(z TO z) reads the character at row u, column z from the map array. If it’s #, that cell is a wall — skip the move. The GO TO 200 jumps past the erase-and-update code, leaving the player where they are.
Lines 180-190 only run if both checks pass. The player erases and redraws at the new position.
Look Before You Move
This is the look-before-you-move pattern. Calculate where you want to go, check whether you can go there, then move only if the path is clear.
The map array makes this trivial. Without it, you’d need to read the screen attributes or maintain a separate collision grid. With the map stored in m$(), a single string index check tells you everything.
String Indexing for Collision
m$(u)(z TO z) is the Spectrum’s way of reading one character from a string. m$(u) is the entire row string. (z TO z) extracts the character at position z. The result is a one-character string that you compare with =.
This is the same string slicing from Word Worm, but here it’s collision detection instead of letter matching.
Try This
Slide along walls. Walk towards a wall at an angle. Notice how the player stops — they can’t slide. Each axis is checked independently because the input only changes one axis at a time.
Open a wall. Change a # to a space in the DATA and run the program. You can now walk through the gap.