feat: add crayfish npc to square map

This commit is contained in:
2026-03-10 22:51:38 +08:00
parent 64b9931eac
commit fa38b75d8f
4 changed files with 114 additions and 19 deletions

View File

@@ -1,29 +1,55 @@
extends CharacterBody2D
signal interaction_happened(text)
# ============================================================================
# 文件名: NPCController.gd
# 作用: 通用 NPC 控制器,负责角色待机表现与交互对话
#
# 主要功能:
# - 播放 NPC 待机动画
# - 响应玩家射线交互
# - 触发聊天气泡与 NPC 对话事件
#
# 依赖: EventSystem, EventNames, ChatBubble
# 作者: Codex
# 创建时间: 2026-03-10
# ============================================================================
signal interaction_happened(text: String)
const CHAT_BUBBLE_SCENE: PackedScene = preload("res://scenes/ui/ChatBubble.tscn")
@export var npc_name: String = "NPC"
@export var dialogue: String = "欢迎来到WhaleTown我是镇长范鲸晶"
@export_multiline var dialogue: String = "欢迎来到WhaleTown我是镇长范鲸晶"
func _ready():
$Sprite2D.texture = preload("res://assets/characters/npc_286_241.png")
$Sprite2D.hframes = 4
$Sprite2D.vframes = 4
# Start Idle Animation
if has_node("AnimationPlayer"):
$AnimationPlayer.play("idle")
# Ensure interaction layer
collision_layer = 3 # Layer 1 & 2 (Blocking)
@onready var animation_player: AnimationPlayer = $AnimationPlayer
func _ready() -> void:
# 播放场景里配置好的待机动画,让不同 NPC 可以复用同一个控制器。
if animation_player.has_animation("idle"):
animation_player.play("idle")
# 保持 NPC 可被玩家射线与角色碰撞识别。
collision_layer = 3
collision_mask = 3
func interact():
# 处理玩家交互,展示气泡并向全局事件系统广播。
func interact() -> void:
show_bubble(dialogue)
EventSystem.emit_event(EventNames.NPC_TALKED, {
"npc": self,
"npc_name": npc_name,
"dialogue": dialogue
})
interaction_happened.emit(dialogue)
return null
func show_bubble(text):
var bubble = preload("res://scenes/ui/ChatBubble.tscn").instantiate()
# 在 NPC 头顶生成一次性聊天气泡。
#
# 参数:
# text: String - 要展示的对话内容
func show_bubble(text: String) -> void:
var bubble: Control = CHAT_BUBBLE_SCENE.instantiate() as Control
if bubble == null:
return
add_child(bubble)
bubble.set_text(text)
if bubble.has_method("set_text"):
bubble.call("set_text", text)