• Advertisement
  • entries
    104
  • comments
    101
  • views
    258222

A C64 Game - Step 74

Sign in to follow this  

1463 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

  • Advertisement