Movement accelerations use two step euler method

This commit is contained in:
Jakob Feldmann 2022-05-29 23:29:00 +02:00
parent 6bf50d1bab
commit 8d92d285d9
4 changed files with 75 additions and 85 deletions

View File

@ -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

View File

@ -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

View File

@ -1 +1 @@
const gravity: float = 1111.0
const gravity: float = 700.0

View File

@ -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