八音盒提示;draggable 优化
This commit is contained in:
parent
c5ad2e56c8
commit
85392b08ea
@ -36,7 +36,8 @@ ui_center_notify_use_prop,按 E 使用道具,,,,,Press E to use item
|
|||||||
ui_center_notify_check_note,按 N 查看线索笔记,,,,,Press N to check clue notes
|
ui_center_notify_check_note,按 N 查看线索笔记,,,,,Press N to check clue notes
|
||||||
ui_center_notify_check_bag,按 B 查看重要物品,,,,,Press B to check important items
|
ui_center_notify_check_bag,按 B 查看重要物品,,,,,Press B to check important items
|
||||||
ui_center_notify_right_click_prop,右键点击可检阅道具,,,,,Right-click to examine item
|
ui_center_notify_right_click_prop,右键点击可检阅道具,,,,,Right-click to examine item
|
||||||
ui_left_mouse_shave,按住鼠标拖拽可刮开海报,,,,,Hold and drag mouse to scrape off poster
|
ui_center_notify_drag_to_rotate,按住拖拽可旋转把手,,,,,Hold and drag to rotate the handle
|
||||||
|
ui_left_mouse_shave,按住拖拽可刮开海报,,,,,Hold and drag to scrape off poster
|
||||||
ui_switch_prop,点击图标可切换道具(或按 Z/C),,,,,Click icon to switch items (or press Z/C)
|
ui_switch_prop,点击图标可切换道具(或按 Z/C),,,,,Click icon to switch items (or press Z/C)
|
||||||
ui_press_shift,按住 Shift 奔跑,,,,,Hold Shift to run
|
ui_press_shift,按住 Shift 奔跑,,,,,Hold Shift to run
|
||||||
ui_boxcat_press_s,按住 S 躲藏,,,,,Hold S to hide
|
ui_boxcat_press_s,按住 S 躲藏,,,,,Hold S to hide
|
||||||
|
|
@ -46,7 +46,8 @@
|
|||||||
按 N 查看线索笔记 [ID:ui_center_notify_check_note]
|
按 N 查看线索笔记 [ID:ui_center_notify_check_note]
|
||||||
按 B 查看重要物品 [ID:ui_center_notify_check_bag]
|
按 B 查看重要物品 [ID:ui_center_notify_check_bag]
|
||||||
右键点击可检阅道具 [ID:ui_center_notify_right_click_prop]
|
右键点击可检阅道具 [ID:ui_center_notify_right_click_prop]
|
||||||
按住鼠标拖拽可刮开海报 [ID:ui_left_mouse_shave]
|
按住拖拽可旋转把手 [ID:ui_center_notify_drag_to_rotate]
|
||||||
|
按住拖拽可刮开海报 [ID:ui_left_mouse_shave]
|
||||||
点击图标可切换道具(或按 Z/C) [ID:ui_switch_prop]
|
点击图标可切换道具(或按 Z/C) [ID:ui_switch_prop]
|
||||||
按住 Shift 奔跑 [ID:ui_press_shift]
|
按住 Shift 奔跑 [ID:ui_press_shift]
|
||||||
按住 S 躲藏 [ID:ui_boxcat_press_s]
|
按住 S 躲藏 [ID:ui_boxcat_press_s]
|
||||||
|
@ -33,7 +33,27 @@ signal dropped(node: Draggable2D)
|
|||||||
sprite.texture = texture
|
sprite.texture = texture
|
||||||
@export var limit_rect := Rect2(Vector2.ZERO, Vector2(564, 316))
|
@export var limit_rect := Rect2(Vector2.ZERO, Vector2(564, 316))
|
||||||
|
|
||||||
@onready var sprite = $Sprite2D as Sprite2D
|
@onready var sprite: Sprite2D = $Sprite2D
|
||||||
|
|
||||||
|
# Whether the item is currently being held by the player
|
||||||
|
var holding := false:
|
||||||
|
set(val):
|
||||||
|
if holding != val:
|
||||||
|
holding = val
|
||||||
|
var touching := false
|
||||||
|
|
||||||
|
# 静态变量优化:使用对象引用而非字符串
|
||||||
|
static var current_focusing_node: Draggable2D = null
|
||||||
|
static var pending_enter_callables: Array[Callable] = []
|
||||||
|
|
||||||
|
# 缓存常量
|
||||||
|
const OUTLINE_THICKNESS := 1.0
|
||||||
|
const OUTLINE_TWEEN_DURATION := 0.2
|
||||||
|
const BUTTON_ALPHA_DURATION := 0.15
|
||||||
|
|
||||||
|
# 缓存变量
|
||||||
|
var _outline_tween: Tween
|
||||||
|
var _button_tween: Tween
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
@ -42,25 +62,18 @@ func _ready() -> void:
|
|||||||
if Engine.is_editor_hint():
|
if Engine.is_editor_hint():
|
||||||
return
|
return
|
||||||
# 初始化隐藏白边
|
# 初始化隐藏白边
|
||||||
sprite.material.set("shader_parameter/thickness", 0.0)
|
sprite.material.set_shader_parameter("thickness", 0.0)
|
||||||
|
|
||||||
|
# 安全检查
|
||||||
|
if has_signal("mouse_entered"):
|
||||||
mouse_entered.connect(_on_mouse_entered)
|
mouse_entered.connect(_on_mouse_entered)
|
||||||
mouse_exited.connect(_on_mouse_exited)
|
mouse_exited.connect(_on_mouse_exited)
|
||||||
|
else:
|
||||||
|
printerr("Draggable2D: mouse_entered or mouse_exited signal not found.")
|
||||||
# Whether the item is currently being held by the player
|
|
||||||
var holding = false
|
|
||||||
var touching = false
|
|
||||||
|
|
||||||
static var current_focusing_item = "":
|
|
||||||
set(val):
|
|
||||||
current_focusing_item = val
|
|
||||||
if GlobalConfig.DEBUG:
|
|
||||||
print("current_focusing_item=", current_focusing_item)
|
|
||||||
static var pending_enter_callables := [] as Array[Callable]
|
|
||||||
|
|
||||||
|
|
||||||
func is_focused() -> bool:
|
func is_focused() -> bool:
|
||||||
return current_focusing_item == item_name
|
return current_focusing_node == self
|
||||||
|
|
||||||
|
|
||||||
func _on_mouse_entered() -> bool:
|
func _on_mouse_entered() -> bool:
|
||||||
@ -69,12 +82,14 @@ func _on_mouse_entered() -> bool:
|
|||||||
return false
|
return false
|
||||||
if holding or is_focused():
|
if holding or is_focused():
|
||||||
return true
|
return true
|
||||||
# 尝试获得 current_focusing_item
|
|
||||||
if current_focusing_item != "":
|
# 尝试获得 current_focusing_node
|
||||||
|
if current_focusing_node:
|
||||||
if not pending_enter_callables.has(_on_mouse_entered):
|
if not pending_enter_callables.has(_on_mouse_entered):
|
||||||
pending_enter_callables.append(_on_mouse_entered)
|
pending_enter_callables.append(_on_mouse_entered)
|
||||||
return false
|
return false
|
||||||
current_focusing_item = item_name
|
|
||||||
|
current_focusing_node = self
|
||||||
_toggle_outline(true)
|
_toggle_outline(true)
|
||||||
return true
|
return true
|
||||||
|
|
||||||
@ -82,53 +97,51 @@ func _on_mouse_entered() -> bool:
|
|||||||
func _on_mouse_exited() -> void:
|
func _on_mouse_exited() -> void:
|
||||||
touching = false
|
touching = false
|
||||||
pending_enter_callables.erase(_on_mouse_entered)
|
pending_enter_callables.erase(_on_mouse_entered)
|
||||||
# frezzing 不影响 mouse exited
|
# freezing 不影响 mouse exited
|
||||||
if is_focused():
|
if is_focused() and not holding:
|
||||||
current_focusing_item = ""
|
current_focusing_node = null
|
||||||
for c in pending_enter_callables:
|
while pending_enter_callables.size() > 0:
|
||||||
|
var c = pending_enter_callables.pop_front()
|
||||||
if c.call():
|
if c.call():
|
||||||
break
|
break
|
||||||
_toggle_outline(false)
|
_toggle_outline(false)
|
||||||
|
|
||||||
|
|
||||||
func _notification(what: int) -> void:
|
|
||||||
if what == NOTIFICATION_PREDELETE:
|
|
||||||
if holding:
|
|
||||||
_drop()
|
|
||||||
elif touching:
|
|
||||||
_on_mouse_exited()
|
|
||||||
|
|
||||||
|
|
||||||
func _input(event: InputEvent) -> void:
|
func _input(event: InputEvent) -> void:
|
||||||
if freezing or Engine.is_editor_hint() or not is_visible_in_tree():
|
if freezing or Engine.is_editor_hint() or not is_visible_in_tree():
|
||||||
return
|
return
|
||||||
if event is InputEventMouseButton:
|
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
|
||||||
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
|
if is_focused() and not holding:
|
||||||
# Trigger the pick action
|
get_viewport().set_input_as_handled()
|
||||||
if touching and not holding:
|
_try_pick.call_deferred()
|
||||||
_try_pick()
|
|
||||||
elif holding:
|
elif holding:
|
||||||
|
get_viewport().set_input_as_handled()
|
||||||
_drop()
|
_drop()
|
||||||
elif holding and event is InputEventMouseMotion:
|
elif holding and event is InputEventMouseMotion:
|
||||||
_update_pos_to_mouse()
|
_update_pos_to_mouse()
|
||||||
|
|
||||||
|
|
||||||
func _update_pos_to_mouse():
|
func _update_pos_to_mouse() -> void:
|
||||||
# update global position
|
# update global position
|
||||||
global_position = get_global_mouse_position()
|
var target_pos = get_global_mouse_position()
|
||||||
global_position.x = clamp(global_position.x, limit_rect.position.x, limit_rect.end.x)
|
global_position.x = clamp(target_pos.x, limit_rect.position.x, limit_rect.end.x)
|
||||||
global_position.y = clamp(global_position.y, limit_rect.position.y, limit_rect.end.y)
|
global_position.y = clamp(target_pos.y, limit_rect.position.y, limit_rect.end.y)
|
||||||
|
|
||||||
|
|
||||||
func _try_pick() -> void:
|
func _try_pick() -> void:
|
||||||
if act_as_button:
|
if act_as_button:
|
||||||
# 作为按钮,发送 picked 信号
|
# 作为按钮,发送 picked 信号
|
||||||
picked.emit(self)
|
picked.emit(self)
|
||||||
var tween = create_tween()
|
if _button_tween and _button_tween.is_running():
|
||||||
tween.tween_property(sprite.material, "shader_parameter/alpha_ratio", 1.0, 0.15)
|
_button_tween.kill()
|
||||||
|
_button_tween = create_tween()
|
||||||
|
_button_tween.tween_property(sprite.material, "shader_parameter/alpha_ratio", 1.0, BUTTON_ALPHA_DURATION)
|
||||||
return
|
return
|
||||||
if current_focusing_item != item_name:
|
|
||||||
|
if not is_focused():
|
||||||
return
|
return
|
||||||
|
|
||||||
# reset rotation
|
# reset rotation
|
||||||
rotation = 0
|
rotation = 0
|
||||||
_toggle_outline(false)
|
_toggle_outline(false)
|
||||||
@ -139,25 +152,47 @@ func _try_pick() -> void:
|
|||||||
|
|
||||||
|
|
||||||
func _drop() -> void:
|
func _drop() -> void:
|
||||||
|
if touching:
|
||||||
|
_toggle_outline(true)
|
||||||
if holding:
|
if holding:
|
||||||
holding = false
|
holding = false
|
||||||
|
if not touching:
|
||||||
|
current_focusing_node = null
|
||||||
|
# 清空数组前创建副本,避免在迭代时修改数组
|
||||||
|
var callables_copy = pending_enter_callables.duplicate()
|
||||||
|
for c in callables_copy:
|
||||||
|
if c.call():
|
||||||
|
break
|
||||||
# z_index -= 1
|
# z_index -= 1
|
||||||
dropped.emit(self)
|
dropped.emit(self)
|
||||||
if is_focused():
|
|
||||||
_toggle_outline(true)
|
|
||||||
else:
|
|
||||||
# not touching but dropped, remove current_focusing_item if any
|
|
||||||
current_focusing_item = ""
|
|
||||||
|
|
||||||
|
|
||||||
func _toggle_outline(display = true):
|
func _toggle_outline(display: bool) -> void:
|
||||||
var tween = create_tween()
|
# 避免重复创建 tween
|
||||||
if display:
|
if _outline_tween and _outline_tween.is_running():
|
||||||
tween.tween_property(sprite.material, "shader_parameter/thickness", 1.0, 0.2)
|
_outline_tween.kill()
|
||||||
else:
|
|
||||||
tween.tween_property(sprite.material, "shader_parameter/thickness", 0.0, 0.2)
|
_outline_tween = create_tween()
|
||||||
|
var target_thickness := OUTLINE_THICKNESS if display else 0.0
|
||||||
|
_outline_tween.tween_property(
|
||||||
|
sprite.material, "shader_parameter/thickness", target_thickness, OUTLINE_TWEEN_DURATION
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
func _exit_tree() -> void:
|
func _exit_tree() -> void:
|
||||||
if touching:
|
if touching:
|
||||||
_on_mouse_exited()
|
_on_mouse_exited()
|
||||||
|
# 清理静态引用,避免内存泄漏
|
||||||
|
if current_focusing_node == self:
|
||||||
|
current_focusing_node = null
|
||||||
|
|
||||||
|
|
||||||
|
func force_hold() -> void:
|
||||||
|
if holding:
|
||||||
|
return
|
||||||
|
if not is_focused() and current_focusing_node:
|
||||||
|
current_focusing_node._drop()
|
||||||
|
_toggle_outline(false)
|
||||||
|
current_focusing_node = self
|
||||||
|
holding = true
|
||||||
|
picked.emit(self)
|
@ -291,6 +291,7 @@ func _chechout_stage(s: int, play_sfx := true) -> void:
|
|||||||
if play_sfx:
|
if play_sfx:
|
||||||
sfx_open_lid.play()
|
sfx_open_lid.play()
|
||||||
3:
|
3:
|
||||||
|
SceneManager.pop_center_notification("ui_center_notify_drag_to_rotate")
|
||||||
box_opened.visible = true
|
box_opened.visible = true
|
||||||
d4.visible = true
|
d4.visible = true
|
||||||
if pic:
|
if pic:
|
||||||
|
Loading…
Reference in New Issue
Block a user