#Advanced Physics of Jump

25 messages · Page 1 of 1 (latest)

lucid shale
#

Seeking Physics experts advice:

I have toyed around with the formulae for fixing JUMP_FORCE of my 2D platformer Character's FiniteStateMachine:

var jump_gravity: float
var jump_force: float

## Code to run when entering state
func enter_state(params: Dictionary = {}) -> void:
    jump_gravity = movement_controller.gravity * movement_controller.jump_gravity_factor
    jump_force = sqrt(2 * jump_gravity * movement_controller.jump_height)
    controlled_body.velocity.y -= jump_force
    controlled_sprite.play("jump")

...
# Somewhere in the _physics_process, I process my desired gravity for the Jump State using:
func process_gravity(delta: float, _controlled_body: CharacterBody2D, _gravity: float) -> void:
    if not _controlled_body.is_on_floor():
        _controlled_body.velocity.y += _gravity * delta

But i realised the issue is, whilst I can control for the jump_height very precisely, it comes at the cost of losing control over the jump air-time.

I would like to know if I can control both the Jump Height & Jump Airtime (time it takes for the Jump Force to wear off by gravity till it reaches peak of jump).

I can control for Jump_gravity and Delta in my Jump State.

woeful tree
#

Do you know about the formulas for projectile motion?

#

I think the one that would be relevant for you is:

y = y_0 + v_0 ∙ t + 0.5 ∙ a ∙ t²

t: the time since the projectile left the ground
y: the height of the projectile at time t
y_0: the starting height (is probably just 0 in your case)
v_0: the starting velocity (in the y direction)
a: the acceleration due to gravity

#

This formula produces a parabola. So if you want to find the max height, it will be the vertex of the parabola:

#

t_max = -v_0 / (2 ∙ (0.5 ∙ a))
= -v_0 / a where t_max is the time at which the projectile reaches the max height

#

y_max = y_0 + v_0 ∙ (t_max) + 0.5 ∙ a ∙ (t_max)²

#

If we assume that y_0 = 0, then we can simplify and solve for y_max:

#

y_max = v_0 ∙ (-v_0 / a) + 0.5 ∙ a ∙ (-v_0 / a)²
= -v_0² / a + v_0² / (2 ∙ a)
= -v_0² / (2 ∙ a)

#

You can also find the air time by solving for when y = 0 (again, i'll assume that the starting height y_0 = 0 so that i can take it out of the equation):

#

y = v_0 ∙ t + 0.5 ∙ a ∙ t²
= 0

#

So:

#

v_0 ∙ t + 0.5 ∙ a ∙ t² = 0
t ∙ (v_0 + 0.5 ∙ a ∙ t) = 0

#

This means either t = 0 or v_0 + 0.5 ∙ a ∙ t = 0. We know t = 0 at the start of the jump, so that's NOT the air time

#

The other one should give us the air time if we solve for t:
v_0 + 0.5 ∙ a ∙ t = 0
0.5 ∙ a ∙ t = -v_0
t = -v_0 / (0.5 ∙ a)
t = -2 ∙ v_0 / a

#

So we have two equations, one for max height and one for air time:

y_max = -v_0² / (2 ∙ a)

t_airtime = -2 ∙ v_0 / a

#

Essentially, you want to reverse these relationships so that you can set y_max and t_airtime to whatever values you want and then calculate v_0 and a from that

#

To do this, you'll need to take these equations and then solve for v_0 and a in terms of y_max and t_airtime

#

I have to leave now, but if i have time later, i can try to come back and finish up the solution

woeful tree
#

Okay, so solving for v_0 and a gives:

v_0 = 4 ∙ y_max / t_airtime

a = -8 ∙ y_max / t_airtime²

#

One note: the air time i solved for is the total time that the object would be in the air, assuming it falls back down and hits the ground at the same place that it left from. If you want the time to the top of the jump, it would be half of the time i solved for

lucid shale
#

Hi @woeful tree First off, I just want to say a huge thank you for taking so much time to answer comprehensively!!

#

in the TLDR, the author provided 2 statements:

  • gravity = H/2t²
  • jump speed  = sqrt(2Hg)
#

In my FSM jump state, i can control for gravity and desired jump height, so I replaced the respective variables with my preset values to get the Jump velocity to apply

extends MovementState

var jump_gravity: float
var jump_force: float

## Code to run when entering state
func enter_state(_params: Dictionary = {}) -> void:
    jump_gravity = movement_controller.jump_height / (2 * movement_controller.jump_airtime**2)
    jump_force = sqrt(2 * movement_controller.jump_height * jump_gravity)
    controlled_body.velocity.y -= jump_force