# Rear Gunner XL – Part 4 – Movement

So far we’ve setup the variables we need, and drawn our sights and the enemy into the screen.  We still can’t really play the game though, as we need to have some way of moving around,  This is handled in lines 90 to 140:

```; 90 IF INKEY\$=“5” THEN LET B=B-1
; 100 IF INKEY\$=“8” THEN LET B=B+1
; 110 IF INKEY\$=“7” THEN LET A=A-1
; 120 IF INKEY\$=“6” THEN LET A=A+1
; 130 IF INKEY\$=“0” THEN GOTO 150
; 140 GOTO 50```

So here we are reading the four cursor keys, and moving the player accordingly by altering the values in our A & B variables.  We also check for zero – the ‘fire’ button – being pressed, and finally loop back to the drawing routine.  It’s this final GOTO which completes the game loop.

It’s probably best now to read-up on the post I made about reading the ZX Spectrum keyboard – HERE – as the code we’ll use is nearly identical.

Read it?  Good.  The ZX81 keyboard system is very similar to the Spectrum, with the same method being used to read it, the same port (254 / \$FE), and nearly identical IDs:

```ID \$F7 - 1, 2, 3, 4, 5
ID \$EF - 0, 9, 8, 7, 6
ID \$FB - Q, W, E, R, T
ID \$DF - P, O, I, U, Y
ID \$FD - A, S, D, F, G
ID \$BF - <ENTER>, L, K, J, H
ID \$FE - <SHIFT>, Z, X, C, V
ID \$7F - <SPACE>, ., M, N, B```

So, line 90 tests to see if the ‘5’ key is held, and if so, decreases the contents of the VARIABLE_B:

``` ld a, \$F7
in a, (\$FE)
bit 4, a
jp nz, LINE_90_KEYNOTHELD
ld hl, VARIABLE_B
dec (hl)
LINE_90_KEYNOTHELD:```

And very similar code is used for the next three lines which handle the other three directions.  Line 130 is slightly different, as that jumps to line 150 if ‘0’ is held, so that just needs a label adding for that, and the appropriate jump operation.

Finally, for line 140, we just need to go back to line 50 – so we’ll add a label for that line, and jump to it.

```; 5 PAUSE 50
LINE_5:
ld hl, 50
call FUNC_WAITFORFRAMES

; 10 LET A=5
ld a, 5
ld (VARIABLE_A), a

; 20 LET B=7
ld a, 7
ld (VARIABLE_B), a

; 30 LET C=INT (RND*26)
ld b, 26
call FUNC_GETRANDOM_RANGE
ld (VARIABLE_C), a

; 40 LET D=INT (RND*17)
ld b, 17
call FUNC_GETRANDOM_RANGE
ld (VARIABLE_D), a

; 50 PRINT AT D,C;”(graphic G)”
LINE_50:
ld a, (VARIABLE_D)
ld d, a
ld a, (VARIABLE_C)
ld e, a
ld (hl), 137

; 60 PRINT AT A,B;” + “
ld a, (VARIABLE_A)
ld d, a
ld a, (VARIABLE_B)
ld e, a
ld (hl), __
inc hl
inc hl
ld (hl), __

; 70 PRINT AT A-1,B;”   “
ld a, (VARIABLE_A)
dec a
ld d, a
ld a, (VARIABLE_B)
ld e, a
ld (hl), __
inc hl
ld (hl), __
inc hl
ld (hl), __

; 80 PRINT AT A+1,B;”   “
ld a, (VARIABLE_A)
inc a
ld d, a
ld a, (VARIABLE_B)
ld e, a
ld (hl), __
inc hl
ld (hl), __
inc hl
ld (hl), __

; 90 IF INKEY\$=“5” THEN LET B=B-1
ld a, \$F7
in a, (\$FE)
bit 4, a
jp nz, LINE_90_KEYNOTHELD
ld hl, VARIABLE_B
dec (hl)
LINE_90_KEYNOTHELD:

; 100 IF INKEY\$=“8” THEN LET B=B+1
ld a, \$EF
in a, (\$FE)
bit 2, a
jp nz, LINE_100_KEYNOTHELD
ld hl, VARIABLE_B
inc (hl)
LINE_100_KEYNOTHELD:

; 110 IF INKEY\$=“7” THEN LET A=A-1
ld a, \$EF
in a, (\$FE)
bit 3, a
jp nz, LINE_110_KEYNOTHELD
ld hl, VARIABLE_A
dec (hl)
LINE_110_KEYNOTHELD:

; 120 IF INKEY\$=“6” THEN LET A=A+1
ld a, \$EF
in a, (\$FE)
bit 4, a
jp nz, LINE_120_KEYNOTHELD
ld hl, VARIABLE_A
inc (hl)
LINE_120_KEYNOTHELD:

; 130 IF INKEY\$=“0” THEN GOTO 150
ld a, \$EF
in a, (\$FE)
bit 0, a
jp z, LINE_150:

; 140 GOTO 50
jp LINE_50

; 150 IF D<>A THEN GOTO 50
; 160 IF C=B THEN GOTO 170
; 170 PRINT AT D-1,C;”(graphic Y;SPACE;graphic T)”
; 180 PRINT AT D,C;”(SPACE;inverse SPACE;SPACE)”
; 190 PRINT AT D+1,C;”(graphic T;SPACE;graphic Y)”
; 200 RUN

; Wait for HL frames
FUNC_WAITFORFRAMES
; Load the system variable FRAMES with the number to wait for
; Remember to keep bit 15 high though
set 7, h
ld (FRAMES), hl
FUNC_WAITFORFRAMES_LOOP
; Read the current value
ld hl, (FRAMES)
; Keep looping until it's zero (ignoring bit 15)
ld a, h
and %01111111
or l
jp nz, FUNC_WAITFORFRAMES_LOOP
; Return
ret

; Get a random 8-bit number
FUNC_GETRANDOM
; Calculate a new 'random' number from the last one and r-register
ld a, r
ld hl, LMATH_GR_SEED
rrca
ld (hl), a
ret
LMATH_GR_SEED
defb 91

; Get a random 8-bit number within a range
; Call with B as the maximum value + 1
FUNC_GETRANDOM_RANGE
call FUNC_GETRANDOM
FUNC_GETRANDOM_RANGE_LOOP:
cp b
ret c
sub b
jp FUNC_GETRANDOM_RANGE_LOOP

VARIABLE_A
defb 0
VARIABLE_B
defb 0
VARIABLE_C
defb 0
VARIABLE_D
defb 0```

So we now have a game loop – the player & enemy are drawn, and you can move the player around. Yay!