Jump to content
  • Advertisement
  • entries
    104
  • comments
    102
  • views
    259228

A C64 Game - Step 43

Sign in to follow this  
Endurion

2040 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
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!