diff --git a/src/Platforms/Spring/SpringPhysics.gd b/src/Platforms/Spring/SpringPhysics.gd index 61c2076..7626a96 100644 --- a/src/Platforms/Spring/SpringPhysics.gd +++ b/src/Platforms/Spring/SpringPhysics.gd @@ -12,14 +12,19 @@ var y_velocity = 0 var friction = 0.91 # TODO Only store velocity coming to the springs orientation var stored_incoming_velocity = 0 -var coupled_body = null +var coupled_body_ref = weakref(null) var shock_ready = true +var spring_sound_armed = false func _ready() -> void: start_y = self.position.y +func coupled_body(): + return coupled_body_ref.get_ref() + + # TODO Limit spring deformation @@ -31,16 +36,14 @@ func _physics_process(delta: float) -> void: _Kinematic_Body_on_Spring() var spring_force = spring_k * (self.start_y - self.position.y) - if coupled_body != null: - coupled_mass = mass + coupled_body.mass + if coupled_body() != null: + coupled_mass = mass + coupled_body().mass else: coupled_mass = mass var weight_force = coupled_mass * PhysicsConst.gravity var result_force = weight_force + spring_force - y_velocity = PhysicsFunc.two_step_euler( - y_velocity, result_force, coupled_mass, delta - ) + y_velocity = PhysicsFunc.two_step_euler(y_velocity, result_force, coupled_mass, delta) y_velocity *= friction @@ -50,20 +53,21 @@ func _physics_process(delta: float) -> void: func _body_contact() -> bool: var areas: Array = $SpringSkin.get_overlapping_areas() 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 - coupled_body = null return false func _Kinematic_Body_on_Spring() -> void: 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_mass = mass - y_velocity += PhysicsFunc.complete_unelastic_shock( - a_velocity, b_velocity, a_mass, b_mass - ) + y_velocity += PhysicsFunc.complete_unelastic_shock(a_velocity, b_velocity, a_mass, b_mass) stored_incoming_velocity = 0 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 kinetic_energy_in_velocity = ( -sign(displacement) - * sqrt( - 2 * transferred_kinetic_energy / max(coupled_mass - mass, 0.001) - ) + * sqrt(2 * transferred_kinetic_energy / max(coupled_mass - mass, 0.001)) ) - if coupled_body != null: - coupled_body.velocity.y += kinetic_energy_in_velocity + if coupled_body() != null: + 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: - if area.get_parent().velocity.y > 0: - stored_incoming_velocity = area.get_parent().velocity.y + if !area.get_parent().is_class("PhysicsBody2D"): + return + if area.get_parent().velocity.y > 0: + stored_incoming_velocity = area.get_parent().velocity.y func _on_EnteringVelocityDetector_area_exited(area: Area2D) -> void: - if coupled_body == null: - $SpringSound.play() + if area.get_parent().is_class("PhysicsBody2D") && spring_sound_armed: + $SpringSound.play() + spring_sound_armed = false