Skip to content

Commit d009a12

Browse files
authored
Merge pull request #933 from endlessm/grappling-hook
Add grappling hook mechanic and intro level
2 parents 0a552f4 + 92baff8 commit d009a12

61 files changed

Lines changed: 2834 additions & 120 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

project.godot

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ filling_barrels=""
7373
projectiles=""
7474
guard_enemy=""
7575
sequence_object=""
76+
hook_listener=""
7677

7778
[input]
7879

@@ -181,6 +182,7 @@ sokoban_skip={
181182
2d_physics/layer_8="enemies hitbox"
182183
2d_physics/layer_9="projectiles"
183184
2d_physics/layer_10="non_walkable_floor"
185+
2d_physics/layer_13="hookable"
184186

185187
[rendering]
186188

scenes/game_elements/characters/player/components/animation_player.gd

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ const REPEL_ANTICIPATION_TIME: float = 0.3
77
@onready var player: Player = owner
88
@onready var player_sprite: AnimatedSprite2D = %PlayerSprite
99
@onready var player_fighting: Node2D = %PlayerFighting
10+
@onready var player_hook: Node2D = %PlayerHook
1011
@onready var original_speed_scale: float = speed_scale
1112

1213

1314
func _ready() -> void:
1415
player.mode_changed.connect(_on_player_mode_changed)
16+
player_hook.string_thrown.connect(_on_player_hook_string_thrown)
1517

1618

1719
func _process(_delta: float) -> void:
@@ -20,6 +22,8 @@ func _process(_delta: float) -> void:
2022
_process_walk_idle(_delta)
2123
Player.Mode.FIGHTING:
2224
_process_fighting(_delta)
25+
Player.Mode.HOOKING:
26+
_process_hooking(_delta)
2327

2428
var double_speed: bool = current_animation == &"walk" and player.is_running()
2529
speed_scale = original_speed_scale * (2.0 if double_speed else 1.0)
@@ -58,7 +62,20 @@ func _process_fighting(delta: float) -> void:
5862
seek(REPEL_ANTICIPATION_TIME, false, false)
5963

6064

65+
func _process_hooking(delta: float) -> void:
66+
if current_animation == &"throw_string":
67+
return
68+
69+
_process_walk_idle(delta)
70+
71+
6172
func _on_player_mode_changed(mode: Player.Mode) -> void:
6273
match player.mode:
6374
Player.Mode.DEFEATED:
6475
play(&"defeated")
76+
77+
78+
func _on_player_hook_string_thrown() -> void:
79+
if current_animation == &"throw_string":
80+
stop()
81+
play(&"throw_string")
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:25e494f91925ca29ad0480fee0805446df204d0142e3a2ddd99d54b32726c02f
3+
size 387
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[remap]
2+
3+
importer="texture"
4+
type="CompressedTexture2D"
5+
uid="uid://q3c2qavtccvu"
6+
path="res://.godot/imported/hook-string.png-e8e2f9d47f895dcaf787c3a257fd7d67.ctex"
7+
metadata={
8+
"vram_texture": false
9+
}
10+
11+
[deps]
12+
13+
source_file="res://scenes/game_elements/characters/player/components/hook-string.png"
14+
dest_files=["res://.godot/imported/hook-string.png-e8e2f9d47f895dcaf787c3a257fd7d67.ctex"]
15+
16+
[params]
17+
18+
compress/mode=0
19+
compress/high_quality=false
20+
compress/lossy_quality=0.7
21+
compress/hdr_compression=1
22+
compress/normal_map=0
23+
compress/channel_pack=0
24+
mipmaps/generate=false
25+
mipmaps/limit=-1
26+
roughness/mode=0
27+
roughness/src_normal=""
28+
process/fix_alpha_border=true
29+
process/premult_alpha=false
30+
process/normal_map_invert_y=false
31+
process/hdr_as_srgb=false
32+
process/hdr_clamp_exposure=false
33+
process/size_limit=0
34+
detect_3d/compress_to=1

scenes/game_elements/characters/player/components/player.gd

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ enum Mode {
1313
COZY,
1414
## Player is engaged in combat. Player can use combat actions.
1515
FIGHTING,
16+
## Player is using the grappling hook.
17+
HOOKING,
1618
## Player can't be controlled anymore.
1719
DEFEATED,
1820
}
@@ -44,6 +46,7 @@ const DEFAULT_SPRITE_FRAME: SpriteFrames = preload("uid://vwf8e1v8brdp")
4446
set = _set_mode
4547
@export_range(10, 100000, 10) var walk_speed: float = 300.0
4648
@export_range(10, 100000, 10) var run_speed: float = 500.0
49+
@export_range(10, 100000, 10) var aiming_speed: float = 100.0
4750
@export_range(10, 100000, 10) var stopping_step: float = 1500.0
4851
@export_range(10, 100000, 10) var moving_step: float = 4000.0
4952

@@ -61,6 +64,7 @@ var input_vector: Vector2
6164

6265
@onready var player_interaction: PlayerInteraction = %PlayerInteraction
6366
@onready var player_fighting: Node2D = %PlayerFighting
67+
@onready var player_hook: PlayerHook = %PlayerHook
6468
@onready var player_sprite: AnimatedSprite2D = %PlayerSprite
6569
@onready var _walk_sound: AudioStreamPlayer2D = %WalkSound
6670

@@ -74,12 +78,19 @@ func _set_mode(new_mode: Mode) -> void:
7478
Mode.COZY:
7579
_toggle_player_behavior(player_interaction, true)
7680
_toggle_player_behavior(player_fighting, false)
81+
_toggle_player_behavior(player_hook, false)
7782
Mode.FIGHTING:
7883
_toggle_player_behavior(player_interaction, false)
7984
_toggle_player_behavior(player_fighting, true)
85+
_toggle_player_behavior(player_hook, false)
86+
Mode.HOOKING:
87+
_toggle_player_behavior(player_interaction, false)
88+
_toggle_player_behavior(player_fighting, false)
89+
_toggle_player_behavior(player_hook, true)
8090
Mode.DEFEATED:
8191
_toggle_player_behavior(player_interaction, false)
8292
_toggle_player_behavior(player_fighting, false)
93+
_toggle_player_behavior(player_hook, false)
8394
if mode != previous_mode:
8495
mode_changed.emit(mode)
8596

@@ -138,7 +149,9 @@ func _unhandled_input(_event: InputEvent) -> void:
138149
var axis: Vector2 = Input.get_vector(&"ui_left", &"ui_right", &"ui_up", &"ui_down")
139150

140151
var speed: float
141-
if Input.is_action_pressed(&"running"):
152+
if player_hook.is_throwing_or_aiming():
153+
speed = aiming_speed
154+
elif Input.is_action_pressed(&"running"):
142155
speed = run_speed
143156
else:
144157
speed = walk_speed
@@ -159,6 +172,10 @@ func _process(delta: float) -> void:
159172
if Engine.is_editor_hint():
160173
return
161174

175+
# While pulling the grappling hook, the movement is handled in PlayerHook._process.
176+
if player_hook.pulling:
177+
return
178+
162179
if player_interaction.is_interacting or mode == Mode.DEFEATED:
163180
velocity = Vector2.ZERO
164181
return

0 commit comments

Comments
 (0)