[4.5.6] Wall jump in Metroidvania mod

kevin81

Active member
Last night, I managed to implement a wall jump in my Metroidvania mod based burner project game. I'm not sure if it is optimized and I think it might be done better, but it worked for my game, so I figured I'd share my script with you all. Maybe someone might find this useful.

To add this to your game, you replace the jump_throughPlat.asm input script with the following code (make sure to not overwrite the original file though).

Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Only can jump if the place below feet is free,
;; OR of the left/right side contains a wall.

    SwitchBank #$1C

;; +checkBottomWall:
    LDY Object_type,x

    LDA ObjectBboxTop,y
    CLC
    ADC ObjectHeight,y
    sta temp2
    
    LDA Object_x_hi,x
    CLC
    ADC ObjectBboxLeft,y
    STA temp

    JSR getPointColTable
    
    LDA Object_y_hi,x
    CLC
    ADC #$02
    CLC
    ADC temp2
    STA temp1

;; check below feet to see if it is solid.
;;; if it is (equal), can jump.
;;; if not, skips jumping.
    CheckCollisionPoint temp, temp1, #$01, tempA
    BNE +checkBottomWallAgain
        JMP  +doJump
        
+checkBottomWallAgain:
    LDY Object_type,x

    LDA ObjectWidth,y
    CLC
    ADC temp
    STA temp

    JSR getPointColTable

;; check below feet to see if it is solid.
;;; if it is (equal), can jump.
;;; if not, skips jumping.
    CheckCollisionPoint temp, temp1, #$01, tempA       
    BNE +checkRightWall
        JMP +doJump

+checkRightWall:
    LDY Object_type,x

    LDA ObjectBboxLeft,y
    CLC
    ADC ObjectWidth,y
    STA temp2
    
    LDA Object_x_hi,x
    CLC
    ADC #$02
    CLC
    ADC temp2
    STA temp

    JSR getPointColTable
    
    LDA Object_y_hi,x
    CLC
    ADC ObjectBboxTop,y
    STA temp1
    
;; check the right side of the player to see if it is solid.
;;; if it is (equal), can jump.
;;; if not, skips jumping.
    CheckCollisionPoint temp, temp1, #$01, tempA
    BNE +checkRightWallAgain
        JMP  +doJump

+checkRightWallAgain:
    LDY Object_type,x

    LDA ObjectHeight,y
    CLC
    ADC temp1
    STA temp1

;; check the right side of the player to see if it is solid.
;;; if it is (equal), can jump.
;;; if not, skips jumping.
    CheckCollisionPoint temp, temp1, #$01, tempA
    BNE +checkLeftWall
        JMP  +doJump

+checkLeftWall:
    LDY Object_type,x
    
    LDA Object_x_hi,x
    CLC
    ADC ObjectBboxLeft,y
    SEC
    SBC #$02
    STA temp

;; check the left side of the player to see if it is solid.
;;; if it is (equal), can jump.
;;; if not, skips jumping.
    CheckCollisionPoint temp, temp1, #$01, tempA
    BNE +checkLeftWallAgain
        JMP +doJump

+checkLeftWallAgain:
    LDY Object_type,x

    LDA Object_y_hi,x
    CLC
    ADC ObjectBboxTop,y
    STA temp1

;; check the left side of the player to see if it is solid.
;;; if it is (equal), can jump.
;;; if not, skips jumping.
    CheckCollisionPoint temp, temp1, #$01, tempA
    BEQ +doJump
        JMP +skipJumping

+doJump:
    TXA
    STA temp ;; assumes the object we want to move is in x.
    
    ;; comment out and replace with your jumping sound effect
    ;; PlaySound #sfx_Jump

    LDY Object_type,x
    LDA ObjectJumpSpeedLo,y
    EOR #$FF
    STA Object_v_speed_lo,x
    LDA ObjectJumpSpeedHi,y
    EOR #$FF
    STA Object_v_speed_hi,x
        
    TXA
    STA temp ;; assumes the object we want to move is in x.

+skipJumping:
    ReturnBank
    RTS
 

Bucket Mouse

Active member
Okay, I've improved this. There's a problem with the original: if you just stand facing a wall, you can jump infinitely while doing nothing else. Wall jumps need a kick to the other side -- otherwise it has no challenge (and makes no sense).

So this improved version checks for both contact with a wall AND a crosspad press in the opposite direction before it allows a jump.

Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Only can jump if the place below feet is free,
;; OR of the left/right side contains a wall.

    SwitchBank #$1C

;; +checkBottomWall:
    LDY Object_type,x

    LDA ObjectBboxTop,y
    CLC
    ADC ObjectHeight,y
    sta temp2
    
    LDA Object_x_hi,x
    CLC
    ADC ObjectBboxLeft,y
    STA temp

    JSR getPointColTable
    
    LDA Object_y_hi,x
    CLC
    ADC #$02
    CLC
    ADC temp2
    STA temp1

;; check below feet to see if it is solid.
;;; if it is (equal), can jump.
;;; if not, skips jumping.
    CheckCollisionPoint temp, temp1, #$01, tempA
    BNE +checkBottomWallAgain
        JMP  +doJump
        
+checkBottomWallAgain:
    LDY Object_type,x

    LDA ObjectWidth,y
    CLC
    ADC temp
    STA temp

    JSR getPointColTable

;; check below feet to see if it is solid.
;;; if it is (equal), can jump.
;;; if not, skips jumping.
    CheckCollisionPoint temp, temp1, #$01, tempA       
    BNE +checkRightWall
        JMP +doJump

+checkRightWall:
    LDY Object_type,x

    LDA ObjectBboxLeft,y
    CLC
    ADC ObjectWidth,y
    STA temp2
    
    LDA Object_x_hi,x
    CLC
    ADC #$02
    CLC
    ADC temp2
    STA temp

    JSR getPointColTable
    
    LDA Object_y_hi,x
    CLC
    ADC ObjectBboxTop,y
    STA temp1
    
;; check the right side of the player to see if it is solid.
;;; if it is (equal), can jump.
;;; if not, skips jumping.
    CheckCollisionPoint temp, temp1, #$01, tempA
    BNE +checkRightWallAgain
                    LDA gamepad
        AND #%01000000 ; checks for left press
        BNE +
        JMP +skipJumping
+
        JMP  +doJump

+checkRightWallAgain:
    LDY Object_type,x

    LDA ObjectHeight,y
    CLC
    ADC temp1
    STA temp1

;; check the right side of the player to see if it is solid.
;;; if it is (equal), can jump.
;;; if not, skips jumping.
    CheckCollisionPoint temp, temp1, #$01, tempA
    BNE +checkLeftWall
        JMP  +doJump

+checkLeftWall:
    LDY Object_type,x
    
    LDA Object_x_hi,x
    CLC
    ADC ObjectBboxLeft,y
    SEC
    SBC #$02
    STA temp

;; check the left side of the player to see if it is solid.
;;; if it is (equal), can jump.
;;; if not, skips jumping.
    CheckCollisionPoint temp, temp1, #$01, tempA
    BNE +checkLeftWallAgain
                LDA gamepad
        AND #%10000000 ; checks for right press
        BNE +
        JMP +skipJumping
+
        JMP +doJump

+checkLeftWallAgain:
    LDY Object_type,x

    LDA Object_y_hi,x
    CLC
    ADC ObjectBboxTop,y
    STA temp1

;; check the left side of the player to see if it is solid.
;;; if it is (equal), can jump.
;;; if not, skips jumping.
    CheckCollisionPoint temp, temp1, #$01, tempA
    BEQ +doJump
        JMP +skipJumping

+doJump:
    TXA
    STA temp ;; assumes the object we want to move is in x.
    
    ;; comment out and replace with your jumping sound effect
    ;; PlaySound #sfx_Jump

    LDY Object_type,x
    LDA ObjectJumpSpeedLo,y
    EOR #$FF
    STA Object_v_speed_lo,x
    LDA ObjectJumpSpeedHi,y
    EOR #$FF
    STA Object_v_speed_hi,x
        
    TXA
    STA temp ;; assumes the object we want to move is in x.

+skipJumping:
    ReturnBank
    RTS
 
Top Bottom