summaryrefslogtreecommitdiffstats
path: root/ps_hanging.gd
diff options
context:
space:
mode:
authorJan Tuomi <jan@jantuomi.fi>2025-11-28 18:42:41 +0200
committerJan Tuomi <jan@jantuomi.fi>2025-11-28 18:42:41 +0200
commit6173a0c4e1b41628532a37f0638339b0724b445e (patch)
tree56c52754cf2aa93e8678639c0ed7c91595acb40d /ps_hanging.gd
parent1723938f22be657cbe8d6bc85e70039622412273 (diff)
Use state machine in Player
Diffstat (limited to 'ps_hanging.gd')
-rw-r--r--ps_hanging.gd90
1 files changed, 90 insertions, 0 deletions
diff --git a/ps_hanging.gd b/ps_hanging.gd
new file mode 100644
index 0000000..3533348
--- /dev/null
+++ b/ps_hanging.gd
@@ -0,0 +1,90 @@
+class_name PlayerStateHanging
+extends PlayerState
+
+var target: HookHanging
+var t: float
+var L: float
+var theta0: float
+var line2D: Line2D
+
+var tweening: bool
+
+func initialize(p: Player, h_target: HookHanging, h_dist: float):
+ t = 0
+ L = h_dist
+ target = h_target
+
+ # Add tongue line
+ line2D = Line2D.new()
+ line2D.width = 2
+ line2D.add_point(Vector2.ZERO)
+ line2D.add_point(Vector2.ZERO) # set in movement handler
+ target.add_child(line2D)
+
+ var hyp = target.global_position - p.global_position
+ var sign_x = sign(hyp.x)
+ var angle_below_horiz = 15
+ var angle_below_horiz_r = deg_to_rad(angle_below_horiz)
+ var tweening_target_point = target.global_position \
+ - Vector2(sign_x * L * cos(angle_below_horiz_r),
+ -L * sin(angle_below_horiz_r))
+
+ # if player is above the hook, we need to tween to horizontal
+ if tweening_target_point.y - p.global_position.y > 0:
+ tweening = true
+ return
+
+ tweening = false
+
+ theta0 = atan2(-hyp.y, hyp.x) - PI/2
+ if theta0 < -PI: theta0 += 2*PI
+ print_debug("hyp: ", hyp, ", theta0: ", theta0)
+
+func _handle(_p: Player, _delta: float):
+ pass
+
+func _handle_physics(p: Player, delta: float):
+ if tweening:
+ _movement_hang_tween(p, delta)
+ else:
+ _movement_hanging(p, delta)
+
+func _movement_hanging(p: Player, delta: float):
+ t += delta
+
+ if Input.is_action_just_pressed("jump"):
+ p.velocity.y = -p.jump_strength
+ line2D.queue_free()
+ p.set_movement_normal()
+
+ var omega = sqrt(p.gravity / L)
+ var theta = theta0 * cos(t * omega)
+ p.global_position.x = target.global_position.x + L * sin(theta)
+ p.global_position.y = target.global_position.y + L * cos(theta)
+
+ line2D.points[1] = p.global_position - target.global_position
+
+func _movement_hang_tween(p: Player, delta: float):
+ var tween_speed = p.jump_strength
+ var hyp = target.global_position - p.global_position
+ var sign_x = sign(hyp.x)
+
+ var angle_below_horiz = 15
+ var angle_below_horiz_r = deg_to_rad(angle_below_horiz)
+ var tweening_target_point = target.global_position \
+ - Vector2(sign_x * L * cos(angle_below_horiz_r),
+ -L * sin(angle_below_horiz_r))
+
+ var tween_hyp = tweening_target_point - p.global_position
+ var tween_dir: Vector2 = tween_hyp.normalized()
+ var v: Vector2 = tween_dir * tween_speed
+ var s: Vector2 = v * delta
+
+ if tween_hyp.length() < s.length():
+ tweening = false
+ theta0 = deg_to_rad(-sign_x * (90 - angle_below_horiz))
+ else:
+ p.position += s
+
+ line2D.points[1] = p.global_position - target.global_position
+ pass