summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/index.html2
-rw-r--r--docs/index.pckbin4606972 -> 4616748 bytes
-rw-r--r--docs/index.service.worker.js2
-rw-r--r--player.gd41
-rw-r--r--player.tscn1
-rw-r--r--project.godot33
-rw-r--r--ps_hanging.gd16
-rw-r--r--ps_zooping.gd81
-rw-r--r--ps_zooping.gd.uid1
-rw-r--r--room_test1.tscn7
-rw-r--r--zoop_point.gd15
-rw-r--r--zoop_point.gd.uid1
-rw-r--r--zoop_point.tscn12
13 files changed, 186 insertions, 26 deletions
diff --git a/docs/index.html b/docs/index.html
index f437c23..c95c3ee 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -112,7 +112,7 @@ body {
<script src="index.js"></script>
<script>
-const GODOT_CONFIG = {"args":[],"canvasResizePolicy":2,"emscriptenPoolSize":8,"ensureCrossOriginIsolationHeaders":true,"executable":"index","experimentalVK":false,"fileSizes":{"index.pck":4606972,"index.wasm":38034280},"focusCanvas":true,"gdextensionLibs":[],"godotPoolSize":4,"serviceWorker":"index.service.worker.js"};
+const GODOT_CONFIG = {"args":[],"canvasResizePolicy":2,"emscriptenPoolSize":8,"ensureCrossOriginIsolationHeaders":true,"executable":"index","experimentalVK":false,"fileSizes":{"index.pck":4616748,"index.wasm":38034280},"focusCanvas":true,"gdextensionLibs":[],"godotPoolSize":4,"serviceWorker":"index.service.worker.js"};
const GODOT_THREADS_ENABLED = false;
const engine = new Engine(GODOT_CONFIG);
diff --git a/docs/index.pck b/docs/index.pck
index dbde122..c28d8cf 100644
--- a/docs/index.pck
+++ b/docs/index.pck
Binary files differ
diff --git a/docs/index.service.worker.js b/docs/index.service.worker.js
index fb84ef1..996425f 100644
--- a/docs/index.service.worker.js
+++ b/docs/index.service.worker.js
@@ -4,7 +4,7 @@
// Incrementing CACHE_VERSION will kick off the install event and force
// previously cached resources to be updated from the network.
/** @type {string} */
-const CACHE_VERSION = '1764884307|18241003549';
+const CACHE_VERSION = '1764931733|33107827033';
/** @type {string} */
const CACHE_PREFIX = 'MobileMetroidvan-sw-cache-';
const CACHE_NAME = CACHE_PREFIX + CACHE_VERSION;
diff --git a/player.gd b/player.gd
index b3b9aef..839aa44 100644
--- a/player.gd
+++ b/player.gd
@@ -5,7 +5,6 @@ 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
@export var camera_offset_look: float
@export var camera_offset_jump: float
@@ -28,17 +27,18 @@ func _camera_target() -> Vector2:
func _process(delta: float) -> void:
state._handle(delta)
- for hook_any in tree.get_nodes_in_group("hook_hanging"):
- assert(hook_any is HookHanging, "hook is not HookHanging")
- var hook: HookHanging = hook_any
- var is_camera_target: bool = hook.is_in_group("camera_target")
- var player_not_much_higher = (hook.global_position.y - global_position.y) < 30
- var is_close: bool = ((hook.global_position - global_position).length() < 100) and player_not_much_higher
+ var look_at_nodes: Array[Node2D] = []
+ look_at_nodes.append_array(tree.get_nodes_in_group("hook_hanging"))
+ look_at_nodes.append_array(tree.get_nodes_in_group("zoop_points"))
+ for look_at_node in look_at_nodes:
+ var is_camera_target: bool = look_at_node.is_in_group("camera_target")
+ var player_not_much_higher = (look_at_node.global_position.y - global_position.y) < 30
+ var is_close: bool = ((look_at_node.global_position - global_position).length() < 100) and player_not_much_higher
if not is_camera_target and is_close:
- hook.add_to_group("camera_target")
+ look_at_node.add_to_group("camera_target")
elif is_camera_target and not is_close:
- hook.remove_from_group("camera_target")
+ look_at_node.remove_from_group("camera_target")
func _physics_process(delta: float):
state._handle_physics(delta)
@@ -59,11 +59,18 @@ func request_state_curve(curve: Curve2D, c_speed: float, c_reverse: bool):
state = PlayerStateCurve.new(self, curve, c_speed, c_reverse)
-func request_state_hanging(target: Node2D, hang_dist: float):
+func request_state_hanging(target: Node2D):
if state is PlayerStateHanging: return
if not PlayerStateHanging.can_hang_from(self, target): return
- state = PlayerStateHanging.new(self, target, hang_dist)
+ state = PlayerStateHanging.new(self, target)
+
+func request_state_zooping(target: ZoopPoint) -> bool:
+ if state is PlayerStateZooping: return false
+ if not PlayerStateZooping.can_zoop_to(self, target): return false
+
+ state = PlayerStateZooping.new(self, target)
+ return true
func get_facing() -> int:
if anim_sp.flip_h:
@@ -74,8 +81,10 @@ func get_facing() -> int:
func handle_action_input():
var hooks = get_tree().get_nodes_in_group("hook_hanging")
for hook_any in hooks:
- assert(hook_any is HookHanging, "hook is not HookHanging")
- var hook: HookHanging = hook_any
- var dist = (hook.global_position - global_position).length()
- if dist < hook_distance_max:
- request_state_hanging(hook, hook.hang_distance)
+ var hook: HookHanging = hook_any as HookHanging
+ if request_state_hanging(hook): return
+
+ var zoops = get_tree().get_nodes_in_group("zoop_points")
+ for zoop_any in zoops:
+ var zoop: ZoopPoint = zoop_any as ZoopPoint
+ if request_state_zooping(zoop): return
diff --git a/player.tscn b/player.tscn
index d052e88..1cab8b7 100644
--- a/player.tscn
+++ b/player.tscn
@@ -107,7 +107,6 @@ speed = 70.0
jump_strength = 200.0
coyote_max_ms = 100.0
jump_held_coef = 0.8
-hook_distance_max = 80.0
camera_offset_look = 40.0
camera_offset_jump = 14.0
diff --git a/project.godot b/project.godot
index e3f4c19..d695c8c 100644
--- a/project.godot
+++ b/project.godot
@@ -34,9 +34,42 @@ hook_hanging=""
ui_action=""
debug_info=""
camera_target=""
+zoop_points=""
[input]
+ui_left={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194319,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"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":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
+]
+}
+ui_right={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194321,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"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":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
+]
+}
+ui_up={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194320,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"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":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
+]
+}
+ui_down={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194322,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"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":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
+]
+}
move_right={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
diff --git a/ps_hanging.gd b/ps_hanging.gd
index 3848da4..aa5e0ed 100644
--- a/ps_hanging.gd
+++ b/ps_hanging.gd
@@ -12,19 +12,20 @@ var tongue: Line2D
var travel_from: Vector2
var travel_to: Vector2
-var T_mlem: float = 0.2
-var T_travel: float = 0.1
+static var T_mlem: float = 0.2
+static var T_travel: float = 0.1
-var swing_force: float = 0.2
+static var swing_force: float = 0.2
+static var hook_distance_max: float = 80
enum S { MLEMING, TRAVELING, HANGING }
var state: S = S.MLEMING
-func _init(pl: Player, h_target: HookHanging, h_dist: float) -> void:
+func _init(pl: Player, h_target: HookHanging) -> void:
super(pl)
t = 0
- L = h_dist
+ L = h_target.hang_distance
target = h_target
w = sqrt(p.gravity / L) * 0.7
@@ -41,7 +42,10 @@ static func can_hang_from(pl: Player, c_target: HookHanging) -> bool:
var angle = atan2(d.y, d.x)
var revs = floor(angle / (2 * PI))
angle -= revs * 2 * PI
- return angle > deg_to_rad(135) or angle < deg_to_rad(45)
+
+ var is_close = d.length() < hook_distance_max
+ var is_ok_angle = angle > deg_to_rad(135) or angle < deg_to_rad(45)
+ return is_close and is_ok_angle
func _handle(_delta: float):
if Input.is_action_just_pressed("move_left"):
diff --git a/ps_zooping.gd b/ps_zooping.gd
new file mode 100644
index 0000000..2c743a3
--- /dev/null
+++ b/ps_zooping.gd
@@ -0,0 +1,81 @@
+class_name PlayerStateZooping
+extends PlayerState
+
+var target: ZoopPoint
+var t: float
+var tongue: Line2D
+
+var travel_from: Vector2
+var travel_to: Vector2
+
+var T_mlem: float = 0.2
+var T_travel: float = 0.2
+
+enum S { MLEMING, TRAVELING }
+var state: S = S.MLEMING
+
+func _init(pl: Player, h_target: ZoopPoint) -> void:
+ super(pl)
+
+ t = 0
+ target = h_target
+
+ var dx = target.global_position.x - pl.global_position.x
+ pl.anim_sp.flip_h = dx < 0
+
+ state = S.MLEMING
+
+func _to_string() -> String:
+ return "PlayerStateZooping %s" % S.keys()[state]
+
+static func can_zoop_to(pl: Player, z_target: ZoopPoint) -> bool:
+ var dy = z_target.global_position.y - pl.global_position.y
+ var dx = z_target.global_position.x - pl.global_position.x
+ return abs(dy) < 20 and abs(dx) < 100
+
+func _handle(_delta: float):
+ pass
+
+func _handle_physics(delta: float):
+ match state:
+ S.MLEMING: _mlem(delta)
+ S.TRAVELING: _travel(delta)
+ _: assert(false, "unknown state %s" % str(state))
+
+func _mlem(delta: float):
+ t += delta
+ var d = target.global_position - p.global_position
+
+ # Add tongue line
+ if not tongue:
+ tongue = Line2D.new()
+ tongue.width = 2
+ tongue.add_point(-d)
+ tongue.add_point(-d)
+ target.add_child(tongue)
+
+ # Update one end to be at player
+ tongue.points[0] = -d
+ tongue.points[1] = (t / T_mlem - 1) * d
+
+ if t >= T_mlem:
+ tongue.points[1] = Vector2.ZERO
+ state = S.TRAVELING
+ travel_from = p.global_position
+ travel_to = target.global_position
+ t = 0
+
+func _travel(delta: float):
+ t += delta
+ p.global_position = travel_from + (t / T_travel) * (travel_to - travel_from)
+
+ var d = target.global_position - p.global_position
+ tongue.points[0] = -d
+
+ # If we're traveling in the right direction, then travel
+ if t >= T_travel:
+ p.global_position = travel_to
+ tongue.queue_free()
+
+ p.velocity = Vector2(0, -100)
+ p.request_state_normal()
diff --git a/ps_zooping.gd.uid b/ps_zooping.gd.uid
new file mode 100644
index 0000000..7cdd3cc
--- /dev/null
+++ b/ps_zooping.gd.uid
@@ -0,0 +1 @@
+uid://cynonfpknidv4
diff --git a/room_test1.tscn b/room_test1.tscn
index f0bb49d..706235b 100644
--- a/room_test1.tscn
+++ b/room_test1.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=9 format=4 uid="uid://cfj21o6wsd3hv"]
+[gd_scene load_steps=10 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="Script" uid="uid://cbhily4o7e2r3" path="res://room.gd" id="1_mrrx3"]
@@ -7,6 +7,7 @@
[ext_resource type="PackedScene" uid="uid://df0loiahar23o" path="res://door.tscn" id="6_lfjh7"]
[ext_resource type="PackedScene" uid="uid://cvpmt6tqgj0qk" path="res://hook_hanging.tscn" id="7_mrrx3"]
[ext_resource type="TileSet" uid="uid://0cd30n67d6k5" path="res://tileset_kenney_platformer.tres" id="7_qglt1"]
+[ext_resource type="PackedScene" uid="uid://4a6yx5iho8tg" path="res://zoop_point.tscn" id="8_mrrx3"]
[sub_resource type="Curve2D" id="Curve2D_m3rqw"]
bake_interval = 1.0
@@ -74,3 +75,7 @@ curve = SubResource("Curve2D_m3rqw")
[node name="HookHanging" parent="." instance=ExtResource("7_mrrx3")]
position = Vector2(226, 7)
+
+[node name="ZoopPoint" parent="." instance=ExtResource("8_mrrx3")]
+position = Vector2(40, 56)
+orientation = "right"
diff --git a/zoop_point.gd b/zoop_point.gd
new file mode 100644
index 0000000..44ff826
--- /dev/null
+++ b/zoop_point.gd
@@ -0,0 +1,15 @@
+class_name ZoopPoint
+extends Node2D
+
+@export_enum("left", "right") var orientation: String
+
+func _ready():
+ $Sprite2D.flip_h = orientation == "left"
+
+func _camera_target() -> Vector2:
+ var off: Vector2
+ if orientation == "left": off = Vector2(-20, 0)
+ elif orientation == "right": off = Vector2(20, 0)
+ else: assert(false, "invalid orientation")
+
+ return global_position + off
diff --git a/zoop_point.gd.uid b/zoop_point.gd.uid
new file mode 100644
index 0000000..ccd3c97
--- /dev/null
+++ b/zoop_point.gd.uid
@@ -0,0 +1 @@
+uid://xk5p3so7xf3a
diff --git a/zoop_point.tscn b/zoop_point.tscn
new file mode 100644
index 0000000..c48be4b
--- /dev/null
+++ b/zoop_point.tscn
@@ -0,0 +1,12 @@
+[gd_scene load_steps=3 format=3 uid="uid://4a6yx5iho8tg"]
+
+[ext_resource type="Texture2D" uid="uid://yev1qskwf73" path="res://assets.untracked/kenney_1-bit-platformer-pack/Tiles/Transparent/tile_0012.png" id="1_jig5b"]
+[ext_resource type="Script" uid="uid://xk5p3so7xf3a" path="res://zoop_point.gd" id="2_p0qu3"]
+
+[node name="ZoopPoint" type="Node2D" groups=["zoop_points"]]
+script = ExtResource("2_p0qu3")
+speed = 70.0
+
+[node name="Sprite2D" type="Sprite2D" parent="."]
+rotation = 1.5707964
+texture = ExtResource("1_jig5b")