• entries
    104
  • comments
    101
  • views
    255312

A C64 Game - Step 74

Sign in to follow this  
Endurion

1398 views

Another boss!

And one, that works differently than the others before him.

step74.png

This boss is spawning bats that fly left/right and vanish once hitting the screen border.
Thus we remove the path-8-flying bat and replace it by a simple attacking bat:

!zone BehaviourBatAttacking
BehaviourBatAttacking
          lda DELAYED_GENERIC_COUNTER
          and #$03
          bne .NoAnimUpdate

          inc SPRITE_ANIM_POS,x
          lda SPRITE_ANIM_POS,x
          and #$03
          sta SPRITE_ANIM_POS,x

          tay
          lda BAT_ANIMATION,y
          sta SPRITE_POINTER_BASE,x

.NoAnimUpdate
          lda #3
          sta PARAM1
          lda SPRITE_DIRECTION,x
          beq .MoveRight
          
.MoveLeft
          jsr ObjectMoveLeft
          dec PARAM1
          bne .MoveLeft
          jmp .XMoveDone

.MoveRight
          jsr ObjectMoveRight
          dec PARAM1
          bne .MoveRight

.XMoveDone
          lda SPRITE_CHAR_POS_X,x
          cmp #255
          beq .RemoveMe
          cmp #39
          beq .RemoveMe
          rts

.RemoveMe
          inc SPAWN_NO_ITEM
          jsr KillEnemy
          dec SPAWN_NO_ITEM
          rts


The boss itself is not really clever. It calculates a random y position, moves there, spawns bats and starts all over again. Note that it is only vulnerable while spawning bats though :)
Remember, vulnerability is controlled by having the MSB set in SPRITE_STATE,x.

;------------------------------------------------------------
;boss #5
;state 0 = find target Y
;state 1 = move towards target Y
;state 2 = attack
;state 3 = cool off
;------------------------------------------------------------
!zone BehaviourBoss5
BehaviourBoss5
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 #0
          bne .NoHitBack
          lda #1
          sta VIC_SPRITE_COLOR,x
          ;make vulnerable again
          lda SPRITE_STATE,x
          cmp #128
          bne .NoHitBack

          lda #0
          sta SPRITE_STATE,x

.NoHitBack
          lda DELAYED_GENERIC_COUNTER
          and #$03
          bne .NoAnimUpdate

.NoAnimUpdate
          lda SPRITE_STATE,x
          bne +
          jmp .FindTargetY
          
+
          cmp #1
          beq .MoveTowardsTarget
          cmp #2
          beq .Attack
          cmp #3
          beq .CoolOff

          lda #0
          sta SPRITE_STATE,x
          rts

.CoolOff
          inc SPRITE_MODE_POS,x
          lda SPRITE_MODE_POS,x
          cmp #30
          bne +

          lda #0
          sta SPRITE_STATE,x

+
          rts

.Attack
          inc SPRITE_MOVE_POS,x
          lda SPRITE_MOVE_POS,x
          and #$1f
          cmp #$1f
          beq +
          rts

+
          ;free bats
          inc SPRITE_MODE_POS,x
          lda SPRITE_MODE_POS,x
          cmp #5
          bne +

          inc 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
          inc SPRITE_STATE,x
          lda #0
          sta SPRITE_MODE_POS,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_SPEED
          beq .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_SPEED
          beq .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


For the boss routine we require a little utility function which returns a ranged random number. No division or module means manual work: create random number, subtract range until it's small enough, then add the lower range.

;lower end = PARAM5
;higher end = PARAM6
GenerateRangedRandom
          lda PARAM6
          sec
          sbc PARAM5
          clc
          adc #1
          sta PARAM6
          jsr GenerateRandomNumber
          
.CheckValue
          cmp PARAM6
          bcc .ValueOk

          ;too high
          sec
          sbc PARAM6
          jmp .CheckValue
          
.ValueOk
          clc
          adc PARAM5
          rts


Have fun!

step74.zip

Previous Step Next Step

 
Sign in to follow this  


0 Comments


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now