2D Platformer: How to control jump height | Mario-like jumps

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Tryst


I am fairly new to Godot and I’ve already taken a look at a few tutorials but I am still very new to this.

Right now I am trying to create a little platformer and have the following jumpscript (with limited controls of the jump height):

  const GRAVITY = 20
  const MIN_JUMP_HEIGHT = -150
  const MAX_JUMP_HEIGHT = -550
  var timeHeld = 0
  var timeForFullJump = 0.1
  var motion = Vector2()

  func _physics_process(delta):
   motion.y += GRAVITY
   var friction = false

  if is_on_floor():
	  if Input.is_action_pressed("ui_up"):
	  	  timeheld += delta
		  if timeHeld >= timeForFullJump:
			  motion.y = MAX_JUMP_HEIGHT
	  if Input.is_action_just_released("ui_up"):
			  motion.y = ((MAX_JUMP_HEIGHT - MIN_JUMP_HEIGHT) * (timeHeld / 
                           timeForFullJump) + MIN_JUMP_HEIGHT)
	  if friction == true:
		  motion.x = lerp(motion.x, 0, 0.2)

The problem I have with my script is, that there is a very slight delay if I hold down the button till the charackter starts jumping (0.1). Is it possible to get rid of the delay without changing the var timeForFullJump?

I have tried to first use another if loop with “Input.is_action_just_pressed” but it did not work properly. :frowning:

Is there a better (and easier) way to implement a mechanism for Mario-like jumps?

Thanks a lot.

:bust_in_silhouette: Reply From: Diet Estus

When I implement variable jump height, I have a jump() method which is called when the jump button is just pressed. In my input processing, I have:

 if Input.is_action_just_pressed("jump"):

The jump() method sets the Player’s y-velocity to the maximum jump velocity:

func jump():
    vel.y = -JUMP_VELOCITY

To get variable jumping, I call a jump_cut() method whenever the jump button is released. So, in my input processing, I have:

 if Input.is_action_just_released("jump"):

And the jump_cut() method looks like this:

func jump_cut():
    if vel.y < -100:
        vel.y = -100

Set up this way, if the player releases the jump button while the jump velocity is still very large, it’s cut down to a mere -100 pixels. This gives variable jumping.

I’d be interested to see someone make your method work though!

I can recommend this method, been using same only with a little bit more of physic calculation, here great GDC talk covering topic

Bartosz | 2018-03-19 17:53

1 Like
:bust_in_silhouette: Reply From: BlumiDev

So I made this mario-like jump, it works wonderfully for me. I know it’s old post but other people may find it useful. Just change variables in code to see what works for you.

extends KinematicBody2D

export var fallMultiplier = 2 
export var lowJumpMultiplier = 10 
export var jumpVelocity = 400 #Jump height

var velocity = Vector2()
export var gravity = 8

func _physics_process(delta):

	#Applying gravity to player
	velocity.y += gravity 
	#Jump Physics
	if velocity.y > 0: #Player is falling
		velocity += Vector2.UP * (-9.81) * (fallMultiplier) #Falling action is faster than jumping action | Like in mario

	elif velocity.y < 0 && Input.is_action_just_released("ui_accept"): #Player is jumping 
		velocity += Vector2.UP * (-9.81) * (lowJumpMultiplier) #Jump Height depends on how long you will hold key

	if is_on_floor():
		if Input.is_action_just_pressed("ui_accept"): 
			velocity = Vector2.UP * jumpVelocity #Normal Jump action
	velocity = move_and_slide(velocity, Vector2(0,-1))	

I’m also adding download for the project so u can see how it works in my case of use. better Jump.rar - Google Drive

BlumiDev | 2019-06-07 14:43

Thank you,

It definitely helped me, i made some improvements to it and it worked perfectly

extends KinematicBody2D

export var fall_gravity_scale := 150.0
export var low_jump_gravity_scale := 100.0
export var jump_power := 500.0
var jump_released = false

var velocity = Vector2()
var earth_gravity = 9.807 # m/s^2
export var gravity_scale := 100.0
var on_floor = false

func _physics_process(delta):
	if Input.is_action_just_released("ui_accept"):
		jump_released = true

	#Applying gravity to player
	velocity += Vector2.DOWN * earth_gravity * gravity_scale * delta
	#Jump Physics
	if velocity.y > 0: #Player is falling
		#Falling action is faster than jumping action | Like in mario
		#On falling we apply a second gravity to the player
		#We apply ((gravity_scale + fall_gravity_scale) * earth_gravity) gravity on the player
		velocity += Vector2.DOWN * earth_gravity * fall_gravity_scale * delta 

	elif velocity.y < 0 && jump_released: #Player is jumping 
		#Jump Height depends on how long you will hold key
		#If we release the jump before reaching the max height 
		#We apply ((gravity_scale + low_jump_gravity_scale) * earth_gravity) gravity on the player
		#It result on a lower jump
		velocity += Vector2.DOWN * earth_gravity * low_jump_gravity_scale * delta

	if on_floor:
		if Input.is_action_just_pressed("ui_accept"): 
			velocity = Vector2.UP * jump_power #Normal Jump action
			jump_released = false
	velocity = move_and_slide(velocity, Vector2.UP) 
	if is_on_floor(): on_floor = true
	else: on_floor = false

khalidx21 | 2019-08-05 17:52