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
 call FUNC_GETDFILE_ADDRESS
 ld (hl), 137 

; 60 PRINT AT A,B;” + “ 
 ld a, (VARIABLE_A)
 ld d, a
 ld a, (VARIABLE_B)
 ld e, a
 call FUNC_GETDFILE_ADDRESS
 ld (hl), __
 inc hl
 ld (hl), _ADD
 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
 call FUNC_GETDFILE_ADDRESS
 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
 call FUNC_GETDFILE_ADDRESS
 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
 add a, (hl)
 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!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s