55 lines
1.5 KiB
GDScript
55 lines
1.5 KiB
GDScript
extends Node2D
|
||
|
||
@export var binded_rock: Rock
|
||
@export var binded_volumn: PlayerTriggerVolumn
|
||
|
||
var _rock : Rock
|
||
var _volumn : PlayerTriggerVolumn
|
||
|
||
func _ready() -> void:
|
||
_rock = binded_rock if binded_rock != null else _find_first_rock(self)
|
||
_volumn = binded_volumn if binded_volumn != null else _find_first_volumn(self)
|
||
|
||
if not _volumn or not _rock: return
|
||
|
||
_volumn.player_entered.connect(_on_rock_start_shake,CONNECT_ONE_SHOT)
|
||
|
||
func _on_rock_start_shake(player: Player) -> void:
|
||
if not _rock: return
|
||
|
||
_rock.start_shaking()
|
||
$Timer.start()
|
||
$Timer.timeout.connect(_on_rock_falling)
|
||
|
||
func _on_rock_falling() -> void:
|
||
_rock.stop_shaking()
|
||
_rock.start_falling()
|
||
|
||
|
||
## ================================
|
||
## 查找工具函数(强类型)
|
||
## ================================
|
||
|
||
func _find_first_rock(root: Node) -> Rock:
|
||
var found: Node = _find_first_child_matching(root, func(n: Node) -> bool: return n is Rock)
|
||
return found as Rock
|
||
|
||
|
||
func _find_first_volumn(root: Node) -> PlayerTriggerVolumn:
|
||
var found: Node = _find_first_child_matching(root, func(n: Node) -> bool: return n is PlayerTriggerVolumn)
|
||
return found as PlayerTriggerVolumn
|
||
|
||
|
||
func _find_first_child_matching(root: Node, predicate: Callable) -> Node:
|
||
for child: Node in root.get_children():
|
||
# predicate.call() 返回值在类型系统里可能是 Variant,所以别用 := 推断
|
||
var ok: bool = bool(predicate.call(child))
|
||
if ok:
|
||
return child
|
||
|
||
var deeper: Node = _find_first_child_matching(child, predicate)
|
||
if deeper != null:
|
||
return deeper
|
||
|
||
return null
|