A C64 Game - Step 74

posted in New Old Things
Published October 27, 2012
Advertisement

Another boss!

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



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 #$03bne .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 #255beq .RemoveMe
          cmp #39beq .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 #0bne .NoHitBack
          lda #1
          sta VIC_SPRITE_COLOR,x
          ;make vulnerable again
          lda SPRITE_STATE,x
          cmp #128bne .NoHitBack

          lda #0
          sta SPRITE_STATE,x

.NoHitBack
          lda DELAYED_GENERIC_COUNTER
          and #$03bne .NoAnimUpdate

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

          lda #0
          sta SPRITE_STATE,x
          rts

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

          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 #5bne +

          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_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

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
          clcadc #1
          sta PARAM6
          jsr GenerateRandomNumber
          
.CheckValuecmp PARAM6
          bcc .ValueOk

          ;too high
          sec
          sbc PARAM6
          jmp .CheckValue
          
.ValueOkclcadc PARAM5
          rts

Have fun!

step74.zip

Previous Step Next Step


Previous Entry A C64 Game - Step 73
0 likes 0 comments

Comments

Nobody has left a comment. You can be the first!
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement