feat: let blobby ride on frog

This commit is contained in:
Jakob Feldmann 2023-07-04 13:50:26 +02:00
parent 317ce3d2b7
commit 311abfcc6f
4 changed files with 112 additions and 90 deletions

View File

@ -12,51 +12,51 @@ var rope
var is_first_signal = true var is_first_signal = true
func _ready() -> void: func _ready() -> void:
signalManager.connect("level_loaded", self, "_on_level_loaded") signalManager.connect("level_loaded", self, "_on_level_loaded")
func _on_level_loaded() -> void: func _on_level_loaded() -> void:
rope = Rope.instance() rope = Rope.instance()
# For some reason the rope only can be instanced in the parent scene # For some reason the rope only can be instanced in the parent scene
# The scene also has to be ready beforehand # The scene also has to be ready beforehand
get_parent().add_child(rope) get_parent().add_child(rope)
rope.rope_end = get_node("RopeAnchor") rope.rope_end = get_node("RopeAnchor")
rope.rope_start = get_node("WhatAreFrog") rope.rope_start = get_node("WhatAreFrog")
rope.rope_end_joint = get_node("RopeAnchor/cshape/pjoint") rope.rope_end_joint = get_node("RopeAnchor/cshape/pjoint")
rope.rope_start_joint = get_node("WhatAreFrog/cshape/pjoint") rope.rope_start_joint = get_node("WhatAreFrog/cshape/pjoint")
rope.spawn_rope($WhatAreFrog.global_position, $RopeAnchor.global_position, movement_radius, false) rope.spawn_rope($WhatAreFrog.global_position, $RopeAnchor.global_position, movement_radius, false)
$WhatAreFrog.tilemap = tilemap $WhatAreFrog.tilemap = tilemap
$WhatAreFrog.bind_to_anchor($RopeAnchor, movement_radius) $WhatAreFrog.bind_to_anchor($RopeAnchor, movement_radius)
# Executes on frog death # Executes on frog death
# The old switchero # The old switchero
func _on_WhatAreFrog_child_exiting_tree(_node:Node) -> void: func _on_WhatAreFrog_child_exiting_tree(_node:Node) -> void:
if(is_first_signal): if(is_first_signal):
disconnect_rope() disconnect_rope()
is_first_signal = false is_first_signal = false
else: else:
pass pass
func disconnect_rope() -> void: func disconnect_rope() -> void:
var anchor = RopeAnchor.instance() var anchor = RopeAnchor.instance()
anchor.mode = 0 anchor.mode = 0
add_child(anchor) add_child(anchor)
anchor.global_position = rope.rope_start_joint.global_position anchor.global_position = rope.rope_start_joint.global_position
rope.queue_free() rope.queue_free()
rope = Rope.instance() rope = Rope.instance()
# For some reason the rope only can be instanced in the parent scene # For some reason the rope only can be instanced in the parent scene
# The scene also has to be ready beforehand # The scene also has to be ready beforehand
get_parent().add_child(rope) get_parent().add_child(rope)
rope.rope_end = $RopeAnchor rope.rope_end = $RopeAnchor
rope.rope_start = anchor rope.rope_start = anchor
rope.rope_end_joint = $RopeAnchor/cshape/pjoint rope.rope_end_joint = $RopeAnchor/cshape/pjoint
rope.rope_start_joint = anchor.get_node("cshape/pjoint") rope.rope_start_joint = anchor.get_node("cshape/pjoint")
rope.spawn_rope(anchor.global_position, $RopeAnchor.global_position, movement_radius, false) rope.spawn_rope(anchor.global_position, $RopeAnchor.global_position, movement_radius, false)
func _on_FrogFreeButton_pushed() -> void: func _on_FrogFreeButton_pushed() -> void:
$WhatAreFrog.levelState.frees += 1 $WhatAreFrog.levelState.frees += 1
$WhatAreFrog.is_bound = false $WhatAreFrog.is_bound = false
$WhatAreFrog/LeashAnchor.visible = false $WhatAreFrog/LeashAnchor.visible = false
$WhatAreFrog.remove_from_group("harmful") $WhatAreFrog.remove_from_group("harmful")
disconnect_rope() disconnect_rope()
is_first_signal = false is_first_signal = false

View File

@ -51,6 +51,8 @@ var detect_timer := 0.0
var reversing_possible_searching := true var reversing_possible_searching := true
var attached_player = null
func _ready(): func _ready():
default_jump_distance = default_jump_distance * tilemap.cell_size.x 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: 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: if !body.is_in_group("player") || is_hurt:
return return
var incoming_vel_vector: Vector2 = body.velocity.normalized() var incoming_vel_vector: Vector2 = body.velocity.normalized()
@ -92,6 +97,10 @@ func _on_StompDetector_body_entered(body: Node) -> void:
$FrogSprite.material = invincible_shader $FrogSprite.material = invincible_shader
$HurtTimer.start() $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: func execute_movement(delta: float) -> void:
# Navigation2DServer.map_get_path() # Navigation2DServer.map_get_path()
@ -109,12 +118,15 @@ func execute_movement(delta: float) -> void:
velocity.y = velocity.y * 0.8 velocity.y = velocity.y * 0.8
was_restricted = true was_restricted = true
velocity = move_and_slide(velocity, FLOOR_NORMAL, false, 4, 0.785398, false) velocity = move_and_slide(velocity, FLOOR_NORMAL, false, 4, 0.785398, false)
if(is_on_floor()): if(is_on_floor()):
velocity = Vector2(0,0) velocity = Vector2(0,0)
# Reverse direction when hitting limit # Reverse direction when hitting limit
func die() -> void: func die() -> void:
levelState.kills += 1 levelState.kills += 1
queue_free() queue_free()
@ -298,8 +310,15 @@ func jump():
v = consider_jumping_on_top() v = consider_jumping_on_top()
if(v == zero_vector && can_reverse_facing_direction()): if(v == zero_vector && can_reverse_facing_direction()):
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: func correct_jump_direction(v: Vector2) -> Vector2:
if sign(v.x) != get_facing_direction(): if sign(v.x) != get_facing_direction():
@ -518,3 +537,6 @@ func _on_HurtTimer_timeout() -> void:
is_hurt = false is_hurt = false
#if(is_bound): add_to_group("harmful") #if(is_bound): add_to_group("harmful")
$FrogSprite.material = null $FrogSprite.material = null

View File

@ -574,6 +574,7 @@ wait_time = 3.236
one_shot = true one_shot = true
[connection signal="body_entered" from="StompDetector" to="." method="_on_StompDetector_body_entered"] [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="area_entered" from="EnemySkin" to="." method="_on_EnemySkin_area_entered"]
[connection signal="body_entered" from="EnemySkin" to="." method="_on_EnemySkin_body_entered"] [connection signal="body_entered" from="EnemySkin" to="." method="_on_EnemySkin_body_entered"]
[connection signal="timeout" from="HurtTimer" to="." method="_on_HurtTimer_timeout"] [connection signal="timeout" from="HurtTimer" to="." method="_on_HurtTimer_timeout"]

View File

@ -17,77 +17,76 @@ var shock_ready = true
func _ready() -> void: func _ready() -> void:
start_y = self.position.y start_y = self.position.y
# TODO Limit spring deformation # TODO Limit spring deformation
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _physics_process(delta: float) -> void: func _physics_process(delta: float) -> void:
var bc = _body_contact() var bc = _body_contact()
if !bc: if !bc:
shock_ready = true shock_ready = true
if bc && shock_ready: if bc && shock_ready:
_Kinematic_Body_on_Spring() _Kinematic_Body_on_Spring()
var spring_force = spring_k * (self.position.y - self.start_y) var spring_force = spring_k * (self.position.y - self.start_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
self.position.y += y_velocity * delta self.position.y += y_velocity * delta
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()):
if ["BlobbySkin","EnemySkin"].has(areas[i].name): if ["BlobbySkin","EnemySkin"].has(areas[i].name):
coupled_body = areas[i].get_parent() coupled_body = areas[i].get_parent()
return true return true
coupled_body = null 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
func _on_SpringSkin_area_exited(_area: Area2D) -> void: func _on_SpringSkin_area_exited(_area: Area2D) -> void:
var displacement = self.position.y - self.start_y var displacement = self.position.y - self.start_y
var potential_spring_energy = spring_k * 0.5 * pow(displacement, 2) var potential_spring_energy = spring_k * 0.5 * pow(displacement, 2)
var mass_ratio = 1 - mass / coupled_mass var mass_ratio = 1 - mass / coupled_mass
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(
abs( abs(
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
func _on_EnteringVelocityDetector_area_entered(area: Area2D) -> void: func _on_EnteringVelocityDetector_area_entered(area: Area2D) -> void:
if area.name == "BlobbySkin": if area.name == "BlobbySkin":
if area.get_parent().velocity.y > 0: if area.get_parent().velocity.y > 0:
stored_incoming_velocity = area.get_parent().velocity.y stored_incoming_velocity = area.get_parent().velocity.y