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:
parent
1b7b6acd09
commit
6bf50d1bab
@ -61,7 +61,7 @@ func calculate_grounded_velocity(
|
|||||||
velocity_direction = -1.0
|
velocity_direction = -1.0
|
||||||
|
|
||||||
# Stopping movement
|
# Stopping movement
|
||||||
if direction.x == 0.0:
|
if is_equal_approx(direction.x, 0):
|
||||||
var deceleration_force = calculate_deceleration_force(
|
var deceleration_force = calculate_deceleration_force(
|
||||||
_gravity, mass, delta
|
_gravity, mass, delta
|
||||||
)
|
)
|
||||||
@ -147,10 +147,10 @@ func is_touching_wall_completely() -> bool:
|
|||||||
|
|
||||||
|
|
||||||
# TODO Player gets stuck to a wall easily
|
# TODO Player gets stuck to a wall easily
|
||||||
|
# Attached to wall state is in the PlayerStateMachine
|
||||||
func is_correct_walljump_input(direction: Vector2) -> bool:
|
func is_correct_walljump_input(direction: Vector2) -> bool:
|
||||||
return (
|
return (
|
||||||
is_touching_wall_completely()
|
Input.is_action_pressed("jump")
|
||||||
&& Input.is_action_just_pressed("jump")
|
|
||||||
&& abs(direction.x + wall_touch_direction) < 1
|
&& abs(direction.x + wall_touch_direction) < 1
|
||||||
&& abs(direction.x + wall_touch_direction) >= 0
|
&& abs(direction.x + wall_touch_direction) >= 0
|
||||||
)
|
)
|
||||||
@ -190,17 +190,13 @@ func calculate_jump_velocity(
|
|||||||
)
|
)
|
||||||
linear_velocity.y = (
|
linear_velocity.y = (
|
||||||
((acceleration_force[state].y + additive_jump_force) / mass)
|
((acceleration_force[state].y + additive_jump_force) / mass)
|
||||||
|
* delta
|
||||||
* -1
|
* -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"):
|
if !Input.is_action_pressed("jump"):
|
||||||
# TODO This is so good not gonna lie
|
# TODO This is so good not gonna lie
|
||||||
|
# Smooth transition from jumping to falling
|
||||||
if velocity.y > _gravity * delta * 10:
|
if velocity.y > _gravity * delta * 10:
|
||||||
linear_velocity.y += _gravity * delta * 10
|
linear_velocity.y += _gravity * delta * 10
|
||||||
else:
|
else:
|
||||||
@ -213,11 +209,15 @@ func calculate_jump_velocity(
|
|||||||
linear_velocity.y += _gravity * delta
|
linear_velocity.y += _gravity * delta
|
||||||
|
|
||||||
# TODO Dis shizzle buggy
|
# TODO Dis shizzle buggy
|
||||||
if velocity.x == 0:
|
if is_equal_approx(velocity.x, 0):
|
||||||
linear_velocity.x += inair_velocity * direction.x
|
linear_velocity.x += inair_velocity * direction.x
|
||||||
|
|
||||||
if is_correct_airstrafe_input() && !walljumping:
|
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
|
air_strafe_charges -= 1
|
||||||
|
|
||||||
return linear_velocity
|
return linear_velocity
|
||||||
@ -229,16 +229,24 @@ func calculate_fall_velocity(
|
|||||||
linear_velocity: Vector2, delta: float, direction: Vector2
|
linear_velocity: Vector2, delta: float, direction: Vector2
|
||||||
) -> Vector2:
|
) -> Vector2:
|
||||||
if velocity.y < max_velocity["fall"]:
|
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:
|
else:
|
||||||
linear_velocity.y = max_velocity["fall"]
|
linear_velocity.y = max_velocity["fall"]
|
||||||
if velocity.x == 0:
|
if is_equal_approx(velocity.x, 0):
|
||||||
# TODO this is weird
|
# TODO this is weird
|
||||||
linear_velocity.x += inair_velocity * direction.x
|
linear_velocity.x += inair_velocity * direction.x
|
||||||
if Input.is_action_just_pressed("jump"):
|
if Input.is_action_just_pressed("jump"):
|
||||||
jump_buffer_filled = true
|
jump_buffer_filled = true
|
||||||
if is_correct_airstrafe_input():
|
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
|
air_strafe_charges -= 1
|
||||||
return linear_velocity
|
return linear_velocity
|
||||||
|
|
||||||
@ -248,14 +256,31 @@ func calculate_wallslide_velocity(
|
|||||||
) -> Vector2:
|
) -> Vector2:
|
||||||
# Walljump mechanics
|
# Walljump mechanics
|
||||||
if is_correct_walljump_input(direction):
|
if is_correct_walljump_input(direction):
|
||||||
|
print("should walljump")
|
||||||
# TODO This +0.01 indicates a larger problem with division through possible 0 values!!
|
# 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 += (
|
linear_velocity.y += (
|
||||||
(acceleration_force["walljump"].y / mass)
|
(acceleration_force["walljump"].y / mass)
|
||||||
* -1
|
* -1
|
||||||
|
* delta
|
||||||
* multiplicator
|
* 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:
|
else:
|
||||||
linear_velocity.y += _gravity * delta * 0.4
|
linear_velocity.y += _gravity * delta * 0.4
|
||||||
# linear_velocity.x += inair_velocity * direction.x
|
# linear_velocity.x += inair_velocity * direction.x
|
||||||
|
|||||||
@ -16,13 +16,14 @@ var velocity_jump_boost_ratio := 0.1967
|
|||||||
var init_acceleration_force := {
|
var init_acceleration_force := {
|
||||||
"idle_walk": 4181, "idle_run": 5765, "walk_run": 1000
|
"idle_walk": 4181, "idle_run": 5765, "walk_run": 1000
|
||||||
}
|
}
|
||||||
|
# Oriented around deltas of 0.0166666...s
|
||||||
# newtonmeters is the unit
|
# newtonmeters is the unit
|
||||||
var acceleration_force := {
|
var acceleration_force := {
|
||||||
"walk": Vector2(2000, 1800),
|
"walk": Vector2(2000, 108000),
|
||||||
"idle": Vector2(2000, 1800),
|
"idle": Vector2(2000, 108000),
|
||||||
"run": Vector2(2000, 1800),
|
"run": Vector2(2000, 108000),
|
||||||
"walljump": Vector2(130, 1800),
|
"walljump": Vector2(7800, 108000),
|
||||||
"air_strafe": Vector2(60, 0)
|
"air_strafe": Vector2(4800, 0)
|
||||||
}
|
}
|
||||||
var _gravity: float = PhysicsConst.gravity
|
var _gravity: float = PhysicsConst.gravity
|
||||||
# Kilograms
|
# Kilograms
|
||||||
|
|||||||
@ -98,7 +98,7 @@ func get_horizontal_direction() -> Vector2:
|
|||||||
|
|
||||||
|
|
||||||
# Determines which state should be active at the moment
|
# Determines which state should be active at the moment
|
||||||
func _get_transition(delta):
|
func _get_transition(_delta):
|
||||||
parent.get_node("StateLabel").text = (
|
parent.get_node("StateLabel").text = (
|
||||||
self.state
|
self.state
|
||||||
+ " x vel:"
|
+ " x vel:"
|
||||||
|
|||||||
@ -2,36 +2,43 @@ extends Node2D
|
|||||||
const PhysicsFunc = preload("res://src/Utilities/Physic/PhysicsFunc.gd")
|
const PhysicsFunc = preload("res://src/Utilities/Physic/PhysicsFunc.gd")
|
||||||
const PhysicsConst = preload("res://src/Utilities/Physic/PhysicsConst.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 mass = 1
|
||||||
var spring_k = -500
|
var spring_k = -1000
|
||||||
var start_y = 0
|
var start_y = 0
|
||||||
var y_velocity = 0
|
var y_velocity = 0
|
||||||
var friction = 0.91
|
var friction = 0.91
|
||||||
var stored_incoming_velocity = 0
|
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:
|
func _ready() -> void:
|
||||||
start_y = self.position.y
|
start_y = self.position.y
|
||||||
|
|
||||||
|
|
||||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
func _physics_process(delta: float) -> void:
|
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 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
|
var result_force = weight_force + spring_force
|
||||||
y_velocity += PhysicsFunc.convert_force_to_velocity(
|
y_velocity += PhysicsFunc.convert_force_to_velocity(
|
||||||
result_force, mass, delta
|
result_force, total_mass, delta
|
||||||
)
|
)
|
||||||
|
|
||||||
y_velocity *= friction
|
y_velocity *= friction
|
||||||
|
|
||||||
self.position.y += y_velocity * delta
|
self.position.y += y_velocity * delta
|
||||||
if !_if_do_bounce():
|
|
||||||
_store_incoming_velocity()
|
|
||||||
|
|
||||||
|
|
||||||
# TODO this works against the physics process
|
# TODO this works against the physics process
|
||||||
@ -39,27 +46,27 @@ func _store_incoming_velocity():
|
|||||||
var areas: Array = $EnteringVelocityDetector.get_overlapping_areas()
|
var areas: Array = $EnteringVelocityDetector.get_overlapping_areas()
|
||||||
for i in range(0, areas.size()):
|
for i in range(0, areas.size()):
|
||||||
if areas[i].name == "BlobbySkin":
|
if areas[i].name == "BlobbySkin":
|
||||||
print_debug(stored_incoming_velocity)
|
|
||||||
if areas[i].get_parent().velocity.y != 0:
|
if areas[i].get_parent().velocity.y != 0:
|
||||||
stored_incoming_velocity = areas[i].get_parent().velocity.y
|
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()
|
var areas: Array = $SpringSkin.get_overlapping_areas()
|
||||||
for i in range(0, areas.size()):
|
for i in range(0, areas.size()):
|
||||||
if areas[i].name == "BlobbySkin":
|
if areas[i].name == "BlobbySkin":
|
||||||
_Kinematic_Body_on_Spring(areas[i])
|
coupled_body = areas[i].get_parent()
|
||||||
return true
|
return true
|
||||||
|
coupled_body = null
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
|
||||||
func _Kinematic_Body_on_Spring(area: Area2D) -> void:
|
func _Kinematic_Body_on_Spring() -> void:
|
||||||
var area_parent = area.get_parent()
|
|
||||||
var a_velocity = stored_incoming_velocity
|
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_velocity = y_velocity
|
||||||
var b_mass = mass
|
var b_mass = mass
|
||||||
y_velocity += PhysicsFunc.complete_unelastic_shock(
|
y_velocity += PhysicsFunc.complete_unelastic_shock(
|
||||||
a_velocity, b_velocity, a_mass, b_mass
|
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
|
||||||
|
|||||||
@ -4,13 +4,13 @@
|
|||||||
[ext_resource path="res://assets/environment/blocks/Basic stone block.png" type="Texture" id=2]
|
[ext_resource path="res://assets/environment/blocks/Basic stone block.png" type="Texture" id=2]
|
||||||
|
|
||||||
[sub_resource type="RectangleShape2D" 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]
|
[sub_resource type="RectangleShape2D" id=1]
|
||||||
extents = Vector2( 11.9386, 1.57982 )
|
extents = Vector2( 11.9386, 1.57982 )
|
||||||
|
|
||||||
[sub_resource type="RectangleShape2D" id=3]
|
[sub_resource type="RectangleShape2D" id=3]
|
||||||
extents = Vector2( 11.4, 1.42384 )
|
extents = Vector2( 11.4, 0.878017 )
|
||||||
|
|
||||||
[node name="Spring" type="Node2D"]
|
[node name="Spring" type="Node2D"]
|
||||||
script = ExtResource( 1 )
|
script = ExtResource( 1 )
|
||||||
@ -24,6 +24,7 @@ collision_layer = 32
|
|||||||
collision_mask = 3
|
collision_mask = 3
|
||||||
|
|
||||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="SpringSkin"]
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="SpringSkin"]
|
||||||
|
position = Vector2( 0, -0.25779 )
|
||||||
shape = SubResource( 2 )
|
shape = SubResource( 2 )
|
||||||
|
|
||||||
[node name="SpringBody" type="KinematicBody2D" parent="."]
|
[node name="SpringBody" type="KinematicBody2D" parent="."]
|
||||||
@ -39,4 +40,5 @@ collision_layer = 32
|
|||||||
collision_mask = 41
|
collision_mask = 41
|
||||||
|
|
||||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="EnteringVelocityDetector"]
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="EnteringVelocityDetector"]
|
||||||
|
position = Vector2( 0, 0.629961 )
|
||||||
shape = SubResource( 3 )
|
shape = SubResource( 3 )
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user