Movement accelerations use two step euler method
This commit is contained in:
parent
6bf50d1bab
commit
8d92d285d9
@ -60,53 +60,42 @@ func calculate_grounded_velocity(
|
||||
if velocity.x < 0:
|
||||
velocity_direction = -1.0
|
||||
|
||||
# Stopping movement
|
||||
var deceleration_force = calculate_deceleration_force(_gravity, mass)
|
||||
|
||||
# Slowing down movement when not controlling direction
|
||||
if is_equal_approx(direction.x, 0):
|
||||
var deceleration_force = calculate_deceleration_force(
|
||||
_gravity, mass, delta
|
||||
out_vel.x = PhysicsFunc.two_step_euler(
|
||||
out_vel.x, deceleration_force * -1 * velocity_direction, mass, delta
|
||||
)
|
||||
# Translates velocity back to force and subtracts deceleration force
|
||||
var result_force = (
|
||||
abs(PhysicsFunc.convert_velocity_to_force(velocity.x, mass, delta))
|
||||
- deceleration_force
|
||||
)
|
||||
if result_force <= 0:
|
||||
if abs(out_vel.x) > abs(velocity.x):
|
||||
out_vel.x = 0
|
||||
else:
|
||||
out_vel.x = (
|
||||
PhysicsFunc.convert_force_to_velocity(result_force, mass, delta)
|
||||
* velocity_direction
|
||||
)
|
||||
else:
|
||||
# Reversing movement
|
||||
# When turning the opposite direction, friction is added to the opposite acceleration movement
|
||||
var reverse_move = is_reversing_horizontal_movement(direction)
|
||||
if reverse_move:
|
||||
out_vel.x -= (
|
||||
PhysicsFunc.convert_force_to_velocity(
|
||||
calculate_deceleration_force(_gravity, mass, delta),
|
||||
mass,
|
||||
delta
|
||||
)
|
||||
* velocity_direction
|
||||
out_vel.x = PhysicsFunc.two_step_euler(
|
||||
out_vel.x,
|
||||
deceleration_force * -1.66 * velocity_direction,
|
||||
mass,
|
||||
delta
|
||||
)
|
||||
# Normal movement
|
||||
if abs(velocity.x) < max_velocity[state]:
|
||||
out_vel.x += (
|
||||
delta
|
||||
* (
|
||||
out_vel.x = PhysicsFunc.two_step_euler(
|
||||
out_vel.x,
|
||||
(
|
||||
(
|
||||
(
|
||||
acceleration_force[state].x
|
||||
+ (
|
||||
init_acceleration_force[init_boost_type]
|
||||
* int(init_boost)
|
||||
)
|
||||
acceleration_force[state].x
|
||||
+ (
|
||||
init_acceleration_force[init_boost_type]
|
||||
* int(init_boost)
|
||||
)
|
||||
/ mass
|
||||
)
|
||||
* direction.x
|
||||
)
|
||||
),
|
||||
mass,
|
||||
delta
|
||||
)
|
||||
elif !reverse_move:
|
||||
out_vel.x = max_velocity[state] * direction.x
|
||||
@ -123,6 +112,8 @@ func calculate_grounded_velocity(
|
||||
return out_vel
|
||||
|
||||
|
||||
# Determines if the player has reversed the steering direction
|
||||
# in reference to the current movement direction
|
||||
func is_reversing_horizontal_movement(direction: Vector2) -> bool:
|
||||
return (
|
||||
(direction.x > 0 && velocity.x < 0)
|
||||
@ -166,11 +157,9 @@ func is_correct_airstrafe_input() -> bool:
|
||||
)
|
||||
|
||||
|
||||
# TODO Comments for parameters
|
||||
func calculate_deceleration_force(
|
||||
_gravity: float, mass: float, delta: float
|
||||
) -> float:
|
||||
return normal_floor_friction * _gravity * mass * delta
|
||||
# Calculates the force of the ground friction
|
||||
func calculate_deceleration_force(_gravity: float, mass: float) -> float:
|
||||
return normal_floor_friction * _gravity * mass
|
||||
|
||||
|
||||
func calculate_jump_velocity(
|
||||
@ -188,10 +177,11 @@ func calculate_jump_velocity(
|
||||
* abs(velocity.x)
|
||||
* mass
|
||||
)
|
||||
linear_velocity.y = (
|
||||
((acceleration_force[state].y + additive_jump_force) / mass)
|
||||
* delta
|
||||
* -1
|
||||
linear_velocity.y = PhysicsFunc.two_step_euler(
|
||||
0,
|
||||
(acceleration_force[state].y + additive_jump_force) * -1,
|
||||
mass,
|
||||
delta
|
||||
)
|
||||
|
||||
if !Input.is_action_pressed("jump"):
|
||||
@ -213,10 +203,11 @@ func calculate_jump_velocity(
|
||||
linear_velocity.x += inair_velocity * direction.x
|
||||
|
||||
if is_correct_airstrafe_input() && !walljumping:
|
||||
linear_velocity.x += (
|
||||
direction.x
|
||||
* acceleration_force["air_strafe"].x
|
||||
* delta
|
||||
linear_velocity.x = PhysicsFunc.two_step_euler(
|
||||
linear_velocity.x,
|
||||
acceleration_force["air_strafe"].x * direction.x,
|
||||
mass,
|
||||
delta
|
||||
)
|
||||
air_strafe_charges -= 1
|
||||
|
||||
@ -230,10 +221,9 @@ func calculate_fall_velocity(
|
||||
) -> Vector2:
|
||||
if velocity.y < max_velocity["fall"]:
|
||||
# linear_velocity.y += _gravity * delta
|
||||
# Better explicit euler step
|
||||
var step1vel = linear_velocity.y + _gravity * 0.5 * delta
|
||||
var step2vel = step1vel + _gravity * 0.5 * delta
|
||||
linear_velocity.y = step2vel
|
||||
linear_velocity.y = PhysicsFunc.two_step_euler(
|
||||
linear_velocity.y, _gravity * mass, mass, delta
|
||||
)
|
||||
else:
|
||||
linear_velocity.y = max_velocity["fall"]
|
||||
if is_equal_approx(velocity.x, 0):
|
||||
@ -242,10 +232,11 @@ func calculate_fall_velocity(
|
||||
if Input.is_action_just_pressed("jump"):
|
||||
jump_buffer_filled = true
|
||||
if is_correct_airstrafe_input():
|
||||
linear_velocity.x += (
|
||||
direction.x
|
||||
* acceleration_force["air_strafe"].x
|
||||
* delta
|
||||
linear_velocity.x = PhysicsFunc.two_step_euler(
|
||||
linear_velocity.x,
|
||||
acceleration_force["air_strafe"].x * direction.x,
|
||||
mass,
|
||||
delta
|
||||
)
|
||||
air_strafe_charges -= 1
|
||||
return linear_velocity
|
||||
@ -256,34 +247,22 @@ func calculate_wallslide_velocity(
|
||||
) -> Vector2:
|
||||
# Walljump mechanics
|
||||
if is_correct_walljump_input(direction):
|
||||
print("should walljump")
|
||||
# TODO This +0.01 indicates a larger problem with division through possible 0 values!!
|
||||
var multiplicator = max(
|
||||
min(
|
||||
1,
|
||||
(
|
||||
acceleration_force["walljump"].y
|
||||
/ (((velocity.y / delta) / mass) + 0.01)
|
||||
)
|
||||
),
|
||||
0.7
|
||||
linear_velocity.y = PhysicsFunc.two_step_euler(
|
||||
linear_velocity.y,
|
||||
acceleration_force["walljump"].y * -1,
|
||||
mass,
|
||||
delta
|
||||
)
|
||||
print_debug(multiplicator)
|
||||
linear_velocity.y += (
|
||||
(acceleration_force["walljump"].y / mass)
|
||||
* -1
|
||||
* delta
|
||||
* multiplicator
|
||||
linear_velocity.x += PhysicsFunc.two_step_euler(
|
||||
linear_velocity.x,
|
||||
acceleration_force["walljump"].x * direction.x,
|
||||
mass,
|
||||
delta
|
||||
)
|
||||
linear_velocity.x += (
|
||||
acceleration_force["walljump"].x
|
||||
* delta
|
||||
* direction.x
|
||||
)
|
||||
print_debug(linear_velocity)
|
||||
else:
|
||||
linear_velocity.y += _gravity * delta * 0.4
|
||||
# linear_velocity.x += inair_velocity * direction.x
|
||||
linear_velocity.y = PhysicsFunc.two_step_euler(
|
||||
linear_velocity.y, _gravity * mass * 0.5, mass, delta
|
||||
)
|
||||
return linear_velocity
|
||||
|
||||
|
||||
|
||||
@ -7,7 +7,8 @@ const FLOOR_NORMAL := Vector2.UP
|
||||
var stomp_feedback := 1000.0
|
||||
var inair_velocity := 21
|
||||
var wallslide_threshold := 300
|
||||
var normal_floor_friction := 28
|
||||
# TODO Map to floor types and move to physics constants
|
||||
var normal_floor_friction := 0.5
|
||||
var max_velocity := {
|
||||
"walk": 120, "run": 160, "fall": 400, "walljump": 150, "idle": 120
|
||||
}
|
||||
@ -19,13 +20,15 @@ var init_acceleration_force := {
|
||||
# Oriented around deltas of 0.0166666...s
|
||||
# newtonmeters is the unit
|
||||
var acceleration_force := {
|
||||
"walk": Vector2(2000, 108000),
|
||||
"idle": Vector2(2000, 108000),
|
||||
"run": Vector2(2000, 108000),
|
||||
"walljump": Vector2(7800, 108000),
|
||||
"air_strafe": Vector2(4800, 0)
|
||||
"walk": Vector2(2000, 68000),
|
||||
"idle": Vector2(2000, 68000),
|
||||
"run": Vector2(2000, 68000),
|
||||
"walljump": Vector2(30000, 58000),
|
||||
"air_strafe": Vector2(20000, 0)
|
||||
}
|
||||
# Gravity as m/s^2
|
||||
var _gravity: float = PhysicsConst.gravity
|
||||
# Mass of Blobby
|
||||
# Kilograms
|
||||
var mass := 6.5
|
||||
|
||||
|
||||
@ -1 +1 @@
|
||||
const gravity: float = 1111.0
|
||||
const gravity: float = 700.0
|
||||
|
||||
@ -10,3 +10,11 @@ static func complete_unelastic_shock(
|
||||
v1: float, v2: float, m1: float, m2: float
|
||||
) -> float:
|
||||
return (m1 * v1 + m2 * v2) / (m1 + m2)
|
||||
|
||||
|
||||
# Explicit euler method looking one step into the future
|
||||
# Returns the mean velocity of applying the force two times
|
||||
static func two_step_euler(v0, force, mass, delta) -> float:
|
||||
var v1 = v0 + force / mass * delta
|
||||
var v2 = v1 + force / mass * delta
|
||||
return (v1 + v2) / 2
|
||||
|
||||
Loading…
Reference in New Issue
Block a user