A C64 Game - Step 27

posted in New Old Things
Published October 15, 2011
Advertisement

Actually a rather simple step, but with a few new changes.

We're adding a new enemy, a bat, that once shot, hides. And randomly reappears to attack you, only to vanish again.



The first problem:

The bat vanishes. However not the object. To tackle that an empty sprite was added to the sheet. This makes the object stay but the image gone. However collision still checks the bat.

Since we have a SPRITE_STATE per object anyway a new design decision get added. Any states >= 128 are treated as non colliding. In other words, bat gets hit, set state to a value >= 128 and set empty sprite. Done. To reappear, repeat reverse.


Let's start with the simpler getting hit part. Set invisible sprite, set sprite state to 128. Voila!

!zone HitBehaviourVanish
HitBehaviourVanish
          lda SPRITE_STATE,x
          bne .NoHit
          lda #SPRITE_BAT_VANISH
          sta SPRITE_POINTER_BASE,x
          lda #128
          sta SPRITE_STATE,x
.NoHit
          rts


The behaviour code is at first quite similar to the left/right moving bat. The neat part is the attack flight. The bat appears in any location diagonal from the player. It then swoops toward the player to the opposite side and vanishes again.

A few cautions are taken to avoid trying to appear or move outside the screen. The bat may actually take V shaped route.


 

!zone BehaviourBatVanishing
BehaviourBatVanishing
          lda SPRITE_STATE,x
          bne .NotNormal
          jmp .NormalUpdate

.NotNormalcmp #128
          beq .Vanish1
          cmp #129
          beq .Hidden
          cmp #130
          beq .Spawn
          cmp #1
          bne .NoSpecialBehaviour

          jmp .AttackFlight

.NoSpecialBehaviour
          rts

.Vanish1
          lda DELAYED_GENERIC_COUNTER
          and #$7
          bne .NoSpecialBehaviour
          lda #SPRITE_INVISIBLE
          sta SPRITE_POINTER_BASE,x
          inc SPRITE_STATE,x
          jsr GenerateRandomNumber
          adc #24
          sta SPRITE_MOVE_POS,x
          rts

.Spawn
          lda DELAYED_GENERIC_COUNTER
          and #$7
          bne .NoSpecialBehaviour

          lda #1
          sta SPRITE_STATE,x
          lda #SPRITE_BAT_1
          sta SPRITE_POINTER_BASE,x
          rts

.Hiddendec SPRITE_MOVE_POS,x
          beq .Unhide
          rts

.Unhide;position diagonal above/below player
          lda SPRITE_CHAR_POS_X
          cmp #10
          bcc .SpawnOnRight
          cmp #30
          bcs .SpawnOnLeft

          ;randomly choose
          jsr GenerateRandomNumber
          and #$1
          beq .SpawnOnRight

.SpawnOnLeft
          lda SPRITE_CHAR_POS_X
          sec
          sbc #5
          sta PARAM1
          lda #0
          sta SPRITE_DIRECTION,x
          jmp .FindYSpawnPos

.SpawnOnRight
          lda SPRITE_CHAR_POS_X
          clcadc #5
          sta PARAM1
          lda #1
          sta SPRITE_DIRECTION,x

.FindYSpawnPos
          lda SPRITE_CHAR_POS_Y
          cmp #5
          bcc .SpawnBelow
          cmp #15
          bcs .SpawnAbove

          ;randomly choose
          jsr GenerateRandomNumber
          and #$1
          beq .SpawnAbove

.SpawnBelow
          lda SPRITE_CHAR_POS_Y
          clcadc #5
          sta PARAM2
          lda #0
          sta SPRITE_FALLING,x
          jmp .Reposition

.SpawnAbove
          lda SPRITE_CHAR_POS_Y
          sec
          sbc #5
          sta PARAM2
          lda #1
          sta SPRITE_FALLING,x

.Reposition
          jsr CalcSpritePosFromCharPos
          inc SPRITE_STATE,x
          lda #SPRITE_BAT_VANISH
          sta SPRITE_POINTER_BASE,x
          rts

.NormalUpdate
          lda DELAYED_GENERIC_COUNTER
          and #$3
          bne .NoAnimUpdate
          inc SPRITE_ANIM_POS,x
          lda SPRITE_ANIM_POS,x
          and #$3
          sta SPRITE_ANIM_POS,x
          tay
          lda BAT_ANIMATION,y
          sta SPRITE_POINTER_BASE,x

.NoAnimUpdate
          lda SPRITE_STATE,x
          bne .NoAction
          lda SPRITE_DIRECTION,x
          beq .MoveRight

          ;move left
          jsr ObjectMoveLeftBlocking
          beq .ToggleDirection
          rts

.MoveRight
          jsr ObjectMoveRightBlocking
          beq .ToggleDirection
          rts

.ToggleDirection
          lda SPRITE_DIRECTION,x
          eor #1
          sta SPRITE_DIRECTION,x
          
.NoAction
          rts

.AttackFlightinc SPRITE_MOVE_POS,x
          lda SPRITE_MOVE_POS,x
          cmp #80
          beq .AttackDone
          cmp #40
          beq .ChangeFlyDirection

          ;fly towards player
          lda SPRITE_DIRECTION,x
          beq .FlyRight
          stx PARAM5
          jsr ObjectMoveLeft
          jmp .FlyUpDown

.FlyRight
          stx PARAM5
          jsr ObjectMoveRight

.FlyUpDown
          ldx PARAM5
          lda SPRITE_FALLING,x
          beq .FlyUp
          jsr ObjectMoveDown
          rts

.FlyUp
          jsr ObjectMoveUp
          rts

.ChangeFlyDirection;change direction to avoid flying out of the screen
          lda SPRITE_CHAR_POS_Y,x
          cmp #5
          bcc .ChangeY
          cmp #18
          bcc .CheckXDir

.ChangeY
          lda SPRITE_FALLING,x
          eor #$1
          sta SPRITE_FALLING,x

.CheckXDir
          lda SPRITE_CHAR_POS_X,x
          cmp #5
          bcc .ChangeX
          cmp #32
          bcs .ChangeX
          rts

.ChangeX
          lda SPRITE_DIRECTION,x
          eor #$1
          sta SPRITE_DIRECTION,x
          rts

.AttackDone;auto-vanish
          lda #0
          sta SPRITE_STATE,x
          jmp HitBehaviourVanish

step27.zip

Previous Step Next Step

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