Tagalong Todd Tutorial: Part 5
Contents
Tagalong Todd Tutorial: Part 5
In this part of the tutorial, we'll add code that will cause Todd to chase the player around the screen - and we'll be done!
The complete source for this tutorial is here. It's actually the same file that comes with the SDK.
A new value and some storage
Since our idea for moving characters on the screen (as developed in part 4) involves a velocity, we'll do the same for Todd. We'll have Todd move at a constant speed rather than speeding up to a set speed like we're doing for the player. To make things simple, we'll just define that speed using a constant.
TODD_VEL EQU $AA
Once that is in place, we need to add a little storage for Todd's velocity calculations.
TODD PROC ; TODD's STATS @@XP RMB 1 ; X position @@YP RMB 1 ; Y position @@XV RMB 1 ; X velocity @@YV RMB 1 ; Y velocity @@TXV RMB 1 ; Target X velocity @@TYV RMB 1 ; Target Y velocity ENDP
We have already defined the X and Y position variables for Todd in the last part of the tutorial. Here we're adding storage for the velocities just like we did for the player.
;; ------------------------------------------------------------ ;; ;; Set up Todd's AI. ;; ;; ------------------------------------------------------------ ;; CALL STARTTASK DECLE 0 DECLE TODDTASK DECLE 60, 60 ; 2Hz (twice a second) MVII #1, R0 MVO R0, TSKACT
To have Todd move around, we're going to define a routine that should get called every so often via the TASKQ library. This will be defined very similarly to how we programmatically moved the player around in the second part of this tutorial when we were using a timed TASKQ task. For more detail on these definitions, you can reread that section of part 2. The only things different here is that we are defining TODDTASK which will be the routine that will calculate Todd's new velocity variables. And we'll set things up so that it gets called twice a second. The actual moving of Todd around the screen will be handed by changes to MOB_UPDATE.
TODDTASK: making Todd chase the player
Now we just need to write some code that will allow Todd to chase the player around the screen.
The "chasing" algorithm will be pretty simple: just pick a direction for the next bit of movement based on Todd's and the player's positions relative to each other.
;; ======================================================================== ;; ;; TODDTASK -- Todd wants to find you! ;; ;; ======================================================================== ;; TODDTASK PROC ;; ------------------------------------------------------------ ;; ;; This is really simple: Todd will pick one of 8 directions ;; ;; to walk in to try to move towards you. He picks this only ;; ;; based on whether you're left/right or above/below him. ;; ;; ------------------------------------------------------------ ;; CLRR R0 ; set X vel to 0 CLRR R1 ; set Y vel to 0
We'll compute Todd's X and Y velocities in R0 and R1, respectively. To start out, we'll set both of these to zero.
MVI PLYR.XP, R2 MVI TODD.XP, R3
Next, we'll need to compare Todd's X position with the player's to see if Todd should be heading left or right to chase the player. We'll move those values into R2 and R3.
SLR R2, 2 SLR R3, 2 CMPR R3, R2 BEQ @@xp0 ; Equal? X-vel stays 0 MVII #TODD_VEL, R0 ; Player > Todd? Move right BGT @@xp0 ; Player < Todd? Move left NEGR R0
This just compares the two positions and sets Todd's X velocity (R0) to either zero (if Todd and the player are at the same X coordinate), TODD_VEL (if Todd is to the left of the player) or -TODD_VEL (if Todd is to the right of the player). You can see the MVII instruction putting our TODD_VEL value into R0 and then the NEGR makes it negative if required. The two SLR shifts that are done before the comparison are creating a little dead zone in the number comparison (4 units out of 256) that will show up as equal. This allows numbers that are close to be seen as equal - we don't really want the game to believe that Todd and the player have to line up on the same exact pixels.
@@xp0 SUBR R3, R2 ;\ BPL @@dx_pos ; | NEGR R2 ; |__ If X coords are close enough @@dx_pos CMPI #2, R2 ; | anyway, force target Xvel to 0 BGE @@xp_ok ; | CLRR R0 ;/
This chunk of code is testing to see if the player and Todd are within 2 screen units (keeping the above discussion of the little dead zone in mind) of each other in the X direction. If they are, then we force the X velocity to be zero. First it subtracts the player's and Todd's X positions and then makes sure that the result is positive using the Branch on PLus operation to jump around the NEGR operation. CMPI compares the (now guaranteed positive) result to the number 2 and sets R0 to zero if the value is not greater. BGE jumps around the CLRR if the comparison shows the value to be greater than 2.
@@xp_ok MVI PLYR.YP, R2 MVI TODD.YP, R3 SLR R2, 2 SLR R3, 2 CMPR R3, R2 BEQ @@yp0 ; Equal? X-vel stays 0 MVII #TODD_VEL, R1 ; Player > Todd? Move right BGT @@yp0 ; Player < Todd? Move left NEGR R1 @@yp0 SUBR R3, R2 ;\ BPL @@dy_pos ; | NEGR R2 ; |__ If Y coords are close enough @@dy_pos CMPI #2, R2 ; | anyway, force target Yvel to 0 BGE @@yp_ok ; | CLRR R1 ;/
And all of this is identical for the Y position and velocity.
@@yp_ok MVO R0, TODD.TXV ; Set Todd's target X velocity MVO R1, TODD.TYV ; Set Todd's target Y velocity
Now that we have the values we need, we store them into our TODD data structure so that the MOB_UPDATE routine will have easy access to them.
JR R5 ; Leave ENDP
Exit as per normal.
Updates to MOB_UPDATE
We need to add some code to make sure Todd moves around during MOB_UPDATE.
MVI TODD.TXV, R0 SUB TODD.XV, R0 SARC R0, 2 ADD TODD.XV, R0 MVO R0, TODD.XV ADD TODD.XP, R0 MVO R0, TODD.XP
This code is pretty similar to what we've done for the player. It subtracts our computed target velocity from Todd's actual velocity (in the X direction), does 2 SARC shifts on it to get a 1/4 effect, then adds that result to Todd's X velocity, and then adds the calculated velocity to the actual X position.
MVI TODD.TYV, R0 SUB TODD.YV, R0 SARC R0, 2 ADD TODD.YV, R0 MVO R0, TODD.YV ADD TODD.YP, R0 MVO R0, TODD.YP
And a nearly identical chunk of code for the Y velocity and position.
That's it!
Assemble and run it. We've gone through and built the very simplistic Tagalong Todd game from the ground up!