[4.5.6] Making special death screen

@dale_coop Coming back to this one. For my new game, I have definitely learned a lot more. Only problem I am having now, due to code placement, it's resulting in a Game Over after just 1 punch from Monster.

Where should I move it to in order to work normally?

Code:
    LDA gameHandler
    AND #%10000000
    BEQ +canHurtPlayer
        JMP +skipHurt
+canHurtPlayer:
    
    
    ; TXA
    ; STA temp
    ; GetActionStep temp
    ; CMP #$07
    ; BNE +canHurtPlayer
        ; JMP +skipHurt
    ; +canHurtPlayer
    ;;; will presume there is a variable myHealth
    ;;; and that player hurt state is action state 7.
    GetActionStep player1_object
    CMP #$07 ;; hurt state.
    BNE +notAlreadyInHurtState
        JMP +skipHurt
    +notAlreadyInHurtState
    
        
        
         DEC myHealth
        
         BMI +healthBelowZero
         BEQ +healthBelowZero
             JMP +notDeadYet
         +healthBelowZero
             JMP +playerHealthIsZero
         +notDeadYet
;        UpdateHudElement #$02
         ChangeActionStep player1_object, #$07
         ;;;; also could warp to game over screen here instead. ;;

         WarpToScreen #$00, #$FF, #$01  ;;This is warp to UNDERWORLD, LAST SCREEN this is for me because 8x8 , #$01 is normal warp;;
    ;; arg0 = warp to map.  0= map1.  1= map2.
    ;; arg1 = screen to warp to. use mouse to find coordinates = #$yx use hex convertor.
    ;; arg2 = screen transition type - most likely use 1 here.
        ;; 1 = warp, where it observes the warp in position for the player.
    ;;Don't Forget to set WARP IN COORDINATES ON YOUR MAP!;;
         JMP +skipHurt
            ; ;; recoil
            ; LDA #$00
            ; STA Object_h_speed_hi,x
            ; STA Object_h_speed_lo,x
            ; STA Object_v_speed_hi,x
            ; STA Object_v_speed_lo,x
            ; LDA xPrev
            ; STA Object_x_hi,x
            ; LDA yPrev
            ; STA Object_y_hi,x
    ; +notAlreadyInHurtState
        ; LDA Object_x_hi,x
        ; CLC
        ; ADC self_center_x
        ; STA tempA
        ; LDA Object_y_hi,x
        ; CLC
        ; ADC self_center_y
        ; STA tempB
        ; TXA
        ; PHA
            ; LDX otherObject
            ; LDA Object_x_hi,x
            ; CLC
            ; ADC other_center_x
            ; STA tempC
            ; LDA Object_y_hi,x
            ; CLC
            ; ADC other_center_y
            ; STA tempD
        ; PLA
        ; TAX
    
        ; ;;; RECOIL
        ; ;;; find the center.
        ; LDA tempA
        ; SEC
        ; SBC tempC
        ; bpl +gotAbs ;; if positive, this is abs value
            ; EOR #$FF
            ; CLC
            ; ADC #$01
        ; +gotAbs
            ; STA temp
            
        ; LDA tempB
        ; SEC
        ; SBC tempD
        ; bpl +gotAbs
            ; EOR #$FF
            ; CLC
            ; ADC #$01
        ; +gotAbs
            ; ;;; now abs of y is in A
            ; CMP temp
            ; BCC +recoilHor
                ; ;; recoil vert
                ; LDA tempB
                ; CMP tempD
                ; BCS +recoilDown
                    ; LDA Object_direction,x
                    ; AND #%00001111
                    ; ORA #%00100000
                    ; STA Object_direction,x
                    ; JMP +skipHurt
                ; +recoilDown
                    ; LDA Object_direction,x
                    ; AND #%00001111
                    ; ORA #%00110000
                    ; STA Object_direction,x
                    ; JMP +skipHurt
            ; +recoilHor
                ; LDA tempA
                ; CMP tempC
                ; BCS +recoilRight
                    ; LDA Object_direction,x
                    ; AND #%00001111
                    ; ORA #%10000000
                    ; STA Object_direction,x
                    ; JMP +skipHurt

                ; +recoilRight
                    ; LDA Object_direction,x
                    ; AND #%00001111
                    ; ORA #%11000000
                    ; STA Object_direction,x
                    ; JMP +skipHurt
    
        ; JMP +skipHurt
 +playerHealthIsZero:

    LDA continueMap
    STA warpMap
    
    LDA continueScreen
    STA currentNametable
    
    LDX player1_object
    STA Object_screen,x
    
    LDA #$02 ;; this is continue type warp.
    STA screenTransitionType ;; is of warp type

    
    LDA gameHandler
    ORA #%10000000
    STA gameHandler ;; this will set the next game loop to update the screen.
    LDA myMaxHealth
    STA myHealth
+skipHurt
 
Code:
    LDA gameHandler
    AND #%10000000
    BEQ +canHurtPlayer
        JMP +skipHurt
+canHurtPlayer:
    
    
    ; TXA
    ; STA temp
    ; GetActionStep temp
    ; CMP #$07
    ; BNE +canHurtPlayer
        ; JMP +skipHurt
    ; +canHurtPlayer
    ;;; will presume there is a variable myHealth
    ;;; and that player hurt state is action state 7.
    GetActionStep player1_object
    CMP #$07 ;; hurt state.
    BNE +notAlreadyInHurtState
        JMP +skipHurt
    +notAlreadyInHurtState
    
        
        
         DEC myHealth
        
         BMI +healthBelowZero
         BEQ +healthBelowZero
             JMP +notDeadYet
         +healthBelowZero
             JMP +playerHealthIsZero
         +notDeadYet
;        UpdateHudElement #$02
         ChangeActionStep player1_object, #$07
        
         JMP +skipHurt
            ; ;; recoil
            ; LDA #$00
            ; STA Object_h_speed_hi,x
            ; STA Object_h_speed_lo,x
            ; STA Object_v_speed_hi,x
            ; STA Object_v_speed_lo,x
            ; LDA xPrev
            ; STA Object_x_hi,x
            ; LDA yPrev
            ; STA Object_y_hi,x
    ; +notAlreadyInHurtState
        ; LDA Object_x_hi,x
        ; CLC
        ; ADC self_center_x
        ; STA tempA
        ; LDA Object_y_hi,x
        ; CLC
        ; ADC self_center_y
        ; STA tempB
        ; TXA
        ; PHA
            ; LDX otherObject
            ; LDA Object_x_hi,x
            ; CLC
            ; ADC other_center_x
            ; STA tempC
            ; LDA Object_y_hi,x
            ; CLC
            ; ADC other_center_y
            ; STA tempD
        ; PLA
        ; TAX
    
        ; ;;; RECOIL
        ; ;;; find the center.
        ; LDA tempA
        ; SEC
        ; SBC tempC
        ; bpl +gotAbs ;; if positive, this is abs value
            ; EOR #$FF
            ; CLC
            ; ADC #$01
        ; +gotAbs
            ; STA temp
            
        ; LDA tempB
        ; SEC
        ; SBC tempD
        ; bpl +gotAbs
            ; EOR #$FF
            ; CLC
            ; ADC #$01
        ; +gotAbs
            ; ;;; now abs of y is in A
            ; CMP temp
            ; BCC +recoilHor
                ; ;; recoil vert
                ; LDA tempB
                ; CMP tempD
                ; BCS +recoilDown
                    ; LDA Object_direction,x
                    ; AND #%00001111
                    ; ORA #%00100000
                    ; STA Object_direction,x
                    ; JMP +skipHurt
                ; +recoilDown
                    ; LDA Object_direction,x
                    ; AND #%00001111
                    ; ORA #%00110000
                    ; STA Object_direction,x
                    ; JMP +skipHurt
            ; +recoilHor
                ; LDA tempA
                ; CMP tempC
                ; BCS +recoilRight
                    ; LDA Object_direction,x
                    ; AND #%00001111
                    ; ORA #%10000000
                    ; STA Object_direction,x
                    ; JMP +skipHurt

                ; +recoilRight
                    ; LDA Object_direction,x
                    ; AND #%00001111
                    ; ORA #%11000000
                    ; STA Object_direction,x
                    ; JMP +skipHurt
    
        ; JMP +skipHurt
 +playerHealthIsZero:
 
  ;;;; also could warp to game over screen here instead. ;;

       WarpToScreen #$00, #$FF, #$01  ;;This is warp to UNDERWORLD, LAST SCREEN this is for me because 8x8 , #$01 is normal warp;;
    ;; arg0 = warp to map.  0= map1.  1= map2.
    ;; arg1 = screen to warp to. use mouse to find coordinates = #$yx use hex convertor.
    ;; arg2 = screen transition type - most likely use 1 here.
        ;; 1 = warp, where it observes the warp in position for the player.
    ;;Don't Forget to set WARP IN COORDINATES ON YOUR MAP!;;

    LDA continueMap
    STA warpMap
    
    LDA continueScreen
    STA currentNametable
    
    LDX player1_object
    STA Object_screen,x
    
    LDA #$02 ;; this is continue type warp.
    STA screenTransitionType ;; is of warp type

    
    LDA gameHandler
    ORA #%10000000
    STA gameHandler ;; this will set the next game loop to update the screen.
    LDA myMaxHealth
    STA myHealth
+skipHurt
The code should be placed after the lone " +playerHealthIsZero:"

Ok, did that, but now we are back to it not warping at all. Here is current setup.

It feels good knowing I'm this close because I have finally seen that I can make it warp upon death... it just doesn't need to be instant death. lol
 
Ok, there's a lot of noted out text between 'JMP +skipHurt' and '+playerHealthIsZero'.

I've experimented with it a few ways.

If I put the code above JMP +skipHurt = Instant game over after one punch (regardless of my health settings)
If put it anywhere below that, including after the lone +playerHealthIsZero = Nothing happens when I die. Just goes back to beginning of stage.
 
Just wanted to share that I finally got the hurt script to warp me to my game over screen. I kept re-reading what Dale had shared on here and tinkering with it until I got it to work. Sharing here for others to use if making a brawler. My game over screen is located on the bottom right x15-y15 (FF)

Code:
 LDA gameHandler
    AND #%10000000
    BEQ +canHurtPlayer
        JMP +skipHurt
+canHurtPlayer:
    
    
    ; TXA
    ; STA temp
    ; GetActionStep temp
    ; CMP #$07
    ; BNE +canHurtPlayer
        ; JMP +skipHurt
    ; +canHurtPlayer
    ;;; will presume there is a variable myHealth
    ;;; and that player hurt state is action state 7.
    GetActionStep player1_object
    CMP #$07 ;; hurt state.
    BNE +notAlreadyInHurtState
        JMP +skipHurt
    +notAlreadyInHurtState
    
        
        
         DEC myHealth
        
         BMI +healthBelowZero
         BEQ +healthBelowZero
             JMP +notDeadYet
         +healthBelowZero
             JMP +playerHealthIsZero
         +notDeadYet
;        UpdateHudElement #$02
         ChangeActionStep player1_object, #$07
        
         JMP +skipHurt
        
            ; ;; recoil
            ; LDA #$00
            ; STA Object_h_speed_hi,x
            ; STA Object_h_speed_lo,x
            ; STA Object_v_speed_hi,x
            ; STA Object_v_speed_lo,x
            ; LDA xPrev
            ; STA Object_x_hi,x
            ; LDA yPrev
            ; STA Object_y_hi,x
    ; +notAlreadyInHurtState
        ; LDA Object_x_hi,x
        ; CLC
        ; ADC self_center_x
        ; STA tempA
        ; LDA Object_y_hi,x
        ; CLC
        ; ADC self_center_y
        ; STA tempB
        ; TXA
        ; PHA
            ; LDX otherObject
            ; LDA Object_x_hi,x
            ; CLC
            ; ADC other_center_x
            ; STA tempC
            ; LDA Object_y_hi,x
            ; CLC
            ; ADC other_center_y
            ; STA tempD
        ; PLA
        ; TAX
    
        ; ;;; RECOIL
        ; ;;; find the center.
        ; LDA tempA
        ; SEC
        ; SBC tempC
        ; bpl +gotAbs ;; if positive, this is abs value
            ; EOR #$FF
            ; CLC
            ; ADC #$01
        ; +gotAbs
            ; STA temp
            
        ; LDA tempB
        ; SEC
        ; SBC tempD
        ; bpl +gotAbs
            ; EOR #$FF
            ; CLC
            ; ADC #$01
        ; +gotAbs
            ; ;;; now abs of y is in A
            ; CMP temp
            ; BCC +recoilHor
                ; ;; recoil vert
                ; LDA tempB
                ; CMP tempD
                ; BCS +recoilDown
                    ; LDA Object_direction,x
                    ; AND #%00001111
                    ; ORA #%00100000
                    ; STA Object_direction,x
                    ; JMP +skipHurt
                ; +recoilDown
                    ; LDA Object_direction,x
                    ; AND #%00001111
                    ; ORA #%00110000
                    ; STA Object_direction,x
                    ; JMP +skipHurt
            ; +recoilHor
                ; LDA tempA
                ; CMP tempC
                ; BCS +recoilRight
                    ; LDA Object_direction,x
                    ; AND #%00001111
                    ; ORA #%10000000
                    ; STA Object_direction,x
                    ; JMP +skipHurt

                ; +recoilRight
                    ; LDA Object_direction,x
                    ; AND #%00001111
                    ; ORA #%11000000
                    ; STA Object_direction,x
                    ; JMP +skipHurt
    
        ; JMP +skipHurt
 +playerHealthIsZero:
 
;; JMP RESET
    
    LDA #$FF            ;; the screen number you want to warp to
    STA warpToScreen
    LDA #$00                ;; the map to warp to (overworld/underworld)
    STA warpToMap

    WarpToScreen warpToMap, warpToScreen, #$02
    JMP +skipHurt
 
    LDA continueMap
    STA warpMap
    
    LDA continueScreen
    STA currentNametable
    
    LDX player1_object
    STA Object_screen,x
    
    LDA #$02 ;; this is continue type warp.
    STA screenTransitionType ;; is of warp type

    
    LDA gameHandler
    ORA #%10000000
    STA gameHandler ;; this will set the next game loop to update the screen.
    LDA myMaxHealth
    STA myHealth
+skipHurt
 

dale_coop

Moderator
Staff member
hey @brandonbrains

Try that fixed code instead:
Code:
LDA gameHandler
    AND #%10000000
    BEQ +canHurtPlayer
        JMP +skipHurt
+canHurtPlayer:
    
    ; TXA
    ; STA temp
    ; GetActionStep temp
    ; CMP #$07
    ; BNE +canHurtPlayer
        ; JMP +skipHurt
    ; +canHurtPlayer

    ;;; will presume there is a variable myHealth
    ;;; and that player hurt state is action state 7.
    GetActionStep player1_object
    CMP #$07 ;; hurt state.
    BNE +notAlreadyInHurtState
        JMP +skipHurt
    +notAlreadyInHurtState
    
         DEC myHealth
        
         BMI +healthBelowZero
         BEQ +healthBelowZero
             JMP +notDeadYet
         +healthBelowZero
             JMP +playerHealthIsZero
         +notDeadYet:
        
;        UpdateHudElement #$02
         ChangeActionStep player1_object, #$07
        
         JMP +skipHurt
        
            ; ;; recoil
            ; LDA #$00
            ; STA Object_h_speed_hi,x
            ; STA Object_h_speed_lo,x
            ; STA Object_v_speed_hi,x
            ; STA Object_v_speed_lo,x
            ; LDA xPrev
            ; STA Object_x_hi,x
            ; LDA yPrev
            ; STA Object_y_hi,x
    ; +notAlreadyInHurtState
        ; LDA Object_x_hi,x
        ; CLC
        ; ADC self_center_x
        ; STA tempA
        ; LDA Object_y_hi,x
        ; CLC
        ; ADC self_center_y
        ; STA tempB
        ; TXA
        ; PHA
            ; LDX otherObject
            ; LDA Object_x_hi,x
            ; CLC
            ; ADC other_center_x
            ; STA tempC
            ; LDA Object_y_hi,x
            ; CLC
            ; ADC other_center_y
            ; STA tempD
        ; PLA
        ; TAX
    
        ; ;;; RECOIL
        ; ;;; find the center.
        ; LDA tempA
        ; SEC
        ; SBC tempC
        ; bpl +gotAbs ;; if positive, this is abs value
            ; EOR #$FF
            ; CLC
            ; ADC #$01
        ; +gotAbs
            ; STA temp
            
        ; LDA tempB
        ; SEC
        ; SBC tempD
        ; bpl +gotAbs
            ; EOR #$FF
            ; CLC
            ; ADC #$01
        ; +gotAbs
            ; ;;; now abs of y is in A
            ; CMP temp
            ; BCC +recoilHor
                ; ;; recoil vert
                ; LDA tempB
                ; CMP tempD
                ; BCS +recoilDown
                    ; LDA Object_direction,x
                    ; AND #%00001111
                    ; ORA #%00100000
                    ; STA Object_direction,x
                    ; JMP +skipHurt
                ; +recoilDown
                    ; LDA Object_direction,x
                    ; AND #%00001111
                    ; ORA #%00110000
                    ; STA Object_direction,x
                    ; JMP +skipHurt
            ; +recoilHor
                ; LDA tempA
                ; CMP tempC
                ; BCS +recoilRight
                    ; LDA Object_direction,x
                    ; AND #%00001111
                    ; ORA #%10000000
                    ; STA Object_direction,x
                    ; JMP +skipHurt

                ; +recoilRight
                    ; LDA Object_direction,x
                    ; AND #%00001111
                    ; ORA #%11000000
                    ; STA Object_direction,x
                    ; JMP +skipHurt
    
        ; JMP +skipHurt
 +playerHealthIsZero:
 
    ;; JMP RESET


     DEC myLives
    
    ;PlaySound #sfx_LOSE   
    ;UpdateHudElement #$01
    
    LDA myLives
    BNE +notZeroLives   
    
        ;; NO MORE LIVES:
        ;; Warp to GAME OVER screen ($FF 255, last screen of the map)
        
        LDA #$FF            ;; the screen number you want to warp to
        STA warpToScreen
        
        LDA #$00                ;; the map to warp to (0:overworld / 1:underworld)
        STA warpToMap

        WarpToScreen warpToMap, warpToScreen, #$01

        LDA #$FF
        STA gameState
        JMP +skipHurt
        
        
 +notZeroLives:
 
    ;; still have lives... we will warp to the last checkpoint :
    LDA continueMap
    STA warpMap
    
    LDA continueScreen
    STA warpToScreen

    WarpToScreen warpToMap, warpToScreen, #$02
    
    LDA myMaxHealth
    STA myHealth
    
    LDA #$FF
    STA gameState
+skipHurt
 
@dale_coop That not only worked, but if you can help me tweak it a bit more, I can solve another issue on my short list of bugs.
Your code incorporates the lives AND the health. Which I hadn't even considered. Thank you for that.
Since you did that, I figured out how to put in checkpoint tiles from the Platformer base, so that if you still have lives left, you aren't kicked back to beginning of game when you run out of health.
My question: How do we further tweak this code to recognize the checkpoints in place?

If this can be done, I won't have to worry about how to refresh health when warping to a new stage.
Then all I'll have left is figuring out the stop functionality on my A button right fist punch. :)
 

dale_coop

Moderator
Staff member
The ckeckpoint tiles should already work. Just place one at the beginning of your levels (usually place it at the same post when your player warps in), or entrance of your main areas (if it's an RPG, ...)
When the player dies, if still have lives remaining, he should spawn to the last checkpoint tile.

If It doesn't work, please share the script of your checkpoint tile.
 
I ensured I have the script and a named tile type of 'Checkpoint' in my 05 Tile Type slot. On the Warp To Screen, my Warp In Location and Checkpoint are both located on X1,Y11.

I got it to work when I realized I needed to make a 2 tile tall checkpoint to accommodate for the brawler being taller than the preset restraints of the Platformer. At least that's what made sense to me and it worked out.
 

dale_coop

Moderator
Staff member
Yes, the tile collision engine is not really... "precise". (depending of the size of your bounding box, the placements,...)
Once you will find a checkpoint placement that works for your game, stick with it ;)
 
Top Bottom