xiandie/scene/entity/hd_entity.gd

125 lines
2.8 KiB
GDScript

@tool
extends Node2D
signal sign_mark_offset_updated
# sign_mark 节点在 ready 时会直接读取
@export var sign_mark_offset := Vector2.ZERO:
set(val):
sign_mark_offset = val
sign_mark_offset_updated.emit(val)
@export var reload := false:
set(val):
_reload()
reload = false
@export var sprite_name := "name":
set(val):
if sprite_name and sprite_name != val:
_remove_sprite(sprite_name)
sprite_name = val
_reload()
@export var texture: Texture2D:
set(val):
texture = val
_reload()
@export var sprite_scale := 1.0:
set(val):
sprite_scale = val
_update_sprite_transform(true)
@export var sprite_ref: Sprite2D
const RATIO = 4.0
@onready var sign_mark = %Sign as Sign
@onready var area2d = %Area2D as Area2D
func _ready() -> void:
_reload()
set_notify_transform(true)
# set_notify_local_transform(true)
item_rect_changed.connect(_update_sprite_transform)
if Engine.is_editor_hint():
return
area2d.body_entered.connect(_reset)
area2d.body_exited.connect(_on_cancel)
sign_mark.interacted.connect(_on_interacted)
sign_mark.cancel.connect(_on_cancel)
func _notification(what: int) -> void:
if what == NOTIFICATION_TRANSFORM_CHANGED:
if not is_node_ready():
await ready
_update_sprite_transform()
func _reload():
if not texture or not sprite_name:
return
var layer = _get_hd_layer()
if not layer:
return
sprite_ref = layer.get_node_or_null(sprite_name) as Sprite2D
if not sprite_ref:
sprite_ref = Sprite2D.new()
layer.add_child(sprite_ref)
sprite_ref.owner = layer
sprite_ref.name = sprite_name
sprite_ref.texture = texture
sprite_ref.z_index = 0
sprite_ref.centered = true
sprite_ref.visible = true
_update_sprite_transform()
func _remove_sprite(sprite_node_name):
if sprite_ref:
sprite_ref.queue_free()
sprite_ref = null
if not sprite_name:
return
var layer = _get_hd_layer()
if layer:
var sprite = layer.get_node_or_null(sprite_node_name)
layer.remove_child(sprite)
sprite.queue_free()
func _get_hd_layer() -> CanvasLayer:
return get_node_or_null("../../SubViewportContainer/SubViewport/HdLayer") as CanvasLayer
func _update_sprite_transform(update_scale := false):
if not sprite_ref:
return
sprite_ref.global_position = global_position * RATIO
if update_scale:
sprite_ref.scale = Vector2(sprite_scale, sprite_scale)
var interacted = false
var cancel_time = 0.0
func _on_interacted() -> void:
if Time.get_ticks_msec() - cancel_time < 700:
return
if interacted:
_on_cancel()
return
interacted = true
SceneManager.get_camera_marker().tween_zoom(1.8)
SceneManager.focus_node(self)
# DialogueManager.show_dialogue_balloon(dialog, "diyizhang_01_03_mimi3")
func _on_cancel(_body = null):
SceneManager.focus_player_and_reset_zoom()
interacted = false
cancel_time = Time.get_ticks_msec()
func _reset(_body):
interacted = false