Mega Man 2 Jump in Godot (Holding jump button gets higher jump, tapping is 100% same height)

Attention Topic was automatically imported from the old Question2Answer platform.

So, I’ve been struggling with making a good jump function in GDScript. I used the Dynamic 2d Demo, and it works, but feels quite awful.

Does anyone have a good example of a jump that when you tap the button is a 100% the same height, and if you hold the button down, it goes higher until it reaches a set max height? Kind of like how it works in Mega Man 2.

``````# Variables
const VEC2GRAVITY = Vector2(0, 1400);
const VEC2FLOORNORMAL = Vector2(0, -1);
const FSLOPESLIDESTOP = 25.0;
const FMININAIRTIME = 0.001;

# Gravity Function
func plGravity(d):
#increment counters
fInAirTime += d;

# Apply Gravity
if not bJumping:
vec2LinearVelocity += d * VEC2GRAVITY;

# Jump function
func plJump():
if Input.is_action_pressed("Jump"):
if bOnFloor:
bJumping = true;
elif Input.is_action_just_released("Jump"):
bJumping = false;

# Process of jumping
if bJumping:
vec2LinearVelocity.y -= fJumpHeight;

if vec2LinearVelocity.y <= -fJumpMaxHeight:
bJumping = false;

if vec2LinearVelocity.y > 0:
bJumping = false; # This is where we tell that the player has started to fall

# Everything is run in this function
func _physics_process(delta):
plGravity(delta);
plMovement();
plJump();
plState();
``````

Never implemented this myself, but someone asked similar a few days ago: 2D Platformer: How to control jump height | Mario-like jumps - Archive - Godot Forum

Hi! After struggling a little bit, I’ve found a video that helped me to create my own jump. The video is from game maker, but I applied it to godot ^^’

The main concept is:
*You have max height that you character can achieve.
*You have to check if the player is pressing the jump key, then decide if he keep with the “normal jump”
*You have to check if the player just released the jump key, then, “cut” and cancel the jump, exposing him to the gravity again

It need a little refinement, but here is my code commented:

``````extends KinematicBody2D

export (int) var jump_speed = -300   #speed of the jump
export (int) var gravity = 800  #gravity
var jump_pressed #variable that check if the jump key is keep pressed
var jump  #variable that check if the jump key is just pressed
var jump_cut # variable that check if jump button is just released

#direction states
var right
var left

#velocity vector
var velocity = Vector2()

func get_input():
velocity.x = 0
right = Input.is_action_pressed('ui_right')
left = Input.is_action_pressed('ui_left')
jump_pressed = Input.is_action_pressed('ui_select') #jump button is keep pressed
jump_cut = Input.is_action_just_released('ui_select')  #jump button just released
jump = Input.is_action_just_pressed('ui_select')   #jump button is just pressed

if jump && is_on_floor():  # check if the jump button is just pressed and if the player is on the floor
jump() # call jump method
if velocity.y < 0 && !jump_pressed: # here is the deal: if the jump button is not keep pressed anymore, the y velocity is set to 0 and the player don't go up anymore
velocity.y = 0

if right:
velocity.x += run_speed
if left:
velocity.x -= run_speed

func jump():
velocity.y = jump_speed

#func change_direction_sprite():
#	if right:
#		\$Sprite.flip_h = false
#	elif left:
#		\$Sprite.flip_h = true

func _physics_process(delta):
get_input()
velocity.y += gravity * delta # gravity
velocity = move_and_slide(velocity, Vector2(0, -1))
#change_direction_sprite()
``````

I hope it helps! My jump works just fine

So I made this mario-like jump, but I can see it will work with your idea. I know it’s old post but other people may find it useful. Just change variables in code to see what works for you. If you want to set jump to 100% value just edit var jumpVelocity and fiddle around with lowJumpMultiplier.

``````extends KinematicBody2D

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

#Physics
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:44

Say, thanks for contributing. This may come in handy one of these days.

Ertain | 2019-06-07 20:31

Hello. Godot newbie here.

Not exactly like what you asked (you wanted a maximum height). But I added these lines and it seems to work fine as far as holding it to give it more power is concerned

``````var hold_jump_power = 3
``````

and then inside _physics_process(delta), add:

``````if Input.is_action_pressed("Jump") and velocity.y < 0 :
velocity.y -= hold_jump_power
``````

That just says if you’re holding the jump button and you’re going up, it adds a little more acceleration going up. You’ll have to tweak it a little so that you can’t let the button go and hold it again. You need the “and velocity.y < 0” to prevent slowing your fall. But if you ever need some sort of glide mechanic when you fall, that’s an idea.

Adjust hold_jump_power to your liking, but if it’s too high compared to gravity, you’ll go up forever and ever with the button held down.

This is actually a very good answer, and since it is the simplest, I personally feel it should be the top answer. It also gives a nice slow-fall effect that I quite like that the other solutions do not.

Kyllingene | 2021-05-11 01:19

For me this comes pretty close to the jump in Mega Man 9:

``````export (int) var jump_speed = -400
export (int) var gravity = 1200

var jumping = false

func _physics_process(delta):
if Input.is_action_just_pressed('jump') and is_on_floor():
jumping = true
velocity.y = jump_speed

if jumping and Input.is_action_just_released("jump"):
if velocity.y < -50:
velocity.y = -50

velocity.y += gravity * delta

velocity = move_and_slide(velocity, Vector2.UP)

if jumping and is_on_floor():
jumping = false
``````

Thanks for this answer! I was just looking at this again, and this one feels really nice!

TobiasDev | 2020-07-31 09:06