Skip to main content

Improve your jumping! | Type of jumps in Godot

Wall jump, Wall climbing, Wall sliding and double jump are some of the most common mechanics for a plat-former game. And on top of that they are super easy to create in Godot. So in this Godot tutorial, I have tried to implement all these things in the simplest way possible.

I would highly recommend you to watch the 2-D movement video first, because I am adding wall jumps and other stuff in that same script. So, watch it at 1.5x speed! to get an overview.

VIDEO TUTORIAL



TEXT TUTORIAL


Double Jump

For this, create a variable jump_counter. This will keep track of how many jumps we have done, while we're in the air. So by default it will be 0.
var jump_counter : int = 0	<-------
var jump_buffer_counter : int = 0
var cayote_counter : int = 0
Now if you remember, in the previous video, when we are pressing the jump button. We are setting the jump_buffer_counter. So, when we are not on the ground, we will check if buffer_counter > 0 This will be true, only when we have pressed the jump button. Other than this we will also make sure the jump_counter < 1: This will make sure we only jump once, when we are in the air.
Now inside it we will set the coyote counter to any number greater than 0.
This is because, if you remember when we are jumping.
We are checking for two things. One is buffer_counter and other is coyote_counter.
so when we press the jump button,
the jump_buffer_counter is going to be greater than 0
And the only other thing we need for jump is to set coyote_counter greater than 0.
And this is exactly what we are doing here. Also we have to increment the jump_counter by 1
if not is_on_floor():
 	if cayote_counter > 0:
    	cayote_counter -= 1
        
    if jump_buffer_counter > 0 and jump_counter < 1:	<-------
    	jump_counter += 1				<-------
        cayote_counter = 1				<-------

	velocity.y += gravity
	if velocity.y > 2000:
		velocity.y = 2000
And at last, when we are on the ground 
We want to reset the jump_counter back to 0.

func _physics_process(_delta):
	if is_on_floor():
		cayote_counter = cayote_time
		jump_counter = 0
And that's it. Just by these few lines of code, we have successfully added Double jump to our game.

Wall climbing

Now moving on to our next mechanics, which is Wall climbing.
To make our player climb the wall, it should first detect the wall
And for that i am going to add a raycast node.
Since my player sprite is 128px wide, 
that's why i am going to set position the raycast node to half of 128px which is 64px
This will position the raycast node on the edge of the sprite
Now we will cast this ray to just 10px on the x axis.
And finally you should set the collision mask according to your game.



Now coming to the script.
First we create a variable that contains the raycast node.
onready var raycast := $RayCast2D	<-------
var jump_counter : int = 0	
var jump_buffer_counter : int = 0
Now you want to do wall climbing, when you are not on the ground.
So, inside this function, First we will remove this jump counter condition.
And put that in a separate if statement.
Still this is the same thing as before.
Now before this if statement i am going to add one more if statement 
Which will contain the wall climbing code.
And replace the second if statement with else if.
Because we can not do both wall climbing and double jump at the same time.
Now in the first if statement, we check if our ray is colliding or not.
And if it is colliding with something, we make sure it is walls.
If both of these condition are satisfied then we can do the jump
So, again we set the coyote counter to 1.
if not is_on_floor():
	if cayote_counter > 0:
		cayote_counter -= 1

	if jump_buffer_counter > 0 :					<-------
		if raycast.is_colliding():				<-------
			if raycast.get_collider().name == "TileMap":	<-------
				cayote_counter = 1			<-------
		elif jump_counter < 1:					<-------
			cayote_counter = 1								
			jump_counter += 1
Now, come a bit down.
And when we are pressing the arrow keys.
We also want to set the position of raycast node and cast_to property.
So, for right key these are going to be positive 64 and 10
And for the left arrow key they are going to be -64 and -10
if Input.is_action_pressed("ui_right"):
	velocity.x += acceleration
	$Sprite.flip_h = false
	raycast.position.x = 64			<-------
	raycast.cast_to.x = 10			<-------

elif Input.is_action_pressed("ui_left"):
	velocity.x -= acceleration
	$Sprite.flip_h = true
	raycast.position.x = -64		<-------
	raycast.cast_to.x = -10			<-------
And now you can see, our player can climb the wall.
But this looks very boring.
So,  I like to also push the player away from the wall.
Because first, now the player has to press the right arrow key in order to continue climbing.
And second, this creates a nice wall climbing animation.

So to add this, we check if the sprite is flipped.
Because if it is flipped, then it means we are going in the left direction.
And the wall is on the left.
So we push the player in the right direction by adding 500 in the velocity.x
Otherwise we will subtract 500 from it.
if not is_on_floor():
	if cayote_counter < 0:
		cayote_counter -= 1

	if jump_buffer_counter > 0 :
		if raycast.is_colliding():
			if raycast.get_collider().name == "TileMap":
				cayote_counter = 1
				if $Sprite.flip_h:			<-------
					velocity.x += 500		<-------
				else:					<-------
					velocity.x -= 500		<-------
		elif jump_counter < 1:
			cayote_counter = 1
			jump_counter += 1
And just by doing that, It looks like our player is actually jumping in order to climb the wall.

Bonus: 
Let me tell you one thing, whatever we did for the wall climbing.
This is the same thing that you have to do if you want to create wall jumps.
And the reason i am calling this a wall climbing instead of wall jump
Is that, my player can change direction in the mid air.
And if i couldn't then i would call it wall jump.

because you should not add wall climbing and wall jump at the same time.
So, if your player can't change direction in the air 
then, you just have to make the player jump in the opposite direction.

Wall sliding

Now the third mechanic is wall sliding.
This is going to be pretty simple, all you have to do is reduce the max_fall_speed when we are on wall.
So, as you can see i have a max_fall_speed variable and it is set to 2000
This is the speed that we can achieve when we are not on the wall.
var max_fall_speed = 2000		<-------    
Now when we are not on the ground we are adding the gravity to player
And make sure it don’t go beyond max_fall_speed.
Now after adding gravity, we will check if the ray is colliding with anything or not.
and if it is colliding, then we make sure it is colliding with walls.
and after then we set the max_fall_speed to 1000
and if the ray is not colliding with anything we will set it to 2000 again.
if not is_on_floor():
	if cayote_counter > 0:
		cayote_counter -= 1

	if jump_buffer_counter > 0:
		if raycast.is_colliding():
			if raycast.get_collider().name == "TileMap":
				cayote_counter = 1
				if $Sprite.flip_h:
					velocity.x += 500
				else:
					velocity.x -= 500
		elif double_jump < 1:
			cayote_counter = 1
			double_jump += 1

	velocity.y += gravity
	if raycast.is_colliding():				<-------
		if raycast.get_collider().name == "TileMap":	<-------
			max_fall_speed = 1000			<-------
	else:							<-------
		max_fall_speed = 2000				<-------
	if velocity.y > max_fall_speed:				<-------
		velocity.y = max_fall_speed			<-------
And you are done! now you have successfully added all three of these mechanics in your game.
I hope you found this post helpful. 
If you have any doubt write down in the comment section.


Comments

Popular posts from this blog

Complete 2D player movement, Beginner to Pro in Godot

 Have you ever wondered why these games feel so good to play? If your answer is visuals then ,  No the key component is their controls. The character movement feels natural, and they move exactly how you want. A good character movement will always make the player feel that they are in total control of the character.  So, you are wondering how to achieve this?  Well, there are some tricks that professional developers use to make their control better. And today we are goanna see what they are and how you can do it in Godot. VIDEO TUTORIAL COMPLETE CODE: extends KinematicBody2D var velocity : Vector2 export var max_speed : int = 1000 export var gravity : float = 55 export var jump_force : int = 1600 export var acceleration : int = 50 export var jump_buffer_time : int = 15 export var cayote_time : int = 15 var jump_buffer_counter : int = 0 var cayote_counter : int = 0 func _physics_process(_delta): if is_on_floor(): cayote_counter = cayote_time if not is_on_floor(): if cayot

Background Loading in Godot | DICODE

Video Tutorial