134 lines
3.4 KiB
GDScript
134 lines
3.4 KiB
GDScript
# @tool
|
|
extends Node2D
|
|
|
|
# @export var texture: Texture:
|
|
# set(val):
|
|
# texture = val
|
|
# sprite2d.texture = texture
|
|
# # @export var base_scale := Vector2.ONE:
|
|
# # set(val):
|
|
# # base_scale = val
|
|
# # sprite2d.scale = base_scale
|
|
@export var show_sign := true
|
|
@export var volume_db := -5.0:
|
|
set(val):
|
|
volume_db = val
|
|
if random_audio_player:
|
|
random_audio_player.volume_db = volume_db
|
|
@export var audio_collection: AudioStreamCollection:
|
|
set(val):
|
|
audio_collection = val
|
|
if random_audio_player:
|
|
random_audio_player.audio_collections.clear()
|
|
random_audio_player.audio_collections.append(audio_collection)
|
|
|
|
signal interacted
|
|
signal cancel
|
|
|
|
# 同时只能有一个物品被激活交互态,其他物品进入等待队列
|
|
static var occupied: NodePath
|
|
# 使用互斥锁保证线程安全
|
|
static var mutex = Mutex.new()
|
|
static var _pending_callables: Array[Callable]
|
|
var own_callable
|
|
|
|
var activated = false
|
|
var random_audio_player: RandomAudioStreamPlayer
|
|
|
|
# var sprite2d = Sprite2D.new()
|
|
var base_scale = Vector2.ONE
|
|
|
|
|
|
func _ready() -> void:
|
|
base_scale = scale
|
|
# layer = GlobalConfig.CANVAS_LAYER_FG
|
|
var point_light = get_node_or_null("../PointLight2D")
|
|
if point_light:
|
|
point_light.energy = 0.0
|
|
var area2d = get_node_or_null("../Area2D")
|
|
if area2d:
|
|
area2d.body_entered.connect(activate)
|
|
area2d.body_exited.connect(disactivate)
|
|
# # add child
|
|
# add_child(sprite2d)
|
|
# sprite2d.modulate.a = 0
|
|
# if Engine.is_editor_hint():
|
|
# sprite2d.modulate.a = 1
|
|
# _load_sprite()
|
|
modulate.a = 0
|
|
if audio_collection:
|
|
random_audio_player = RandomAudioStreamPlayer.new()
|
|
random_audio_player.audio_collections.append(audio_collection)
|
|
random_audio_player.bus = GlobalConfig.AUDIO_BUS_SFX
|
|
random_audio_player.volume_db = volume_db
|
|
add_child(random_audio_player)
|
|
|
|
|
|
# func _load_sprite() -> void:
|
|
# sprite2d.texture = texture
|
|
# sprite2d.scale = base_scale
|
|
|
|
|
|
func activate(_body: Node2D) -> void:
|
|
# point_light.energy = 1.0
|
|
mutex.lock()
|
|
if occupied and occupied != get_path():
|
|
own_callable = activate.bind(_body)
|
|
_pending_callables.append(own_callable)
|
|
else:
|
|
occupied = get_path()
|
|
activated = true
|
|
mutex.unlock()
|
|
if activated and show_sign:
|
|
var tween = create_tween()
|
|
tween.tween_property(self, "modulate:a", 1.0, 0.2)
|
|
var p_tween = tween.parallel()
|
|
p_tween.tween_property(self, "scale", base_scale * Vector2(1.2, 1.2), 0.3)
|
|
p_tween.tween_property(self, "scale", base_scale, 0.1)
|
|
|
|
|
|
func disactivate(_body: Node2D) -> void:
|
|
activated = false
|
|
if _unoccupy():
|
|
while _pending_callables.size() > 0:
|
|
var callable = _pending_callables.pop_front() as Callable
|
|
if callable.is_valid():
|
|
callable.call()
|
|
break
|
|
# point_light.energy = 0.0
|
|
if show_sign:
|
|
create_tween().tween_property(self, "modulate:a", 0.0, 0.2)
|
|
|
|
|
|
func _input(event: InputEvent) -> void:
|
|
if activated:
|
|
if event.is_action_pressed("interact"):
|
|
interacted.emit()
|
|
if show_sign and random_audio_player:
|
|
random_audio_player.play_random()
|
|
elif event.is_action_pressed("cancel"):
|
|
cancel.emit()
|
|
|
|
|
|
func _exit_tree() -> void:
|
|
if _unoccupy():
|
|
while _pending_callables.size() > 0:
|
|
var callable = _pending_callables.pop_front() as Callable
|
|
if callable.is_valid():
|
|
callable.call()
|
|
break
|
|
cancel.emit()
|
|
|
|
|
|
func _unoccupy() -> bool:
|
|
var self_occupied = false
|
|
mutex.lock()
|
|
if occupied == get_path():
|
|
occupied = ""
|
|
self_occupied = true
|
|
elif own_callable:
|
|
_pending_callables.erase(own_callable)
|
|
own_callable = null
|
|
mutex.unlock()
|
|
return self_occupied
|