And another boss. This one is different, as it spawns bats to the left and right. And is only vulnerable during that part
The boss routine is a bit bigger this time. The attacking bat code is already there, so nothing to add on that part.
As behaviours got increasingly complex I started to write the state values on top of the routines. Remember, any states with MSB set (>=128) mark the object as invincible.
;------------------------------------------------------------ ;boss #5 ;state 128 = find target Y ;state 129 = move towards target Y ;state 0 = attack ;state 130 = cool off ;------------------------------------------------------------ !zone BehaviourBoss6 BehaviourBoss6 BOSS_MOVE_SPEED = 1 lda SPRITE_HITBACK,x beq .NoHitBack dec SPRITE_HITBACK,x ldy SPRITE_HITBACK,x lda BOSS_FLASH_TABLE,y sta VIC_SPRITE_COLOR,x cpy #0bne .NoHitBack lda #1 sta VIC_SPRITE_COLOR,x ;keep invulnerable .NoHitBack lda DELAYED_GENERIC_COUNTER and #$03bne .NoAnimUpdate .NoAnimUpdate lda SPRITE_STATE,x beq .Attack cmp #128bne + jmp .FindTargetY + cmp #129beq .MoveTowardsTarget cmp #130beq .CoolOff lda #0 sta SPRITE_STATE,x rts .CoolOffinc SPRITE_MODE_POS,x lda SPRITE_MODE_POS,x cmp #30bne + lda #128 sta SPRITE_STATE,x + rts .Attackinc SPRITE_MOVE_POS,x lda SPRITE_MOVE_POS,x and #$1fcmp #$1f beq + rts + ;free batsinc SPRITE_MODE_POS,x lda SPRITE_MODE_POS,x cmp #5bne + lda #130 sta SPRITE_STATE,x lda #0 sta SPRITE_MODE_POS,x rts + lda SPRITE_CHAR_POS_X,x sta PARAM1 lda SPRITE_CHAR_POS_Y,x sta PARAM2 inc PARAM2 stx PARAM10 jsr FindEmptySpriteSlot beq ++ lda #TYPE_BAT_ATTACKING sta PARAM3 jsr SpawnObject lda #0 sta SPRITE_DIRECTION,x jsr FindEmptySpriteSlot beq ++ jsr SpawnObject lda #1 sta SPRITE_DIRECTION,x ++ ldx PARAM10 rts .MoveTowardsTarget;player index in y lda SPRITE_VALUE,x cmp SPRITE_CHAR_POS_Y,x bne + ;arrived at target Y lda #0 sta SPRITE_MODE_POS,x sta SPRITE_STATE,x rts + bpl .MoveDown ;move up? lda SPRITE_DIRECTION_Y,x bne .AlreadyLookingUp lda SPRITE_MOVE_POS_Y,x beq .TurnUNow dec SPRITE_MOVE_POS_Y,x bne .DoGhostMove .TurnUNow;turning now lda #1 sta SPRITE_DIRECTION_Y,x jmp .DoGhostMove .AlreadyLookingUp lda SPRITE_MOVE_POS_Y,x cmp #BOSS_MOVE_SPEEDbeq .DoGhostMove inc SPRITE_MOVE_POS_Y,x jmp .DoGhostMove .MoveDown lda SPRITE_DIRECTION_Y,x beq .AlreadyLookingDown lda SPRITE_MOVE_POS_Y,x beq .TurnDNow dec SPRITE_MOVE_POS_Y,x bne .DoGhostMove ;turning now .TurnDNow lda #0 sta SPRITE_DIRECTION_Y,x jmp .DoGhostMove .AlreadyLookingDown lda SPRITE_MOVE_POS_Y,x cmp #BOSS_MOVE_SPEEDbeq .DoGhostMove inc SPRITE_MOVE_POS_Y,x jmp .DoGhostMove .DoGhostMove;move X times ldy SPRITE_MOVE_POS_Y,x sty PARAM4 beq .MoveDone lda SPRITE_DIRECTION_Y,x beq .DoDown .MoveLoopU jsr ObjectMoveUpBlocking dec PARAM4 bne .MoveLoopU jmp .MoveDone .DoDown .MoveLoopD jsr ObjectMoveDownBlockingNoPlatform dec PARAM4 bne .MoveLoopD .MoveDone rts .FindTargetY lda #4 sta PARAM5 lda #18 sta PARAM6 jsr GenerateRangedRandom sta SPRITE_VALUE,x inc SPRITE_STATE,x rts
Have fun!
step77.zip (currently broken)