From 311abfcc6f9c0ba36672f0f49a11b9f0f66b07e5 Mon Sep 17 00:00:00 2001 From: Jakob Feldmann Date: Tue, 4 Jul 2023 13:50:26 +0200 Subject: [PATCH] feat: let blobby ride on frog --- src/Actors/Enemies/Beings/BoundFrog.gd | 74 +++++++-------- src/Actors/Enemies/Beings/WhatAreFrog.gd | 24 ++++- src/Actors/Enemies/Beings/WhatAreFrog.tscn | 1 + src/Platforms/SpringPhysics.gd | 103 ++++++++++----------- 4 files changed, 112 insertions(+), 90 deletions(-) diff --git a/src/Actors/Enemies/Beings/BoundFrog.gd b/src/Actors/Enemies/Beings/BoundFrog.gd index cf698e6..03ea1a4 100644 --- a/src/Actors/Enemies/Beings/BoundFrog.gd +++ b/src/Actors/Enemies/Beings/BoundFrog.gd @@ -12,51 +12,51 @@ var rope var is_first_signal = true func _ready() -> void: - signalManager.connect("level_loaded", self, "_on_level_loaded") + signalManager.connect("level_loaded", self, "_on_level_loaded") func _on_level_loaded() -> void: - rope = Rope.instance() - # For some reason the rope only can be instanced in the parent scene - # The scene also has to be ready beforehand - get_parent().add_child(rope) - rope.rope_end = get_node("RopeAnchor") - rope.rope_start = get_node("WhatAreFrog") - rope.rope_end_joint = get_node("RopeAnchor/cshape/pjoint") - rope.rope_start_joint = get_node("WhatAreFrog/cshape/pjoint") - rope.spawn_rope($WhatAreFrog.global_position, $RopeAnchor.global_position, movement_radius, false) - $WhatAreFrog.tilemap = tilemap - $WhatAreFrog.bind_to_anchor($RopeAnchor, movement_radius) + rope = Rope.instance() + # For some reason the rope only can be instanced in the parent scene + # The scene also has to be ready beforehand + get_parent().add_child(rope) + rope.rope_end = get_node("RopeAnchor") + rope.rope_start = get_node("WhatAreFrog") + rope.rope_end_joint = get_node("RopeAnchor/cshape/pjoint") + rope.rope_start_joint = get_node("WhatAreFrog/cshape/pjoint") + rope.spawn_rope($WhatAreFrog.global_position, $RopeAnchor.global_position, movement_radius, false) + $WhatAreFrog.tilemap = tilemap + $WhatAreFrog.bind_to_anchor($RopeAnchor, movement_radius) # Executes on frog death # The old switchero func _on_WhatAreFrog_child_exiting_tree(_node:Node) -> void: - if(is_first_signal): - disconnect_rope() - is_first_signal = false - else: - pass + if(is_first_signal): + disconnect_rope() + is_first_signal = false + else: + pass func disconnect_rope() -> void: - var anchor = RopeAnchor.instance() - anchor.mode = 0 - add_child(anchor) - anchor.global_position = rope.rope_start_joint.global_position - rope.queue_free() - rope = Rope.instance() - # For some reason the rope only can be instanced in the parent scene - # The scene also has to be ready beforehand - get_parent().add_child(rope) - rope.rope_end = $RopeAnchor - rope.rope_start = anchor - rope.rope_end_joint = $RopeAnchor/cshape/pjoint - rope.rope_start_joint = anchor.get_node("cshape/pjoint") - rope.spawn_rope(anchor.global_position, $RopeAnchor.global_position, movement_radius, false) + var anchor = RopeAnchor.instance() + anchor.mode = 0 + add_child(anchor) + anchor.global_position = rope.rope_start_joint.global_position + rope.queue_free() + rope = Rope.instance() + # For some reason the rope only can be instanced in the parent scene + # The scene also has to be ready beforehand + get_parent().add_child(rope) + rope.rope_end = $RopeAnchor + rope.rope_start = anchor + rope.rope_end_joint = $RopeAnchor/cshape/pjoint + rope.rope_start_joint = anchor.get_node("cshape/pjoint") + rope.spawn_rope(anchor.global_position, $RopeAnchor.global_position, movement_radius, false) func _on_FrogFreeButton_pushed() -> void: - $WhatAreFrog.levelState.frees += 1 - $WhatAreFrog.is_bound = false - $WhatAreFrog/LeashAnchor.visible = false - $WhatAreFrog.remove_from_group("harmful") - disconnect_rope() - is_first_signal = false + $WhatAreFrog.levelState.frees += 1 + $WhatAreFrog.is_bound = false + $WhatAreFrog/LeashAnchor.visible = false + $WhatAreFrog.remove_from_group("harmful") + disconnect_rope() + is_first_signal = false diff --git a/src/Actors/Enemies/Beings/WhatAreFrog.gd b/src/Actors/Enemies/Beings/WhatAreFrog.gd index 9e676b1..7b34094 100644 --- a/src/Actors/Enemies/Beings/WhatAreFrog.gd +++ b/src/Actors/Enemies/Beings/WhatAreFrog.gd @@ -51,6 +51,8 @@ var detect_timer := 0.0 var reversing_possible_searching := true +var attached_player = null + func _ready(): default_jump_distance = default_jump_distance * tilemap.cell_size.x @@ -75,6 +77,9 @@ func bind_to_anchor(anchor_node: Node2D, radius: float ) -> void: func _on_StompDetector_body_entered(body: Node) -> void: + if body.is_in_group("player"): + attached_player = body + $FeelerRayCast.collision_mask -= 1 if !body.is_in_group("player") || is_hurt: return var incoming_vel_vector: Vector2 = body.velocity.normalized() @@ -92,6 +97,10 @@ func _on_StompDetector_body_entered(body: Node) -> void: $FrogSprite.material = invincible_shader $HurtTimer.start() +func _on_StompDetector_body_exited(body: Node) -> void: + if attached_player == body: + $FeelerRayCast.collision_mask += 1 + attached_player = null func execute_movement(delta: float) -> void: # Navigation2DServer.map_get_path() @@ -109,12 +118,15 @@ func execute_movement(delta: float) -> void: velocity.y = velocity.y * 0.8 was_restricted = true velocity = move_and_slide(velocity, FLOOR_NORMAL, false, 4, 0.785398, false) + if(is_on_floor()): velocity = Vector2(0,0) # Reverse direction when hitting limit + + func die() -> void: levelState.kills += 1 queue_free() @@ -298,8 +310,15 @@ func jump(): v = consider_jumping_on_top() if(v == zero_vector && can_reverse_facing_direction()): reverse_facing_direction() - velocity = v + +# if attached_player != null && v != zero_vector: +# move_with_player(v) + velocity = v + +#func move_with_player(v: Vector2): +# print(v) +# attached_player.move_and_slide(v * 10) func correct_jump_direction(v: Vector2) -> Vector2: if sign(v.x) != get_facing_direction(): @@ -518,3 +537,6 @@ func _on_HurtTimer_timeout() -> void: is_hurt = false #if(is_bound): add_to_group("harmful") $FrogSprite.material = null + + + diff --git a/src/Actors/Enemies/Beings/WhatAreFrog.tscn b/src/Actors/Enemies/Beings/WhatAreFrog.tscn index 94ff155..31f3453 100644 --- a/src/Actors/Enemies/Beings/WhatAreFrog.tscn +++ b/src/Actors/Enemies/Beings/WhatAreFrog.tscn @@ -574,6 +574,7 @@ wait_time = 3.236 one_shot = true [connection signal="body_entered" from="StompDetector" to="." method="_on_StompDetector_body_entered"] +[connection signal="body_exited" from="StompDetector" to="." method="_on_StompDetector_body_exited"] [connection signal="area_entered" from="EnemySkin" to="." method="_on_EnemySkin_area_entered"] [connection signal="body_entered" from="EnemySkin" to="." method="_on_EnemySkin_body_entered"] [connection signal="timeout" from="HurtTimer" to="." method="_on_HurtTimer_timeout"] diff --git a/src/Platforms/SpringPhysics.gd b/src/Platforms/SpringPhysics.gd index 8f166ab..6ca35e5 100644 --- a/src/Platforms/SpringPhysics.gd +++ b/src/Platforms/SpringPhysics.gd @@ -17,77 +17,76 @@ var shock_ready = true func _ready() -> void: - start_y = self.position.y + start_y = self.position.y # TODO Limit spring deformation -# Called every frame. 'delta' is the elapsed time since the previous frame. func _physics_process(delta: float) -> void: - var bc = _body_contact() - if !bc: - shock_ready = true - if bc && shock_ready: - _Kinematic_Body_on_Spring() + var bc = _body_contact() + if !bc: + shock_ready = true + if bc && shock_ready: + _Kinematic_Body_on_Spring() - var spring_force = spring_k * (self.position.y - self.start_y) - if coupled_body != null: - coupled_mass = mass + coupled_body.mass - else: - coupled_mass = mass + var spring_force = spring_k * (self.position.y - self.start_y) + 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 - ) + 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 *= friction + y_velocity *= friction - self.position.y += y_velocity * delta + self.position.y += y_velocity * delta func _body_contact() -> bool: - var areas: Array = $SpringSkin.get_overlapping_areas() - for i in range(0, areas.size()): - if ["BlobbySkin","EnemySkin"].has(areas[i].name): - coupled_body = areas[i].get_parent() - return true - coupled_body = null - return false + var areas: Array = $SpringSkin.get_overlapping_areas() + for i in range(0, areas.size()): + if ["BlobbySkin","EnemySkin"].has(areas[i].name): + coupled_body = 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 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 = 0 - shock_ready = false + var a_velocity = stored_incoming_velocity + 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 = 0 + shock_ready = false func _on_SpringSkin_area_exited(_area: Area2D) -> void: - var displacement = self.position.y - self.start_y - var potential_spring_energy = spring_k * 0.5 * pow(displacement, 2) - var mass_ratio = 1 - mass / coupled_mass - var transferred_kinetic_energy = potential_spring_energy * mass_ratio - var kinetic_energy_in_velocity = ( - -sign(displacement) - * sqrt( - abs( - 2 * transferred_kinetic_energy / max(coupled_mass - mass, 0.001) - ) - ) - ) - if coupled_body != null: - coupled_body.velocity.y += kinetic_energy_in_velocity + var displacement = self.position.y - self.start_y + var potential_spring_energy = spring_k * 0.5 * pow(displacement, 2) + var mass_ratio = 1 - mass / coupled_mass + var transferred_kinetic_energy = potential_spring_energy * mass_ratio + var kinetic_energy_in_velocity = ( + -sign(displacement) + * sqrt( + abs( + 2 * transferred_kinetic_energy / max(coupled_mass - mass, 0.001) + ) + ) + ) + if coupled_body != null: + coupled_body.velocity.y += kinetic_energy_in_velocity func _on_EnteringVelocityDetector_area_entered(area: Area2D) -> void: - if area.name == "BlobbySkin": - if area.get_parent().velocity.y > 0: - stored_incoming_velocity = area.get_parent().velocity.y + if area.name == "BlobbySkin": + if area.get_parent().velocity.y > 0: + stored_incoming_velocity = area.get_parent().velocity.y