Variable Height Jump

I was wondering how you might implement a variable height jump. I don’t care so much for Double Jump, although I’m sure many others do. Being able to vary the height is a must for most platform games, but there seems to be a lack of info on the subject and how to best implement it in Godot.

Can anyone share their lovely knowledge on this with maybe a sample piece of code?

Thanks, Jay.

I’m definitely a beginner with Godot however I assume you would have to use how long the jump key is pressed to decide how high to jump. Perhaps a simple way would be to use the Input.is_action_pressed() to increase the height of a jump in small increments e.g. motion.y -= 100. This way the longer the button is pressed the higher the jump is.

You would need to know when the player is jumping to be able to do this; you don’t want to be changing motion.y when the player is walking around. That means changing the design of Yann’s code quite a bit and will break other stuff. If you are familiar with finite state machines then that is what I would code to make it so I knew when the player was jumping.

Just to throw an idea into the mix Jay …
If theres a feature or thing that you want, I would, in the first instance, ignore the coding side of it and walk it through sequentially in an abstract manner. that way you will have a process that you have to go through to get the feature behaving. then fallback to code it.

just from reading I take it that its like the longer you hold the jump button down the higher you go, up to a set maximum?

in its current form, could be a little tricky as its force based. but if its something you want to get your teeth into, why not come back to it once the hoppy days section has been completed.

Hi,

thanks for the ideas guys. I’ve tackled this before with Construct 2, however, I never quite grasped how it worked fully - forces and physics always make me scratch my head, even with simple things like this!

And to re-cap, yes, the longer you hold down the key/button, the higher the character jumps, but with a maximum height.

Below is a screenshot of a basic implementation of a players movement in Construct 2 and It works with forces/velocity:

set player vector y to player.platform.vector y/2

(There is a force applied to add gravity already).

Surely this could be adapted to Godot?

Oh, before I forget, below is a link to a post in Construct 2 regarding this problem and solution using the above method - please note the the red "x"s in the code are a method to reverse the conditions.

https://www.scirra.com/tutorials/1048/platform-jump-height-or-movement-based-on-tap-or-click-duration

Here’s some overly verbose code that gets the job done by keeping track of jumping and falling in the Player.gd script. It can, obviously, be improved quite a bit with a little time and consideration.

var jumping = false
var falling = false
var jumpSpeed = -300
var jumpHeight = 0
var maxJumpHeight = -1000

func jump(delta):
	if is_on_floor():
		jumping = false
		falling = false
		motion.y = 0
		jumpHeight = 0
		
	if not falling and Input.is_action_pressed("ui_up"):
		jumping = true
	
	if jumping and not Input.is_action_pressed("ui_up"):
		jumping = false
		falling = true
	
	if jumpHeight <= maxJumpHeight:
		jumping = false
		falling = true
		
	if jumping:
		motion.y = jumpSpeed # note: delta gets applied in mve_and_slide()
		jumpHeight += motion.y * delta

func fall(delta):
	if is_on_floor():
		jumping = false
		falling = false
		motion.y = 0
		jumpHeight = 0
	elif is_on_ceiling():
		jumping = false
		falling = true
		motion.y = GRAVITY * delta
	else:
		motion.y += GRAVITY * delta

Thanks TyN for putting in the effort, as you say it’s quite verbose, but I’ll give it a try to experiment with. I wonder if there is more direct way though, maybe someone else can comment?

I contacted Benjamin Anderson, who has a great set of lessons regarding making a basic platform game in Godot. He has kindly provided me with a simple way to implement a Variable Jump Height. I thought I’d share it here as it’s sadly missing wherever I look online.

extends KinematicBody2D

const UP = Vector2(0, -1)
const GRAVITY = 20
const ACCELERATION = 50
const MAX_SPEED = 200
const JUMP_HEIGHT = -550
const MIN_JUMP_HEIGHT = -300

var motion = Vector2()
var current_animation = "Idle"

func _physics_process(delta):
	motion.y += GRAVITY
	var friction = false
	
	if Input.is_action_pressed("ui_right"):
		motion.x = min(motion.x+ACCELERATION, MAX_SPEED)
		set_animation("Run")
	elif Input.is_action_pressed("ui_left"):
		motion.x = max(motion.x-ACCELERATION, -MAX_SPEED)
		set_animation("Run")
	else:
		friction = true
		set_animation("Idle")
	
	if is_on_floor():
		if Input.is_action_just_pressed("ui_up"):
			motion.y = JUMP_HEIGHT
		if friction == true:
			motion.x = lerp(motion.x, 0, .2)
	else:
		if motion.y < 0:
			set_animation("Jump")
		else:
			set_animation("Fall")
		motion.x = lerp(motion.x, 0, .05)
		
		# Variable jump height
		if Input.is_action_just_released("ui_up") && motion.y < MIN_JUMP_HEIGHT:
			motion.y = MIN_JUMP_HEIGHT
	
	if motion.x > 0:
		$Sprite.flip_h = false
	elif motion.x < 0:
		$Sprite.flip_h = true
	
	motion = move_and_slide(motion, UP, 5, 4, PI/3)

func set_animation(new_animation):
	if new_animation != current_animation:
		current_animation = new_animation
		$Sprite.play(current_animation)
2 Likes

Looks really good. After a bit of searching I found the lessons you mentioned here on YouTube

Privacy & Terms