This actually began on Christmas Day (who else was coding then??!) when I finally got round to noting down the locations in hex of the enemy sprites in the sprite bank. This was done using good old fashioned pen and paper while sat in my comfy reclining chair, sipping a nice red Tempranillo! Here's what my scrappy notes looked like:
Once these hex locations were noted, I got to thinking what information was needed to set up, display and move an enemy sprite. Obviously, a sprite 'x' and 'y' screen location was needed, but I also need to know colours, the default (start) sprite definition, animation start/end definitions, sprite direction and speed and finally the maximum and minimum screen locations travelled to by the sprite enemy. To keep things simple, sprites in this game move in straight line paths for now! The set-up table for level 1 ended up looking like this...
l1_sprite_x !byte $19,$20,$4c,$94,$90,$6f,$5a,$0d
l1_sprite_y !byte $cd,$9e,$4f,$a4,$cd,$a8,$54,$85
l1_sprite_col !byte $0a,$07,$0c,$05,$0c,$0c,$0c,$0c
l1_sprite_def !byte $ab,$bf,$ee,$ec,$cf,$c7,$d3,$e8
l1_sprite_anims !byte $ab,$bf,$ee,$ec,$cf,$c7,$d3,$e8
l1_sprite_anime !byte $ac,$c0,$f0,$ee,$d3,$cb,$d7,$eb
l1_sprite_dir !byte $00,$00,$00,$01,$01,$01,$00,$00
l1_sprite_spd !byte $00,$00,$01,$02,$01,$01,$01,$01
l1_sprite_min !byte $00,$00,$53,$53,$19,$5a,$5a,$0d
l1_sprite_max !byte $00,$00,$b8,$a7,$90,$85,$85,$3a
At first, I was going to have a separate bit of code to handle each enemy, but once I realised that the enemies only move up/down or left/right, I realised I could handle the sprites in a single loop; well two loops actually, one handling vertical movement and the other horizontal. This could be rationalised further into one loop by having another table setting whether each enemy is vertical or horizontal moving, but since the code would be roughly the same, with skips in the loop to handle vertical/horizontal, I decided to keep it simple and have two loops - hopefully this will be easier to read and remember for the future.
I did need to create some more tables holding the sprite animation definitions for each enemy when moving left or right, but I was now ready for some code. It ended up looking a little like this (note, this is for the horizontally moving enemies only):
; now deal with the horizontal moving enemies
; zombie, ghost, bat, witch (sprites 4 - 7)
enemy_hori_check
lda sprite_dir,x
cmp #$01
beq enemy_hori1
lda sprite_x,x
clc
adc sprite_spd,x
sta sprite_x,x
cmp sprite_max,x
bcc next_hori_enemy
lda #$01
sta sprite_dir,x
lda left_enm_def,x
sta sprite_def,x
sta sprite_anims,x
lda left_enm_anime,x
sta sprite_anime,x
jmp next_hori_enemy
enemy_hori1
lda sprite_x,x
sec
sbc sprite_spd,x
sta sprite_x,x
cmp sprite_min,x
bcs next_hori_enemy
lda #$00
sta sprite_dir,x
lda rite_enm_def,x
sta sprite_def,x
sta sprite_anims,x
lda rite_enm_anime,x
sta sprite_anime,x
next_hori_enemy
inx
cpx #$08
bne enemy_hori_check
Basically all that's happening is the code first checks which direction the sprite should be moving (in my game '0' means down or right and '1' means up or left) and then adds or subtracts from the sprites 'x' position on the screen. The addition or subtraction can be altered, thus altering the 'speed' of the sprite, by changing the values in the 'speed_spd' table, which the code references in the loop.
Also referenced is each enemies 'max' and 'min' values which determines the end point of the movement path on screen. Once the max or min is reached, the code switches the 'sprite_dir' so the sprite moves the other way, along with the animation definitions for that direction.
The code for vertical movement is almost identical, save for the sprites 'y' screen value is altered instead.
Once this code is called in the game and the set-up table for level 1 referenced, the enemies ended up doing this (and believe it or not it worked first time!):
I'd call that a successful couple of days and a Merry Christmas indeed!
Next diary entry...

