• entries
    104
  • comments
    101
  • views
    255217

A C64 Game - Step 43

Sign in to follow this  
Endurion

1837 views

And another two new enemies, Frankenstein's monster and a slime.



step43.png


Frankenstein's monster behaves very much like zombies, but is a bit stronger.
 

;------------------------------------------------------------
;simply walk left/right, do not fall off
;state 128 = invisible
; 1 = rising
; 0 = moving
; 2 = collapsing
;------------------------------------------------------------
!zone BehaviourFrankenstein
BehaviourFrankenstein
          lda SPRITE_HITBACK,x
          beq .NoHitBack
          dec SPRITE_HITBACK,x
          lda SPRITE_HITBACK_DIRECTION,x
          beq .HitBackRight

          ;move left
          jsr ObjectMoveLeftBlocking
          rts

.HitBackRight
          jsr ObjectMoveRightBlocking
          rts

.NoHitBack
          lda SPRITE_JUMP_POS,x
          bne .IsJumping
          jsr ObjectMoveDownBlocking
          bne .Falling

.IsJumping
          lda DELAYED_GENERIC_COUNTER
          and #$03
          beq .MovementUpdate
.NoMovement
          rts

.Falling
          lda DELAYED_GENERIC_COUNTER
          and #$03
          bne .NoMovement
          jmp .WalkWithoutAnimation

.MovementUpdate
          lda SPRITE_JUMP_POS,x
          bne .UpdateJump
          lda SPRITE_STATE,x
          bne .OtherStates
          ;moving
          jsr GenerateRandomNumber
          cmp #17
          beq .Jump
          jmp .NormalWalk

.OtherStates
          ;collapsing?
          cmp #2
          beq .Collapsing
          cmp #1
          beq .Rising
          cmp #128
          bne .NotHidden
          jmp .Hidden

.NotHidden
          rts

.Jump
          ;start jump
          lda #SPRITE_FRANKIE_JUMP_R
          clc
          adc SPRITE_DIRECTION,x
          sta SPRITE_POINTER_BASE,x

.UpdateJump
          jsr UpdateSpriteJump

          ;still move
          jmp .WalkWithoutAnimation

.NoUpdate
          rts
          
.Collapsing
          inc SPRITE_ANIM_DELAY,x
          lda SPRITE_ANIM_DELAY,x
          cmp #3
          bne .NoUpdate

          lda #0
          sta SPRITE_ANIM_DELAY,x

          lda SPRITE_ANIM_POS,x
          beq .CollapseDone

          dec SPRITE_ANIM_POS,x

          lda SPRITE_ANIM_POS,x
          clc
          asl
          adc #SPRITE_FRANKIE_RISE_R_1
          adc SPRITE_DIRECTION,x
          sta SPRITE_POINTER_BASE,x
          rts

.CollapseDone
          ;on to hidden state
          lda #128
          sta SPRITE_STATE,x

          lda #SPRITE_INVISIBLE
          sta SPRITE_POINTER_BASE,x
          ;generate hidden time
          jsr GenerateRandomNumber
          and #$31
          clc
          adc #25
          sta SPRITE_MOVE_POS,x

          ;normalise position on full char
          ldy SPRITE_CHAR_POS_X_DELTA,x
          sty PARAM5
.CheckXPos
          beq .XPosClear
          jsr ObjectMoveLeft
          dec PARAM5
          jmp .CheckXPos

.XPosClear
          ldy SPRITE_CHAR_POS_Y_DELTA,x
          sty PARAM5
.CheckYPos
          beq .YPosClear
          jsr ObjectMoveUp
          dec PARAM5
          jmp .CheckYPos
.YPosClear
          rts

.Rising
          inc SPRITE_ANIM_DELAY,x
          lda SPRITE_ANIM_DELAY,x
          cmp #3
          bne .NoUpdate

          lda #0
          sta SPRITE_ANIM_DELAY,x

          inc SPRITE_ANIM_POS,x
          lda SPRITE_ANIM_POS,x
          cmp #3
          beq .RiseDone
          clc
          asl
          adc #SPRITE_FRANKIE_RISE_R_1
          adc SPRITE_DIRECTION,x
          sta SPRITE_POINTER_BASE,x
          rts

.RiseDone
          lda #SPRITE_FRANKIE_WALK_R_1
          clc
          adc SPRITE_DIRECTION,x
          sta SPRITE_POINTER_BASE,x

          lda #0
          sta SPRITE_MOVE_POS,x
          sta SPRITE_ANIM_DELAY,x
          sta SPRITE_ANIM_POS,x
          sta SPRITE_STATE,x
          rts

.NormalWalk
          inc SPRITE_ANIM_DELAY,x
          lda SPRITE_ANIM_DELAY,x
          cmp #3
          bne .NoAnimUpdate

          lda #0
          sta SPRITE_ANIM_DELAY,x

          inc SPRITE_MOVE_POS,x

.NoAnimUpdate
          lda SPRITE_MOVE_POS,x
          and #$03
          sta SPRITE_MOVE_POS,x

          clc
          asl
          adc #SPRITE_FRANKIE_WALK_R_1
          adc SPRITE_DIRECTION,x
          sta SPRITE_POINTER_BASE,x

.WalkWithoutAnimation
          lda SPRITE_DIRECTION,x
          beq .MoveRight

          ;move left
          jsr ObjectMoveLeftBlocking
          beq .ToggleDirection

          lda SPRITE_ANNOYED,x
          beq .NotAnnoyed
          jsr ObjectMoveLeftBlocking
          beq .ToggleDirection
.NotAnnoyed
          rts

.MoveRight
          jsr ObjectMoveRightBlocking
          beq .ToggleDirection
          lda SPRITE_ANNOYED,x
          beq .NotAnnoyed
          jsr ObjectMoveRightBlocking
          beq .ToggleDirection
          rts

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

.Hidden
          ;are we apt to wake up?
          dec SPRITE_MOVE_POS,x
          bne .RandomMove
          
          ;wake up
          lda #1
          sta SPRITE_STATE,x
          lda #SPRITE_FRANKIE_RISE_R_1
          clc
          adc SPRITE_DIRECTION,x
          sta SPRITE_POINTER_BASE,x
          rts

.RandomMove
          ;move randomly left/right
          jsr GenerateRandomNumber
          and #$01
          beq .MoveLeft
          ;move right if possible
          jsr CanWalkRight
          beq .Blocked

          inc SPRITE_CHAR_POS_X,x

          ldy #8
          sty PARAM5

.MoveSpriteRight
          jsr MoveSpriteRight
          dec PARAM5
          bne .MoveSpriteRight
          rts

.MoveLeft
          jsr CanWalkLeft
          beq .Blocked

          dec SPRITE_CHAR_POS_X,x

          ldy #8
          sty PARAM5

.MoveSpriteLeft
          jsr MoveSpriteLeft
          dec PARAM5
          bne .MoveSpriteLeft
          rts
          
.Blocked
          rts


The slime sports new behaviour. Ducking and jumping through the stage trying to slime the player.
 

;------------------------------------------------------------
;slime
;------------------------------------------------------------
!zone BehaviourSlime
BehaviourSlime
          lda SPRITE_HITBACK,x
          beq .NoHitBack
          dec SPRITE_HITBACK,x
          lda SPRITE_HITBACK_DIRECTION,x
          beq .HitBackRight

          ;move left
          jsr ObjectMoveLeftBlocking
          rts

.HitBackRight
          jsr ObjectMoveRightBlocking
          rts

.NoHitBack
          ;state 0 = jumping
          ;state 1 = ducking
          ;state 2 = ducked
          ;state 3 = unducking

          lda SPRITE_STATE,x
          beq .SlimeJumping
          cmp #2
          beq .SlimeDucked

          inc SPRITE_ANIM_DELAY,x
          lda SPRITE_ANIM_DELAY,x
          cmp #6
          bne .AnimPause
          lda #0
          sta SPRITE_ANIM_DELAY,x

          ldy SPRITE_ANIM_POS,x
          inc SPRITE_ANIM_POS,x

          lda SPRITE_STATE,x
          cmp #3
          beq .SlimeUnducking

          cpy #3
          beq .DuckDone

          lda SLIME_DUCK_ANIMATION_TABLE,y
          clc
          adc SPRITE_DIRECTION,x
          sta SPRITE_POINTER_BASE,x
          rts

.DuckDone
          ;start ducked state
          lda #0
          sta SPRITE_ANIM_POS,x
          lda #2
          sta SPRITE_STATE,x

          jsr GenerateRandomNumber
          sta SPRITE_MOVE_POS,x

.AnimPause
          rts
          
.SlimeUnducking
          cpy #3
          beq .UnduckDone

          lda SLIME_UNDUCK_ANIMATION_TABLE,y
          clc
          adc SPRITE_DIRECTION,x
          sta SPRITE_POINTER_BASE,x
          rts

.UnduckDone
          ;start jump
          lda #0
          sta SPRITE_ANIM_POS,x
          sta SPRITE_STATE,x
          inc SPRITE_JUMP_POS,x
          rts

.SlimeDucked
          dec SPRITE_MOVE_POS,x
          bne .StayDucked

          inc SPRITE_STATE,x
.StayDucked
          rts

.SlimeJumping
          lda SPRITE_JUMP_POS,x
          beq .FallIfPossible

          ;toad is jumping
          lda SPRITE_JUMP_POS,x
          cmp #TOAD_JUMP_TABLE_SIZE
          bne .JumpOn

          ;jump done
          jmp .JumpBlocked

.JumpOn
          ldy SPRITE_JUMP_POS,x
          inc SPRITE_JUMP_POS,x
          lda TOAD_JUMP_TABLE,y
          bne .KeepJumping

          ;no jump movement needed
          jmp .SlimeMove

.KeepJumping
          sta PARAM5

.JumpContinue
          jsr ObjectMoveUpBlocking
          beq .JumpBlocked

          dec PARAM5
          bne .JumpContinue
          jmp .SlimeMove

.JumpBlocked
          lda #0
          sta SPRITE_JUMP_POS,x
          jmp .SlimeMove

.FallIfPossible
          jsr UpdateSpriteFall
          beq .CanJump
          jmp .SlimeMove

.CanJump
          inc SPRITE_STATE,x
          lda #0
          sta SPRITE_ANIM_DELAY,x
          sta SPRITE_ANIM_POS,x

          lda SPRITE_DIRECTION,x
          beq .LookingRight
          lda #SPRITE_SLIME_L_1
          sta SPRITE_POINTER_BASE,x
          rts

.LookingRight
          lda #SPRITE_SLIME_R_1
          sta SPRITE_POINTER_BASE,x
          rts

          ;simple move left/right
.SlimeMove
          lda SPRITE_DIRECTION,x
          beq .MoveRight

          jsr ObjectMoveLeftBlocking
          beq .ToggleDirection
          rts

.MoveRight
          jsr ObjectMoveRightBlocking
          beq .ToggleDirection
          rts

.ToggleDirection
          lda SPRITE_DIRECTION,x
          eor #1
          sta SPRITE_DIRECTION,x
          clc
          adc #SPRITE_SLIME_R_1
          sta SPRITE_POINTER_BASE,x
          rts



Beside the new monsters a few fixes and features are added as well. For one the LookingAtPlayer function would only notice player 1. Now it works for both players:
 

;------------------------------------------------------------
;determins if object is looking at player
;X = sprite index
;returns 1 if looking at player, 0 if not
;------------------------------------------------------------
!zone LookingAtPlayer
LookingAtPlayer
          lda SPRITE_DIRECTION,x
          beq .LookingRight

          lda SPRITE_ACTIVE
          cmp #TYPE_PLAYER_DEAN
          bne .NotDean

          lda SPRITE_CHAR_POS_X,x
          cmp SPRITE_CHAR_POS_X
          bpl .LookingAtPlayer

.NotDean
          lda SPRITE_ACTIVE + 1
          cmp #TYPE_PLAYER_SAM
          bne .NoPlayerInSight

          lda SPRITE_CHAR_POS_X,x
          cmp SPRITE_CHAR_POS_X + 1
          bpl .LookingAtPlayer
          jmp .NoPlayerInSight
          
.LookingRight
          lda SPRITE_ACTIVE
          cmp #TYPE_PLAYER_DEAN
          bne .NotDeanR

          lda SPRITE_CHAR_POS_X,x
          cmp SPRITE_CHAR_POS_X
          bmi .LookingAtPlayer

.NotDeanR
          lda SPRITE_ACTIVE + 1
          cmp #TYPE_PLAYER_SAM
          bne .NoPlayerInSight
          lda SPRITE_CHAR_POS_X,x
          cmp SPRITE_CHAR_POS_X + 1
          bmi .LookingAtPlayer
          jmp .NoPlayerInSight

.LookingAtPlayer
          lda #1
          rts

.NoPlayerInSight
          lda #0
          rts


And a little usability thing. Previously you could only change the game mode by pressing up in the title screen. Now it also works when pressing down:

 

          lda #$02
          bit JOYSTICK_PORT_II
          bne .NotDownPressed

          lda DOWN_RELEASED
          beq .DownPressed


          lda GAME_MODE
          bne .NoGameModeWrap2
          lda #3
          sta GAME_MODE
.NoGameModeWrap2
          dec GAME_MODE

          ;redisplay game mode
          ldx GAME_MODE
          lda TEXT_GAME_MODE_LO,x
          sta ZEROPAGE_POINTER_1
          lda TEXT_GAME_MODE_HI,x
          sta ZEROPAGE_POINTER_1 + 1
          lda #11
          sta PARAM1
          lda #21
          sta PARAM2
          jsr DisplayText

          lda #0
          jmp .DownPressed
          
.NotDownPressed
          lda #1
.DownPressed
          sta DOWN_RELEASED



 

step43.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