fix: improved spring behavior

This commit is contained in:
Jakob Feldmann 2024-01-19 16:03:32 +01:00
parent bfe0805377
commit 71b7448626

View File

@ -12,14 +12,19 @@ var y_velocity = 0
var friction = 0.91 var friction = 0.91
# TODO Only store velocity coming to the springs orientation # TODO Only store velocity coming to the springs orientation
var stored_incoming_velocity = 0 var stored_incoming_velocity = 0
var coupled_body = null var coupled_body_ref = weakref(null)
var shock_ready = true var shock_ready = true
var spring_sound_armed = false
func _ready() -> void: func _ready() -> void:
start_y = self.position.y start_y = self.position.y
func coupled_body():
return coupled_body_ref.get_ref()
# TODO Limit spring deformation # TODO Limit spring deformation
@ -31,16 +36,14 @@ func _physics_process(delta: float) -> void:
_Kinematic_Body_on_Spring() _Kinematic_Body_on_Spring()
var spring_force = spring_k * (self.start_y - self.position.y) var spring_force = spring_k * (self.start_y - self.position.y)
if coupled_body != null: if coupled_body() != null:
coupled_mass = mass + coupled_body.mass coupled_mass = mass + coupled_body().mass
else: else:
coupled_mass = mass coupled_mass = mass
var weight_force = coupled_mass * PhysicsConst.gravity var weight_force = coupled_mass * PhysicsConst.gravity
var result_force = weight_force + spring_force var result_force = weight_force + spring_force
y_velocity = PhysicsFunc.two_step_euler( y_velocity = PhysicsFunc.two_step_euler(y_velocity, result_force, coupled_mass, delta)
y_velocity, result_force, coupled_mass, delta
)
y_velocity *= friction y_velocity *= friction
@ -50,20 +53,21 @@ func _physics_process(delta: float) -> void:
func _body_contact() -> 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()):
coupled_body = areas[i].get_parent() if !areas[i].get_parent().is_class("PhysicsBody2D"):
continue
if !areas[i].get_parent().is_on_floor():
return false
coupled_body_ref = weakref(areas[i].get_parent())
return true return true
coupled_body = null
return false return false
func _Kinematic_Body_on_Spring() -> void: func _Kinematic_Body_on_Spring() -> void:
var a_velocity = stored_incoming_velocity var a_velocity = stored_incoming_velocity
var a_mass = coupled_body.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 = 0 stored_incoming_velocity = 0
shock_ready = false shock_ready = false
@ -75,19 +79,22 @@ func _on_SpringSkin_area_exited(_area: Area2D) -> void:
var transferred_kinetic_energy = potential_spring_energy * mass_ratio var transferred_kinetic_energy = potential_spring_energy * mass_ratio
var kinetic_energy_in_velocity = ( var kinetic_energy_in_velocity = (
-sign(displacement) -sign(displacement)
* sqrt( * sqrt(2 * transferred_kinetic_energy / max(coupled_mass - mass, 0.001))
2 * transferred_kinetic_energy / max(coupled_mass - mass, 0.001)
)
) )
if coupled_body != null: if coupled_body() != null:
coupled_body.velocity.y += kinetic_energy_in_velocity coupled_body().velocity.y += kinetic_energy_in_velocity
coupled_body_ref = weakref(null)
spring_sound_armed = true
func _on_EnteringVelocityDetector_area_entered(area: Area2D) -> void: func _on_EnteringVelocityDetector_area_entered(area: Area2D) -> void:
if area.get_parent().velocity.y > 0: if !area.get_parent().is_class("PhysicsBody2D"):
stored_incoming_velocity = area.get_parent().velocity.y return
if area.get_parent().velocity.y > 0:
stored_incoming_velocity = area.get_parent().velocity.y
func _on_EnteringVelocityDetector_area_exited(area: Area2D) -> void: func _on_EnteringVelocityDetector_area_exited(area: Area2D) -> void:
if coupled_body == null: if area.get_parent().is_class("PhysicsBody2D") && spring_sound_armed:
$SpringSound.play() $SpringSound.play()
spring_sound_armed = false