A C64 Game - Step 35


And onwards we go. Enemies now get an annoyed state once they got hit. For some enemies annoyance is even increasing. And to top it off, a new jumping spider enemy was added.



Adding the new enemy follows the common pattern we've seen in earlier steps.

Add new constants:

SPRITE_SPIDER_STAND = SPRITE_BASE + 44
SPRITE_SPIDER_WALK_1 = SPRITE_BASE + 45
SPRITE_SPIDER_WALK_2 = SPRITE_BASE + 46

TYPE_SPIDER = 8



Add the behaviour code:

;------------------------------------------------------------
;run left/right, jump off directional
;------------------------------------------------------------
!zone BehaviourSpider
BehaviourSpider
;animate spider
inc SPRITE_ANIM_DELAY,x
lda SPRITE_ANIM_DELAY,x
cmp #2
bne .NoAnimUpdate

lda #0
sta SPRITE_ANIM_DELAY,x
inc SPRITE_ANIM_POS,x
lda SPRITE_ANIM_POS,x
and #$3
sta SPRITE_ANIM_POS,x
tay
lda SPIDER_ANIMATION_TABLE,y
sta SPRITE_POINTER_BASE,x

.NoAnimUpdate
lda SPRITE_JUMP_POS,x
bne .NoFallHandling
jsr UpdateSpriteFall
sta SPRITE_FALLING,x

.NoFallHandling
lda #3
sta PARAM6

.MoveStep
dec PARAM6
beq .MoveDone
lda SPRITE_DIRECTION,x
beq .MoveRight

;move left
lda SPRITE_JUMP_POS,x
ora SPRITE_FALLING,x
bne .OnlyMoveLeft

jsr ObjectWalkOrJumpLeft
beq .ToggleDirection
jmp .MoveStep

.MoveDone
lda SPRITE_JUMP_POS,x
beq .NotJumping
jsr UpdateSpriteJump

.NotJumping
rts

.OnlyMoveLeft
jsr ObjectMoveLeftBlocking
beq .ToggleDirection
jmp .MoveStep

.MoveRight
lda SPRITE_JUMP_POS,x
ora SPRITE_FALLING,x
bne .OnlyMoveRight

jsr ObjectWalkOrJumpRight
beq .ToggleDirection
jmp .MoveStep

.OnlyMoveRight
jsr ObjectMoveRightBlocking
beq .ToggleDirection
jmp .MoveStep

.ToggleDirection
lda SPRITE_DIRECTION,x
eor #1
sta SPRITE_DIRECTION,x
jmp .MoveStep



The behaviour of this spider enemy: Walk. If a gap below is encountered, jump. If the way is blocked, turn. This behaviour is put in a general subroutine, since it might come in handy for other enemies later (and it will):

;------------------------------------------------------------
;walk object left if could fall off jump if blocked turn
;x = object index
;------------------------------------------------------------
!zone ObjectWalkOrJumpLeft
ObjectWalkOrJumpLeft
lda SPRITE_CHAR_POS_X_DELTA,x
beq .CheckCanMoveLeft

.CanMoveLeft
dec SPRITE_CHAR_POS_X_DELTA,x
jsr MoveSpriteLeft
lda #1
rts

.CheckCanMoveLeft
jsr CanWalkOrJumpLeft
beq .Blocked
cmp #1
beq .WalkLeft

;jump
lda SPRITE_JUMP_POS,x
bne .WalkLeft

lda #1
sta SPRITE_JUMP_POS,x

.WalkLeft
lda #8
sta SPRITE_CHAR_POS_X_DELTA,x
dec SPRITE_CHAR_POS_X,x
jmp .CanMoveLeft

.Blocked
rts

;------------------------------------------------------------
;checks if an object can walk or jump left (jump if would fall off)
;x = object index
;returns 0 if blocked
;returns 1 if possible
;returns 2 if jump required (not blocked, but in front of hole)
;------------------------------------------------------------
!zone CanWalkOrJumpLeft
CanWalkOrJumpLeft
ldy SPRITE_CHAR_POS_Y,x
dey
lda SCREEN_LINE_OFFSET_TABLE_LO,y
sta ZEROPAGE_POINTER_1
lda SCREEN_BACK_LINE_OFFSET_TABLE_HI,y
sta ZEROPAGE_POINTER_1 + 1
ldy SPRITE_CHAR_POS_X,x
dey
lda (ZEROPAGE_POINTER_1),y
jsr IsCharBlocking
bne .BlockedLeft
tya
clc
adc #40
tay
lda (ZEROPAGE_POINTER_1),y
jsr IsCharBlocking
bne .BlockedLeft

;is a hole in front
ldy SPRITE_CHAR_POS_Y,x
lda SCREEN_LINE_OFFSET_TABLE_LO,y
sta ZEROPAGE_POINTER_1
lda SCREEN_BACK_LINE_OFFSET_TABLE_HI,y
sta ZEROPAGE_POINTER_1 + 1
lda SPRITE_CHAR_POS_X,x
clc
adc #39
tay
lda (ZEROPAGE_POINTER_1),y
jsr IsCharBlockingFall
bne .NoHole

lda #2
rts

.NoHole
lda #1
rts

.BlockedLeft
lda #0
rts



To get and show annoyed behaviour a new state array SPRITE_ANNOYED is created. Enemies are supposed to change color to see once they get angry. For this we add a new color table:

TYPE_ANNOYED_COLOR
!byte 0 ;dummy
!byte 10 ;player
!byte 2 ;bat diagonal
!byte 2 ;bat up down
!byte 4 ;bat 8
!byte 2 ;mummy
!byte 13 ;zombie
!byte 2 ;bat vanish
!byte 2 ;spider



Add a little change to the common HitBehaviourHurt routine to increase the annoyance state:

!zone HitBehaviourHurt
HitBehaviourHurt
inc SPRITE_ANNOYED,x
ldy SPRITE_ACTIVE,x
lda TYPE_ANNOYED_COLOR,y
sta VIC_SPRITE_COLOR,x
rts



Voila! In a later step we'll add some enemies that change behaviour once they get angry.


step35.zip