Wall jumping - how to implement

I’m making a 2-D platformer using arcade physics, and I want to implement wall jumping into my characters moveset.

I want it to be Mario-style - meaning I don’t want my character to be able to wall-jump up one wall by curving back to it and jumping off again - I’d rather the player have to use two walls and navigate upwards by jumping from one to another.

How would I go about implementing this? I’ve got some basic code that lets my character run and jump around a tile map, but I’m not sure where to start with wall jumping.

 if(Phaser.Input.Keyboard.JustDown(keyW) && player.body.blocked.right){
    player.setVelocityY(-200);
    player.setVelocityX(-200)
}

Above is the code I wrote to begin with (for jumping off the right wall), but it doesn’t work for me. Where am I going wrong?

Thank you! :slight_smile:

You could use a timer for each side, with a boolean in your if(Phaser.Input.Keyboard.JustDown(keyW) && player.body.blocked.right && canJumpRight)

if(player.Input.Keyboar.JustDown(keyW) && player.body.blocked.right && player.canJumpRight){
    player.serVelocityY(-200);
    player.setVelocityX(-200);
    player.canJumpRight = false;
    setTimeout(function(){
        player.canJumpRight = true;
    }, 3000);
}

3000 is the time in milliseconds, so 3 seconds :wink:

1 Like

Is there a game I can look at to see the mechanics you want?

1 Like

I’m thinking of something along the lines of Mario’s wall jump in the New Super Mario Bros series. Celeste also has the same type of wall jump.

Basically I don’t want something like Super Meat Boy or Hollow Knight where you can wall jump up ‘one side’ of the wall.

I can’t find any good example of clips on youtube of what I mean, but to be honest any type of functioning wall jump which pushes the player a little away from the wall when they jump would be super useful.

First things first is actually allowing wall jumping in the first place. The basic code you have there should be on the right track, it’s hard to know exactly why it’s not working without seeing your code. For example you may accidentally be setting horizontal velocity to 0 while in the air or have really high friction enabled. You should debug it to see if you ever get inside the conditional and it failing is a matter of your velocity change not working properly, or if the if statement is never true at all. If you could post the relevant player movement code then we should have a better idea of what’s going on here.

As for blocking Megaman X-style wall jumps, the trick is usually to not explicitly forbid it but to make the wall jump impart significant horizontal velocity. That way by the time the player is able to move back to the wall they first jumped from, they’ve fallen too far to gain height with a second jump. Here’s a numerical example: if your player wall jumps to the left and you give the player 200 pixels per second left velocity and their possible air acceleration is 100 pixels per second per second, then it will take them 2 seconds to return to net 0 horizontal velocity by exerting maximum rightward acceleration, i.e. holding down right on the D-pad. In this time they’ll have traveled 200 pixels, so now starting from velocity 0 they have to continue accelerating to the right until they’ve re-traveled those 200 pixels. This will take an additional 2 seconds, so 4 seconds total to return to the original wall. Therefore you just need to balance it so that the distance traveled vertically between the vertical velocity from the wall jump and gravity is negative before four seconds, i.e. say the wall jump gives 50 pixels per second vertical velocity upwards but gravity is 50 pixels per second per second downwards. (You can figure out these exact numbers with a bit of simple calculus/physics, but if that’s not your thing then it’s easy to just mess around with your values until you get something that feels good to you.) The important thing here is that in the air you need to have a momentum system of some sort, otherwise the frame after the wall jump the player can immediately return to the wall.

You -could- set it up so that there is a boolean flag (i.e. canLeftWallJump) that switches off whenever you left (right) wall jump and it doesn’t switch back on until you right (left) wall jump or land, but this could lead to some weird behavior where a player may fall a long ways after left (right) wall jumping, only to try it again and not be able to even if they can reach the wall again. In general it makes it harder to explain to your player when they can and cannot wall jump, which isn’t a good thing. It’s better to leave the system as easy to explain/remember as possible while designing it to get rid of certain behaviors you don’t want in my opinion.

1 Like

1 Like

Hey, I solved the problem! Thanks everyone for your help! :slight_smile:

I realised that for this type of wall jumping to work I definetly need a momentum-based platforming system, so I switched from setting velocity to setting acceleration up to a max speed.

Some example code - handles if player inputs right:

if (cursors.right.isDown || keyD.isDown) {
    player.setFlipX(true)
    player.setMaxVelocity(MAX_SPEED,TERMINAL_VELOCITY);
    
    if (player.body.onFloor()) {
        player.play('run', true);
        player.setAccelerationX(ACCELERATION);
    }
    else{player.setAccelerationX(AIR_ACCELERATION)};

I set the max acceleration for every input because I wanted some inputs to produce different results (e.g. air dashing would have a higher max speed).

And this is the code I used for jumping off the right wall (basically the same for the left wall):

if (Phaser.Input.Keyboard.JustDown(keySpace) {
    //jump from right wall
   if (player.body.blocked.right){
        player.setAccelerationX(-WALL_JUMP_ACCELERATION);
        player.setMaxVelocity(WALL_JUMP_MAX_SPEED, TERMINAL_VELOCITY);
        player.setVelocityY(JUMP_FORCE) 
    }