Jump forces, smoother falling, ez walljumps

The jump velocity is not calculated on a one second basis anymore.
Instead the 60hz physics ticks are
the new reference for the jump force constants.
This is to unify the calculation of velocities in the blobby class.

Walljumps are now easier.
A just pressed jump event was changed to a pressed jump event.
This means the player can walljump,
with pressing a direction while sliding down a wall and keeping jump pressed.

Falling was smoothed out with a slightly and naivly improved euler method.

Also the spring is being experimented on.
This commit is contained in:
Jakob Feldmann 2022-05-28 16:10:33 +02:00
parent 1b7b6acd09
commit 6bf50d1bab
5 changed files with 75 additions and 40 deletions

View File

@ -61,7 +61,7 @@ func calculate_grounded_velocity(
velocity_direction = -1.0
# Stopping movement
if direction.x == 0.0:
if is_equal_approx(direction.x, 0):
var deceleration_force = calculate_deceleration_force(
_gravity, mass, delta
)
@ -147,10 +147,10 @@ func is_touching_wall_completely() -> bool:
# TODO Player gets stuck to a wall easily
# Attached to wall state is in the PlayerStateMachine
func is_correct_walljump_input(direction: Vector2) -> bool:
return (
is_touching_wall_completely()
&& Input.is_action_just_pressed("jump")
Input.is_action_pressed("jump")
&& abs(direction.x + wall_touch_direction) < 1
&& abs(direction.x + wall_touch_direction) >= 0
)
@ -190,17 +190,13 @@ func calculate_jump_velocity(
)
linear_velocity.y = (
((acceleration_force[state].y + additive_jump_force) / mass)
* delta
* -1
)
# TODO Das eskaliert ab und an komplett
if walljumping && !is_on_floor():
# The faster you are moving up the farther the walljump goes
linear_velocity.y = (acceleration_force["walljump"].y / mass) * -1
linear_velocity.x += acceleration_force["walljump"].x * direction.x
if !Input.is_action_pressed("jump"):
# TODO This is so good not gonna lie
# Smooth transition from jumping to falling
if velocity.y > _gravity * delta * 10:
linear_velocity.y += _gravity * delta * 10
else:
@ -213,11 +209,15 @@ func calculate_jump_velocity(
linear_velocity.y += _gravity * delta
# TODO Dis shizzle buggy
if velocity.x == 0:
if is_equal_approx(velocity.x, 0):
linear_velocity.x += inair_velocity * direction.x
if is_correct_airstrafe_input() && !walljumping:
linear_velocity.x += (direction.x * acceleration_force["air_strafe"].x)
linear_velocity.x += (
direction.x
* acceleration_force["air_strafe"].x
* delta
)
air_strafe_charges -= 1
return linear_velocity
@ -229,16 +229,24 @@ func calculate_fall_velocity(
linear_velocity: Vector2, delta: float, direction: Vector2
) -> Vector2:
if velocity.y < max_velocity["fall"]:
linear_velocity.y += _gravity * delta
# 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
else:
linear_velocity.y = max_velocity["fall"]
if velocity.x == 0:
if is_equal_approx(velocity.x, 0):
# TODO this is weird
linear_velocity.x += inair_velocity * direction.x
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)
linear_velocity.x += (
direction.x
* acceleration_force["air_strafe"].x
* delta
)
air_strafe_charges -= 1
return linear_velocity
@ -248,14 +256,31 @@ 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, 1000 / (velocity.y + 0.01)), 0.9)
var multiplicator = max(
min(
1,
(
acceleration_force["walljump"].y
/ (((velocity.y / delta) / mass) + 0.01)
)
),
0.7
)
print_debug(multiplicator)
linear_velocity.y += (
(acceleration_force["walljump"].y / mass)
* -1
* delta
* multiplicator
)
linear_velocity.x += acceleration_force["walljump"].x * direction.x
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

View File

@ -16,13 +16,14 @@ var velocity_jump_boost_ratio := 0.1967
var init_acceleration_force := {
"idle_walk": 4181, "idle_run": 5765, "walk_run": 1000
}
# Oriented around deltas of 0.0166666...s
# newtonmeters is the unit
var acceleration_force := {
"walk": Vector2(2000, 1800),
"idle": Vector2(2000, 1800),
"run": Vector2(2000, 1800),
"walljump": Vector2(130, 1800),
"air_strafe": Vector2(60, 0)
"walk": Vector2(2000, 108000),
"idle": Vector2(2000, 108000),
"run": Vector2(2000, 108000),
"walljump": Vector2(7800, 108000),
"air_strafe": Vector2(4800, 0)
}
var _gravity: float = PhysicsConst.gravity
# Kilograms

View File

@ -98,7 +98,7 @@ func get_horizontal_direction() -> Vector2:
# Determines which state should be active at the moment
func _get_transition(delta):
func _get_transition(_delta):
parent.get_node("StateLabel").text = (
self.state
+ " x vel:"

View File

@ -2,36 +2,43 @@ extends Node2D
const PhysicsFunc = preload("res://src/Utilities/Physic/PhysicsFunc.gd")
const PhysicsConst = preload("res://src/Utilities/Physic/PhysicsConst.gd")
# Declare member variables here. Examples:
# var a: int = 2
# var b: Strin = "text"
var mass = 1
var spring_k = -500
var spring_k = -1000
var start_y = 0
var y_velocity = 0
var friction = 0.91
var stored_incoming_velocity = 0
var coupled_body = null
var shock_ready = true
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
start_y = self.position.y
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _physics_process(delta: float) -> void:
if !_body_contact():
_store_incoming_velocity()
shock_ready = true
if _body_contact() && shock_ready:
_Kinematic_Body_on_Spring()
shock_ready = false
var spring_force = spring_k * (self.position.y - self.start_y)
var weight_force = PhysicsConst.gravity * mass
var total_mass = mass
if coupled_body != null:
total_mass = mass + coupled_body.mass
var weight_force = total_mass * PhysicsConst.gravity
var result_force = weight_force + spring_force
y_velocity += PhysicsFunc.convert_force_to_velocity(
result_force, mass, delta
result_force, total_mass, delta
)
y_velocity *= friction
self.position.y += y_velocity * delta
if !_if_do_bounce():
_store_incoming_velocity()
# TODO this works against the physics process
@ -39,27 +46,27 @@ func _store_incoming_velocity():
var areas: Array = $EnteringVelocityDetector.get_overlapping_areas()
for i in range(0, areas.size()):
if areas[i].name == "BlobbySkin":
print_debug(stored_incoming_velocity)
if areas[i].get_parent().velocity.y != 0:
stored_incoming_velocity = areas[i].get_parent().velocity.y
func _if_do_bounce() -> bool:
func _body_contact() -> bool:
var areas: Array = $SpringSkin.get_overlapping_areas()
for i in range(0, areas.size()):
if areas[i].name == "BlobbySkin":
_Kinematic_Body_on_Spring(areas[i])
coupled_body = areas[i].get_parent()
return true
coupled_body = null
return false
func _Kinematic_Body_on_Spring(area: Area2D) -> void:
var area_parent = area.get_parent()
func _Kinematic_Body_on_Spring() -> void:
var a_velocity = stored_incoming_velocity
var a_mass = area_parent.mass
var a_mass = coupled_body.mass
var b_velocity = y_velocity
var b_mass = mass
y_velocity += PhysicsFunc.complete_unelastic_shock(
a_velocity, b_velocity, a_mass, b_mass
)
stored_incoming_velocity = area_parent.velocity.y
coupled_body.velocity.y = y_velocity
stored_incoming_velocity = 0

View File

@ -4,13 +4,13 @@
[ext_resource path="res://assets/environment/blocks/Basic stone block.png" type="Texture" id=2]
[sub_resource type="RectangleShape2D" id=2]
extents = Vector2( 11.4526, 1.7975 )
extents = Vector2( 11.4526, 1.75208 )
[sub_resource type="RectangleShape2D" id=1]
extents = Vector2( 11.9386, 1.57982 )
[sub_resource type="RectangleShape2D" id=3]
extents = Vector2( 11.4, 1.42384 )
extents = Vector2( 11.4, 0.878017 )
[node name="Spring" type="Node2D"]
script = ExtResource( 1 )
@ -24,6 +24,7 @@ collision_layer = 32
collision_mask = 3
[node name="CollisionShape2D" type="CollisionShape2D" parent="SpringSkin"]
position = Vector2( 0, -0.25779 )
shape = SubResource( 2 )
[node name="SpringBody" type="KinematicBody2D" parent="."]
@ -39,4 +40,5 @@ collision_layer = 32
collision_mask = 41
[node name="CollisionShape2D" type="CollisionShape2D" parent="EnteringVelocityDetector"]
position = Vector2( 0, 0.629961 )
shape = SubResource( 3 )