summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hook_hanging.gd4
-rw-r--r--hook_hanging.gd.uid1
-rw-r--r--player.gd60
-rw-r--r--project.godot7
-rw-r--r--room_test1.tscn11
-rw-r--r--transition_player.gd2
6 files changed, 83 insertions, 2 deletions
diff --git a/hook_hanging.gd b/hook_hanging.gd
new file mode 100644
index 0000000..19a3ff6
--- /dev/null
+++ b/hook_hanging.gd
@@ -0,0 +1,4 @@
+class_name HookHanging
+extends Sprite2D
+
+@export var hang_distance: float
diff --git a/hook_hanging.gd.uid b/hook_hanging.gd.uid
new file mode 100644
index 0000000..95c0889
--- /dev/null
+++ b/hook_hanging.gd.uid
@@ -0,0 +1 @@
+uid://b5vux357w0ou2
diff --git a/player.gd b/player.gd
index 2a0137f..9b4eebc 100644
--- a/player.gd
+++ b/player.gd
@@ -5,6 +5,7 @@ extends CharacterBody2D
@export var jump_strength: float
@export var coyote_max_ms: float
@export var jump_held_coef: float
+@export var hook_distance_max: float
## float (-1.0 .. 1.0) or null
var forced_input_x: Variant
@@ -14,10 +15,17 @@ var curve_target: Curve2D
var curve_speed: float
var curve_dir: int
+var hanging_target: HookHanging
+var hanging_t: float
+var hanging_L: float
+var hanging_theta0: float
+var hanging_line2D: Line2D
+
enum MovementType {
NORMAL,
FORCED,
CURVE,
+ HANGING,
}
var movement_type = MovementType.NORMAL
var movement_handler: Callable = _movement_normal
@@ -106,6 +114,24 @@ func set_movement_curve(curve: Curve2D, speed: float, reverse: bool):
else:
curve_dir = 1
curve_t = 0
+
+func set_movement_hanging(target: Node2D, hang_dist: float):
+ if movement_type == MovementType.HANGING: return
+
+ movement_type = MovementType.HANGING
+ movement_handler = _movement_hanging
+
+ hanging_t = 0
+ hanging_L = hang_dist
+ hanging_target = target
+ var theta0_sign = sign(global_position.x - target.global_position.x)
+ hanging_theta0 = deg_to_rad(theta0_sign * 30)
+
+ hanging_line2D = Line2D.new()
+ hanging_line2D.width = 2
+ hanging_line2D.add_point(Vector2.ZERO)
+ hanging_line2D.add_point(Vector2.ZERO) # set in movement handler
+ target.add_child(hanging_line2D)
#endregion
#region movement handlers
@@ -132,6 +158,9 @@ func _movement_normal(delta: float):
if not Input.is_action_pressed("jump"):
jump_was_released = true
+
+ if Input.is_action_just_pressed("action"):
+ handle_action_input()
var direction: float
if Input.is_action_pressed("move_left") and Input.is_action_pressed("move_right"):
@@ -174,4 +203,35 @@ func _movement_curve(delta: float):
return
position = new_position
+
+func _movement_hanging(delta: float):
+ hanging_t += delta
+
+ if Input.is_action_just_pressed("jump"):
+ velocity.y = -jump_strength
+ # Force coyote time to expire to forbid double jumps
+ coyote = coyote_max_ms
+ jump_was_released = false
+ hanging_line2D.queue_free()
+ set_movement_normal()
+
+ var omega = sqrt(gravity / hanging_L)
+ var theta = hanging_theta0 * cos(hanging_t * omega)
+ global_position.x = hanging_target.global_position.x + hanging_L * sin(theta)
+ global_position.y = hanging_target.global_position.y + hanging_L * cos(theta)
+
+ hanging_line2D.points[1] = global_position - hanging_target.global_position
#endregion
+
+func handle_action_input():
+ var hooks = get_tree().get_nodes_in_group("hook_hanging")
+ for hook_any in hooks:
+ if not hook_any is HookHanging:
+ print_debug("hook is not HookHanging!", hook_any)
+ continue
+
+ var hook: HookHanging = hook_any
+ var dist = (hook.global_position - global_position).length()
+ print_debug("found hook: ", hook, ", dist: ", dist)
+ if dist < hook_distance_max:
+ set_movement_hanging(hook, hook.hang_distance)
diff --git a/project.godot b/project.godot
index a8e0cf5..8155a63 100644
--- a/project.godot
+++ b/project.godot
@@ -30,6 +30,7 @@ window/stretch/scale_mode="integer"
ui_movement=""
ui_menu=""
+hook_hanging=""
[input]
@@ -57,6 +58,12 @@ menu={
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
+action={
+"deadzone": 0.2,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null)
+]
+}
[layer_names]
diff --git a/room_test1.tscn b/room_test1.tscn
index 2cd5b1b..d47e98c 100644
--- a/room_test1.tscn
+++ b/room_test1.tscn
@@ -1,9 +1,11 @@
-[gd_scene load_steps=7 format=4 uid="uid://cfj21o6wsd3hv"]
+[gd_scene load_steps=9 format=4 uid="uid://cfj21o6wsd3hv"]
[ext_resource type="Texture2D" uid="uid://dkek11j5dh6as" path="res://assets.untracked/kenney_1-bit-platformer-pack/Tiles/Default/tile_0338.png" id="1_m3rqw"]
[ext_resource type="PackedScene" uid="uid://coxnsharboouu" path="res://player.tscn" id="2_qglt1"]
[ext_resource type="PackedScene" uid="uid://dfyvkc2qlcdac" path="res://game_camera.tscn" id="3_mrrx3"]
[ext_resource type="PackedScene" uid="uid://df0loiahar23o" path="res://door.tscn" id="6_lfjh7"]
+[ext_resource type="Texture2D" uid="uid://bhtovawtfqev3" path="res://assets.untracked/kenney_1-bit-platformer-pack/Tiles/Default/tile_0006.png" id="6_ubxha"]
+[ext_resource type="Script" uid="uid://b5vux357w0ou2" path="res://hook_hanging.gd" id="7_mrrx3"]
[ext_resource type="TileSet" uid="uid://0cd30n67d6k5" path="res://tileset_kenney_platformer.tres" id="7_qglt1"]
[sub_resource type="Curve2D" id="Curve2D_m3rqw"]
@@ -36,6 +38,7 @@ tile_set = ExtResource("7_qglt1")
[node name="Player" parent="." instance=ExtResource("2_qglt1")]
position = Vector2(87, 91)
collision_layer = 2
+hook_distance_max = 100.0
[node name="GameCamera" parent="Player" instance=ExtResource("3_mrrx3")]
unique_name_in_owner = true
@@ -70,3 +73,9 @@ tile_set = ExtResource("7_qglt1")
[node name="Path2D" type="Path2D" parent="."]
curve = SubResource("Curve2D_m3rqw")
+
+[node name="HookHanging" type="Sprite2D" parent="." groups=["hook_hanging"]]
+position = Vector2(226, -4)
+texture = ExtResource("6_ubxha")
+script = ExtResource("7_mrrx3")
+hang_distance = 50.0
diff --git a/transition_player.gd b/transition_player.gd
index 7238151..a118b56 100644
--- a/transition_player.gd
+++ b/transition_player.gd
@@ -15,7 +15,7 @@ func room_transition(from_door: Door, to_room_path: String, door_name: Variant):
if from_door:
var player: Player = top.get_node("ActiveRoom").find_child("Player")
- player.set_forced_input(from_door.enter_towards)
+ player.set_movement_forced(from_door.enter_towards)
# Start animation
# The animation calls _change_room at a specific time