🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

A C64 Game - Step 70

posted in New Old Things
Published September 29, 2012
Advertisement

And a new boss. Quite similar to the first actually, but supposed to be a bit more aggressive.

This boss needed a bit of refactoring since a few code parts were reusable from the first boss. First up, the find one player to hunt:

;looks for player
;x = own object index
;returns player index in y
!zone FindPlayer
FindPlayer
          txa
          and #$01
          tay
          lda SPRITE_ACTIVE,y
          cmp #TYPE_PLAYER_DEAN
          beq .FoundPlayer
          cmp #TYPE_PLAYER_SAM
          beq .FoundPlayer

          ;check other player
          tya
          eor #1
          tay
          lda SPRITE_ACTIVE,y
          cmp #TYPE_PLAYER_DEAN
          beq .FoundPlayer
          cmp #TYPE_PLAYER_SAM
          beq .FoundPlayer

          ;no player to hunt
          ldy #2
          rts

.FoundPlayer
          rts


The homing boss movement is put in a sub routine:

BossFollowPlayer
          inc SPRITE_ANIM_DELAY,x
          lda SPRITE_ANIM_DELAY,x
          cmp #10
          beq .DoCheckMove
          jmp .DoGhostMove
          
.DoCheckMove
          lda #0
          sta SPRITE_ANIM_DELAY,x

          jsr FindPlayer
          cmp #2
          bne +

          ;no player to hunt
          rts

+
          ;player index in y
          lda SPRITE_CHAR_POS_X,y
          cmp SPRITE_CHAR_POS_X,x
          bpl .MoveRight

          ;move left
          lda SPRITE_DIRECTION,x
          bne .AlreadyLookingLeft
          lda SPRITE_MOVE_POS,x
          beq .TurnLNow
          dec SPRITE_MOVE_POS,x
          bne .CheckYNow

.TurnLNow;turning now
          lda #1
          sta SPRITE_DIRECTION,x
          jmp .CheckYNow

.AlreadyLookingLeft
          lda SPRITE_MOVE_POS,x
          cmp #BOSS_MOVE_SPEED
          beq .CheckYNow
          inc SPRITE_MOVE_POS,x
          jmp .CheckYNow

.MoveRight
          lda SPRITE_DIRECTION,x
          beq .AlreadyLookingRight

          lda SPRITE_MOVE_POS,x
          beq .TurnRNow
          dec SPRITE_MOVE_POS,x
          bne .CheckYNow

          ;turning now
.TurnRNow
          lda #0
          sta SPRITE_DIRECTION,x
          lda #SPRITE_BOSS_FOOT_R
          sta SPRITE_POINTER_BASE,x
          jmp .CheckYNow

.AlreadyLookingRight
          lda SPRITE_MOVE_POS,x
          cmp #BOSS_MOVE_SPEED
          beq .CheckYNow
          inc SPRITE_MOVE_POS,x
          jmp .CheckYNow

.CheckYNow;player index in y
          lda SPRITE_CHAR_POS_Y,y
          cmp SPRITE_CHAR_POS_Y,x
          bpl .MoveDown

          ;move left
          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,x
          sty PARAM4
          beq .DoY

          lda SPRITE_DIRECTION,x
          beq .DoRight
          
.MoveLoopL
          jsr ObjectMoveLeftBlocking
          dec PARAM4
          bne .MoveLoopL
          jmp .DoY

.DoRight
.MoveLoopR
          jsr ObjectMoveRightBlocking
          dec PARAM4
          bne .MoveLoopR

.DoY;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

And here's the actual boss behaviour. The boss homes in on the player and will directly attack if the player could be hit:


;------------------------------------------------------------
;boss
;------------------------------------------------------------
!zone BehaviourBoss4
BehaviourBoss4
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

          ;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 .NotFollowPlayer

          ;check if on same height as a player
          lda SPRITE_ACTIVE
          cmp #TYPE_PLAYER_DEANbne ++

          lda SPRITE_CHAR_POS_Y
          cmp SPRITE_CHAR_POS_Y,x
          beq .StartAttackMode

++
          lda SPRITE_ACTIVE + 1cmp #TYPE_PLAYER_SAMbne ++
          lda SPRITE_CHAR_POS_Y + 1cmp SPRITE_CHAR_POS_Y,x
          beq .StartAttackMode

++
          ;anim
          lda SPRITE_DIRECTION,x
          beq +
          lda #SPRITE_BOSS_FOOT_L
          jmp ++

+
          lda #SPRITE_BOSS_FOOT_R
++
          sta SPRITE_POINTER_BASE,x

          jmp BossFollowPlayer

.StartAttackMode
          lda #1
          sta SPRITE_STATE,x
          lda #0
          sta SPRITE_MOVE_POS,x
          sta SPRITE_MODE_POS,x
          jmp .AttackMode

.NotFollowPlayercmp #1beq .AttackMode
          rts

.AttackMode;Attack modes (more modes?)
          inc SPRITE_MOVE_POS,x
          lda SPRITE_MOVE_POS,x
          cmp #4beq .NextAttackStep
          rts

.NextAttackStep
          lda SPRITE_CHAR_POS_X,x
          sta PARAM4
          lda SPRITE_CHAR_POS_Y,x
          sta PARAM5

          lda #0
          sta SPRITE_MOVE_POS,x
          inc SPRITE_MODE_POS,x

          lda SPRITE_MODE_POS,x
          cmp #11bcc .BeamNotDangerous
          cmp #29bcs .BeamNotDangerous
;does player hit beam?
          ldy #0
          jsr CheckIsPlayerCollidingWithBeam
          ldy #1
          jsr CheckIsPlayerCollidingWithBeam

.BeamNotDangerous
          lda SPRITE_MODE_POS,x
          cmp #5beq .BeamStep1
          cmp #6beq .BeamStep2
          cmp #7beq .BeamStep3
          cmp #8beq .BeamStep4
          cmp #9beq .BeamStep3
          cmp #10beq .BeamStep4
          cmp #11beq .BeamStep3
          cmp #12beq .BeamEnd
          rts

.HandleBeam
          lda BEAM_CHAR_H,y
          sta PARAM1
          lda BEAM_CHAR_V,y
          sta PARAM2
          lda BEAM_COLOR,y
          sta PARAM3

          jsr DrawBeamH
          jsr DrawBeamV
          rts
          
.BeamStep1;beam
          ldy #BEAM_TYPE_DARK
          jmp .HandleBeam

.BeamStep2;beam
          ldy #BEAM_TYPE_MEDIUM
          jmp .HandleBeam

.BeamStep3;beam
          ldy #BEAM_TYPE_LIGHT
          jmp .HandleBeam

.BeamStep4;beam
          ldy #BEAM_TYPE_LIGHT2
          jmp .HandleBeam

.BeamEnd
          jsr RestoreBeamHV

          lda #0
          sta SPRITE_STATE,x
          rts

Have fun!

step70.zip

Previous Step Next Step


Previous Entry A C64 Game - Step 69
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