1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
class_name Player
extends CharacterBody2D
@export var speed: float
@export var jump_strength: float
@export var coyote_max_ms: float
@export var jump_held_coef: float
@export var camera_offset_look: float
@export var camera_offset_jump: float
var state: PlayerState = PlayerStateInit.new(self)
@onready var anim_sp: AnimatedSprite2D = $AnimatedSprite2D
@onready var tree: SceneTree = get_tree()
@onready var top: Top = tree.root.get_node("Top") as Top
@onready var inventory: Inventory = top.inventory
@onready var walk_audio: AudioStreamPlayer2D = $WalkAudio
@onready var jump_audio: AudioStreamPlayer2D = $JumpAudio
@onready var die_audio: AudioStreamPlayer2D = $DieAudio
@onready var fanfare_audio: AudioStreamPlayer2D = $FanfareAudio
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
func _debug_info():
return "%s\ngot zoop: %s\ngot hanging: %s\nrelics: %s" % [state.to_string(), str(inventory.zoop), str(inventory.hanging), str(inventory.relics)]
func _camera_target() -> Vector2:
var oy: float = 0
if not is_on_floor():
oy = camera_offset_jump
return global_position + Vector2(get_facing() * camera_offset_look, oy)
func _process(delta: float) -> void:
state._handle(delta)
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:
look_at_node.add_to_group("camera_target")
elif is_camera_target and not is_close:
look_at_node.remove_from_group("camera_target")
func _physics_process(delta: float):
state._handle_physics(delta)
func request_state_init():
state = PlayerStateInit.new(self)
func request_state_normal():
state = PlayerStateNormal.new(self)
func request_state_forced(dir: String):
if state is PlayerStateForced: return
state = PlayerStateForced.new(self, dir)
func request_state_curve(curve: Curve2D, c_speed: float, c_reverse: bool):
if state is PlayerStateCurve: return
state = PlayerStateCurve.new(self, curve, c_speed, c_reverse)
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)
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 request_state_dead():
if state is PlayerStateDead: return false
state = PlayerStateDead.new(self)
func get_facing() -> int:
if anim_sp.flip_h:
return -1
else:
return 1
func handle_action_input():
if inventory.zoop and _try_action_zoop(): return
if inventory.hanging and _try_action_hang(): return
func _try_action_hang() -> bool:
var hooks = get_tree().get_nodes_in_group("hook_hanging")
for hook_any in hooks:
var hook: HookHanging = hook_any as HookHanging
if request_state_hanging(hook): return true
return false
func _try_action_zoop():
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 true
return false
const walk_sfx_interval_ms = 300
var last_walk_sfx_time = -INF
func request_play_walk_sfx():
var now = Time.get_ticks_msec()
if now - last_walk_sfx_time > walk_sfx_interval_ms:
walk_audio.pitch_scale = 1 + 1 * randf()
walk_audio.volume_db = -3 + 0.5 * randf()
walk_audio.play()
last_walk_sfx_time = now
func request_play_jump_sfx():
jump_audio.pitch_scale = 0.95 + 0.1 * randf()
jump_audio.volume_db = -0.5 + 0.5 * randf()
jump_audio.play()
func request_play_die_sfx():
die_audio.play()
func request_play_fanfare_sfx():
fanfare_audio.play()
|