🎉 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 43

posted in New Old Things
Published February 25, 2012
Advertisement

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



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
          clcadc SPRITE_DIRECTION,x
          sta SPRITE_POINTER_BASE,x

.UpdateJump
          jsr UpdateSpriteJump

          ;still movejmp .WalkWithoutAnimation

.NoUpdate
          rts
          
.Collapsinginc 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 #$31clcadc #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

.Risinginc 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
          clcadc 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

.NormalWalkinc 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
          clcadc 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
          clcadc 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
          clcadc 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

.SlimeDuckeddec 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 donejmp .JumpBlocked

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

          ;no jump movement neededjmp .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

.CanJumpinc 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
          clcadc #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_DEANbne .NotDean

          lda SPRITE_CHAR_POS_X,x
          cmp SPRITE_CHAR_POS_X
          bpl .LookingAtPlayer

.NotDean
          lda SPRITE_ACTIVE + 1cmp #TYPE_PLAYER_SAMbne .NoPlayerInSight

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

          lda SPRITE_CHAR_POS_X,x
          cmp SPRITE_CHAR_POS_X
          bmi .LookingAtPlayer

.NotDeanR
          lda SPRITE_ACTIVE + 1cmp #TYPE_PLAYER_SAMbne .NoPlayerInSight
          lda SPRITE_CHAR_POS_X,x
          cmp SPRITE_CHAR_POS_X + 1bmi .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

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