Compare commits

...

3 Commits

12 changed files with 328 additions and 110 deletions

View File

@ -114,19 +114,20 @@ c01_s08_书店工钱,这个月的工钱还没拿。,,,,,I haven't collected this
mem_偷听对话,偷听对话,,,,,Eavesdropping
mem_疯子看井,疯子看井,,,,,Madman Guards Well
c01_鸡毛掸子,这是鸡毛掸子吗?,,,,,Is this a feather duster?
c01_院长书桌,桌上放着一本《圣经》。{br}「得著生命的,將要失喪生命...」,,,,,There's a Bible on the desk.{br}'Whoever finds their life will lose it...'
c01_院长书桌,桌上放着一本《圣经》。{br}「凡要救自己生命的,必丧掉生命...」,,,,,"There's a Bible on the table.{br}'Whoever wants to save their life will lose it, but whoever loses their life for me will find it...'"
c01_院长床,这本书已经看过了。{br}...那些句子是什么意思呢?,,,,,I've already read this book.{br}...What do those sentences mean?
c01_院长座钟,这西洋钟没坏的时候,走针会咔哒、咔哒地响...{br}停在未时一刻不动了。,,,,,"When this Western clock wasn't broken, the hands would tick and tock...{br}It's stopped at a quarter past one in the afternoon."
c01_院长座钟,咦?这西洋钟为什么倒着走?,,,,,Huh? Why is this Western clock running backwards?
c01_倾斜的洋相片,哇啊,这张洋相片要掉下来了!{br}我得做点什么...,,,,,"Oh no, this Western photograph is about to fall!{br}I need to do something..."
c01_摆正的洋相片,这是院长的儿子吗?,,,,,Is this the director's son?
c01_s06_院长房间,这是院长的房间,,,,,This is the director's room
c01_s06_小朋友房间,这是其他小朋友的房间,,,,,This is the other children's room
c01_s06_熟悉的墙画,墙上的画看起来好熟悉。{br}过去问问看吧,没准他们几个知道些什么。,,,,,The painting on the wall looks so familiar.{br}Let me go ask them. Maybe they know something.
c01_s06_四小孩对话结束,怪人、花、门...{br}他在找什么东西,或是什么人?,,,,,"Strange man, flowers, door...{br}What is he looking for, or who?"
c01_s06_四小孩对话结束,怪人、花...{br}有时候真搞不懂他们在说些什么。,,,,,"Strange people, flowers...{br}Sometimes I really don't understand what they're talking about."
c01_s07_钱碗,碗里只有一枚铜钱。,,,,,There's only one copper coin in the bowl.
c01_s07_获得报纸,这是什么?,,,,,What is this?
c01_s07_书店展柜,院长说,读一百本书,就可以成为无所不能的大人。{br}如果我再大一些,没准可以求店长把我留下,我会干很多活,也能吃苦...,,,,,"The director said that reading a hundred books would make me an all-capable adult.{br}If I were a bit older, maybe I could ask the shop owner to keep me. I'd work hard and endure hardship..."
c01_s08_书架游戏完成,这些书都被老鼠啃坏了,连木头架子都没放过。,,,,,"These books have all been gnawed by mice, even the wooden shelves weren't spared."
c01_s08_书架游戏完成,{br}刚才那是什么?,,,,,?!{br}What was that just now?
c01_s08_书架游戏恢复记忆,...{br}这是...我之前工作的地方。{br}...{br}现在老板不在了,我也该走了...,,,,,"...{br}This is... where I used to work.{br}...{br}Now that the boss is gone, I should leave too..."
c01_s08_获得袁大头后,工钱还在老地方。,,,,,The wages are still in the usual place.
c02_海报_剪辫子侦探,剪辫悬梁上侦探奇闻,,,,,Detective Tales of the Queue-Cutting Mystery
c02_海报_戏法班,朱连魁全班戏法——「各有幻女...演技新奇」,,,,,Zhu Liankui's Magic Troupe—'Each with enchanting women... performances most novel'

1 keys zh_CN _character _notes _tags zh_SH en
114 mem_偷听对话 偷听对话 Eavesdropping
115 mem_疯子看井 疯子看井 Madman Guards Well
116 c01_鸡毛掸子 这是鸡毛掸子吗? Is this a feather duster?
117 c01_院长书桌 桌上放着一本《圣经》。{br}「得著生命的,將要失喪生命...」 桌上放着一本《圣经》。{br}「凡要救自己生命的,必丧掉生命...」 There's a Bible on the desk.{br}'Whoever finds their life will lose it...' There's a Bible on the table.{br}'Whoever wants to save their life will lose it, but whoever loses their life for me will find it...'
118 c01_院长床 这本书已经看过了。{br}...那些句子是什么意思呢? I've already read this book.{br}...What do those sentences mean?
119 c01_院长座钟 这西洋钟没坏的时候,走针会咔哒、咔哒地响...{br}停在未时一刻不动了。 咦?这西洋钟为什么倒着走? When this Western clock wasn't broken, the hands would tick and tock...{br}It's stopped at a quarter past one in the afternoon. Huh? Why is this Western clock running backwards?
120 c01_倾斜的洋相片 哇啊,这张洋相片要掉下来了!{br}我得做点什么... Oh no, this Western photograph is about to fall!{br}I need to do something...
121 c01_摆正的洋相片 这是院长的儿子吗? Is this the director's son?
122 c01_s06_院长房间 这是院长的房间 This is the director's room
123 c01_s06_小朋友房间 这是其他小朋友的房间 This is the other children's room
124 c01_s06_熟悉的墙画 墙上的画看起来好熟悉。{br}过去问问看吧,没准他们几个知道些什么。 The painting on the wall looks so familiar.{br}Let me go ask them. Maybe they know something.
125 c01_s06_四小孩对话结束 怪人、花、门...{br}他在找什么东西,或是什么人? 怪人、花...{br}有时候真搞不懂他们在说些什么。 Strange man, flowers, door...{br}What is he looking for, or who? Strange people, flowers...{br}Sometimes I really don't understand what they're talking about.
126 c01_s07_钱碗 碗里只有一枚铜钱。 There's only one copper coin in the bowl.
127 c01_s07_获得报纸 这是什么? What is this?
128 c01_s07_书店展柜 院长说,读一百本书,就可以成为无所不能的大人。{br}如果我再大一些,没准可以求店长把我留下,我会干很多活,也能吃苦... The director said that reading a hundred books would make me an all-capable adult.{br}If I were a bit older, maybe I could ask the shop owner to keep me. I'd work hard and endure hardship...
129 c01_s08_书架游戏完成 这些书都被老鼠啃坏了,连木头架子都没放过。 ?!{br}刚才那是什么? These books have all been gnawed by mice, even the wooden shelves weren't spared. ?!{br}What was that just now?
130 c01_s08_书架游戏恢复记忆 ...{br}这是...我之前工作的地方。{br}...{br}现在老板不在了,我也该走了... ...{br}This is... where I used to work.{br}...{br}Now that the boss is gone, I should leave too...
131 c01_s08_获得袁大头后 工钱还在老地方。 The wages are still in the usual place.
132 c02_海报_剪辫子侦探 剪辫悬梁上侦探奇闻 Detective Tales of the Queue-Cutting Mystery
133 c02_海报_戏法班 朱连魁全班戏法——「各有幻女...演技新奇」 Zhu Liankui's Magic Troupe—'Each with enchanting women... performances most novel'

View File

@ -168,9 +168,9 @@
~ Notes_c01
# c01-s05 院长房间
这是鸡毛掸子吗? [ID:c01_鸡毛掸子]
桌上放着一本《圣经》。{br}「得著生命的,將要失喪生命...」 [ID:c01_院长书桌]
桌上放着一本《圣经》。{br}「凡要救自己生命的,必丧掉生命...」 [ID:c01_院长书桌]
这本书已经看过了。{br}...那些句子是什么意思呢? [ID:c01_院长床]
这西洋钟没坏的时候,走针会咔哒、咔哒地响...{br}停在未时一刻不动了。 [ID:c01_院长座钟]
咦?这西洋钟为什么倒着走? [ID:c01_院长座钟]
哇啊,这张洋相片要掉下来了!{br}我得做点什么... [ID:c01_倾斜的洋相片]
这是院长的儿子吗? [ID:c01_摆正的洋相片]
# c01-s06 院子
@ -178,13 +178,14 @@
这是其他小朋友的房间 [ID:c01_s06_小朋友房间]
# 院子里四个小孩交谈结束后
墙上的画看起来好熟悉。{br}过去问问看吧,没准他们几个知道些什么。 [ID:c01_s06_熟悉的墙画]
怪人、花、门...{br}他在找什么东西,或是什么人? [ID:c01_s06_四小孩对话结束]
怪人、花...{br}有时候真搞不懂他们在说些什么。 [ID:c01_s06_四小孩对话结束]
# c01-s07 书店外
碗里只有一枚铜钱。 [ID:c01_s07_钱碗]
这是什么? [ID:c01_s07_获得报纸]
院长说,读一百本书,就可以成为无所不能的大人。{br}如果我再大一些,没准可以求店长把我留下,我会干很多活,也能吃苦... [ID:c01_s07_书店展柜]
# c01-s08 书店
这些书都被老鼠啃坏了,连木头架子都没放过。 [ID:c01_s08_书架游戏完成]
{br}刚才那是什么? [ID:c01_s08_书架游戏完成]
...{br}这是...我之前工作的地方。{br}...{br}现在老板不在了,我也该走了... [ID:c01_s08_书架游戏恢复记忆]
工钱还在老地方。 [ID:c01_s08_获得袁大头后]
=> END

View File

@ -13,10 +13,11 @@ const RES_FILE_FORMAT = ".tres"
const CANVAS_LAYER_SETTINGS = 30
# note
const CANVAS_LAYER_NOTE = 25
# dialog
const CANVAS_LAYER_DIALOG = 24
const CANVAS_LAYER_MEM_ITEM = 23
const CANVAS_LAYER_UX_PANEL = 22
# dialog
const CANVAS_LAYER_DIALOG_MEM = 30
const CANVAS_LAYER_DIALOG = 22
# main 场景的 UI 层prop hud、上下mask、notification
const CANVAS_LAYER_UI = 21
# 道具 inspectorprop/local
@ -33,6 +34,8 @@ const CANVAS_LAYER_LITTLE_GAME = 5
const CANVAS_LAYER_FG = 2
const DIALOG_IGNORE_INPUT = "ignore_input"
# memory layer: 30
const DIALOG_MEM_LAYER = "mem_layer"
const CHARACTER_COLOR_MAP = {
"default": Color.LIGHT_SEA_GREEN,

View File

@ -153,6 +153,8 @@ func _notification(what: int) -> void:
func start(
dialogue_resource: DialogueResource, title: String, extra_game_states: Array = []
) -> void:
if extra_game_states.has(GlobalConfig.DIALOG_MEM_LAYER):
pass
temporary_game_states = [self] + extra_game_states
is_waiting_for_input = false
resource = dialogue_resource

View File

@ -10,7 +10,7 @@ func _ready() -> void:
var tween: Tween
func dizzy(duration := 3.5, intensity := 1.5):
func dizzy(duration := 3.5, intensity := 1.5) -> void:
if duration < 0.6:
return
if tween and tween.is_valid():

View File

@ -2,10 +2,15 @@
class_name Npc2D extends AnimatedSprite2D
signal interacted
# 在 unlock player 之前发射
signal talk_finished
signal talk_finished # 在 unlock player 之前发射
# <0 means no walk to edge
# 常量定义
const SPEAKING_SIGN_FADE_DURATION := 0.3
const SPEAKING_SCALE_MULTIPLIER := 1.3
enum SpeakingSignMode { HIDDEN = 0, SILENT = 1, SPEAKING = 2 }
# 导出变量
@export var snap_to_edge := true
@export var walk_to_edge_width := 25.0
@export var action_key := 4
@ -14,41 +19,47 @@ signal talk_finished
enabled = val
if is_node_ready():
_align_signs_status()
@export var sign_mark_height := 10.0:
set(val):
sign_mark_height = val
if is_node_ready():
if is_node_ready() and sign_mark:
sign_mark.sign_mark_offset.y = -sign_mark_height
@export var speaking_sign_height := 60.0:
set(val):
speaking_sign_height = val
if is_node_ready():
if is_node_ready() and speaking_sign:
speaking_sign.position.y = -speaking_sign_height
@export var sign_x_offset := 0.0:
set(val):
sign_x_offset = val
if is_node_ready():
speaking_sign.position.x = sign_x_offset
sign_mark.position.x = sign_x_offset
_update_sign_x_positions()
@export var collision_width_and_x := Vector2(20.0, 0):
set(val):
collision_width_and_x = val
if is_node_ready():
var shape = area2d.get_node("CollisionShape2D").shape
shape.size.x = collision_width_and_x.x
area2d.position.x = collision_width_and_x.y
_update_collision_shape()
# 节点引用
@onready var speaking_animation = %SpeakingAnimationPlayer
@onready var speaking_sign = %SpeakingSign2D as Node2D
@onready var sign_mark = %Sign as Sign
@onready var sign_snapper = %SignSnapper as SignSnapper
@onready var area2d = %Area2D as Area2D
# 内部变量
var ground_archive: GroundArchive
# 尝试互动的次数
var icount: int:
set(val):
if icount == val:
return
icount = val
ground_archive.set_pair(name, "icount", val)
if ground_archive:
ground_archive.set_pair(name, "icount", val)
_align_signs_status()
var dialogue_title := ""
@ -56,105 +67,246 @@ var dialogue_res = preload("res://asset/dialogue/npc.dialogue")
var base_scale := Vector2.ONE
var base_mod := Color.WHITE_SMOKE
var speaking_sign_tween: Tween
# 0 hide; 1 silent; 2 speaking
var speaking_sign_mode := 0:
var speaking_sign_mode := SpeakingSignMode.HIDDEN:
set(val):
if speaking_sign_mode != val:
speaking_sign_mode = val
if speaking_sign_tween and speaking_sign_tween.is_valid():
speaking_sign_tween.kill()
speaking_sign_tween = create_tween()
if val == 0:
speaking_sign_tween.tween_property(speaking_sign, "modulate:a", 0.0, 0.3)
speaking_animation.stop()
elif val == 1:
speaking_sign_tween.tween_property(speaking_sign, "modulate", base_mod, 0.3)
speaking_sign_tween.parallel().tween_property(
speaking_sign, "scale", base_scale, 0.3
)
speaking_animation.play("speaking")
elif val == 2:
speaking_sign_tween.tween_property(speaking_sign, "modulate", Color.WHITE, 0.3)
speaking_sign_tween.parallel().tween_property(
speaking_sign, "scale", base_scale * 1.3, 0.3
)
speaking_animation.play("speaking")
if speaking_sign_mode == val:
return
speaking_sign_mode = val
_update_speaking_sign_mode()
# 强制播放状态管理
var is_hooked := false
var hook_id := 0 # 用于追踪hook会话避免异步问题
func _ready() -> void:
# sign position
sign_mark.sign_mark_offset.y = -sign_mark_height
speaking_sign.position.y = -speaking_sign_height
sign_mark.position.x = sign_x_offset
speaking_sign.position.x = sign_x_offset
# collisiong shape
var shape = area2d.get_node("CollisionShape2D").shape
shape.size.x = collision_width_and_x.x
area2d.position.x = collision_width_and_x.y
sign_snapper.action_on_arrived = action_key
sign_snapper.radius = walk_to_edge_width
sign_snapper.enabled = snap_to_edge
# 设置 speaking_sign 默认值
base_scale = speaking_sign.scale
base_mod = speaking_sign.modulate
speaking_sign.modulate.a = 0.0
_initialize_components()
if Engine.is_editor_hint():
# editor 下都显示
_setup_editor_preview()
return
_setup_game_mode()
_align_signs_status()
func _initialize_components() -> void:
# 设置标记位置
if sign_mark:
sign_mark.sign_mark_offset.y = -sign_mark_height
sign_mark.position.x = sign_x_offset
if speaking_sign:
speaking_sign.position.y = -speaking_sign_height
speaking_sign.position.x = sign_x_offset
base_scale = speaking_sign.scale
base_mod = speaking_sign.modulate
speaking_sign.modulate.a = 0.0
# 设置碰撞形状
_update_collision_shape()
# 配置 sign_snapper
if sign_snapper:
sign_snapper.action_on_arrived = action_key
sign_snapper.radius = walk_to_edge_width
sign_snapper.enabled = snap_to_edge
func _setup_editor_preview() -> void:
if speaking_sign:
speaking_sign.visible = true
speaking_sign.modulate.a = 1.0
speaking_sign.get_node("Sprite2D").position.x = -60.0
speaking_sign.get_node("Sprite2D").frame = 2
var sprite = speaking_sign.get_node_or_null("Sprite2D")
if sprite:
sprite.position.x = -60.0
sprite.frame = 2
if sign_mark:
sign_mark.display_sign = true
return
# setup default value
func _setup_game_mode() -> void:
# 获取存档数据
ground_archive = ArchiveManager.archive.ground_archive()
icount = ground_archive.get_value(name, "icount", 0)
if snap_to_edge:
# 连接信号
if snap_to_edge and sign_snapper:
sign_snapper.arrived.connect(_on_interacted)
else:
elif sign_mark:
sign_mark.interacted.connect(_on_interacted)
# sign_mark.cancel.connect(_stop_speaking)
sign_mark.toggle_active.connect(_on_toggle_active)
if sign_mark:
sign_mark.toggle_active.connect(_on_toggle_active)
visibility_changed.connect(_on_visibility_changed)
# 开始动画
if sprite_frames and animation:
play()
func _update_sign_x_positions() -> void:
if speaking_sign:
speaking_sign.position.x = sign_x_offset
if sign_mark:
sign_mark.position.x = sign_x_offset
func _update_collision_shape() -> void:
if not area2d:
return
var collision_shape = area2d.get_node_or_null("CollisionShape2D")
if collision_shape and collision_shape.shape:
collision_shape.shape.size.x = collision_width_and_x.x
area2d.position.x = collision_width_and_x.y
func _update_speaking_sign_mode() -> void:
if not speaking_sign:
return
# 清理之前的补间动画
if speaking_sign_tween and speaking_sign_tween.is_valid():
speaking_sign_tween.kill()
speaking_sign_tween = create_tween()
match speaking_sign_mode:
SpeakingSignMode.HIDDEN:
speaking_sign_tween.tween_property(
speaking_sign, "modulate:a", 0.0, SPEAKING_SIGN_FADE_DURATION
)
if speaking_animation:
speaking_animation.stop()
SpeakingSignMode.SILENT:
speaking_sign_tween.tween_property(
speaking_sign, "modulate", base_mod, SPEAKING_SIGN_FADE_DURATION
)
speaking_sign_tween.parallel().tween_property(
speaking_sign, "scale", base_scale, SPEAKING_SIGN_FADE_DURATION
)
if speaking_animation:
speaking_animation.play("speaking")
SpeakingSignMode.SPEAKING:
speaking_sign_tween.tween_property(
speaking_sign, "modulate", Color.WHITE, SPEAKING_SIGN_FADE_DURATION
)
speaking_sign_tween.parallel().tween_property(
speaking_sign,
"scale",
base_scale * SPEAKING_SCALE_MULTIPLIER,
SPEAKING_SIGN_FADE_DURATION
)
if speaking_animation:
speaking_animation.play("speaking")
func _on_visibility_changed() -> void:
_align_signs_status()
func _align_signs_status():
sign_mark.enabled = enabled and is_visible_in_tree()
sign_mark.display_sign = icount == 0
speaking_sign.visible = enabled and icount > 0
func _align_signs_status() -> void:
if not is_node_ready():
return
var is_active = enabled and is_visible_in_tree()
if sign_mark:
sign_mark.enabled = is_active
sign_mark.display_sign = icount == 0
if speaking_sign:
speaking_sign.visible = enabled and (icount > 0 or is_hooked)
func _on_toggle_active(activated: bool) -> void:
# 如果处于hook状态不响应正常的toggle
if is_hooked:
return
if not activated:
speaking_sign_mode = 0
elif speaking_sign_mode == 0:
speaking_sign_mode = 1
speaking_sign_mode = SpeakingSignMode.HIDDEN
elif speaking_sign_mode == SpeakingSignMode.HIDDEN:
speaking_sign_mode = SpeakingSignMode.SILENT
func _on_interacted() -> void:
# play dialogue
if dialogue_title:
SceneManager.lock_player(0, action_key)
icount += 1
if not dialogue_title:
return
# 如果正在hook播放先取消hook
if is_hooked:
_cancel_hook()
SceneManager.lock_player(0, action_key)
icount += 1
if ground_archive:
ground_archive.set_pair(name, "icount", icount)
DialogueManager.show_dialogue_balloon(dialogue_res, dialogue_title)
interacted.emit()
var out_of_range = speaking_sign_mode == 0
speaking_sign_mode = 2
await DialogueManager.dialogue_ended
speaking_sign_mode = 0 if out_of_range else 1
# 在 unlock 之前发射
talk_finished.emit()
SceneManager.unlock_player()
DialogueManager.show_dialogue_balloon(dialogue_res, dialogue_title)
interacted.emit()
var was_out_of_range = speaking_sign_mode == SpeakingSignMode.HIDDEN
speaking_sign_mode = SpeakingSignMode.SPEAKING
await DialogueManager.dialogue_ended
speaking_sign_mode = SpeakingSignMode.HIDDEN if was_out_of_range else SpeakingSignMode.SILENT
talk_finished.emit()
SceneManager.unlock_player()
# 新增:强制播放说话动画
func hook_speaking() -> int:
# 强制显示说话气泡动画
# 返回值hook会话ID用于验证unhook的有效性
is_hooked = true
hook_id += 1
var current_hook_id = hook_id
# 确保speaking_sign可见
if speaking_sign and not speaking_sign.visible:
speaking_sign.visible = true
# 保存当前状态并切换到说话模式
speaking_sign_mode = SpeakingSignMode.SPEAKING
return current_hook_id
# 新增:退出强制播放
func unhook_speaking(session_id: int = -1) -> void:
# 退出强制播放模式
# 参数:
# session_id: hook会话ID如果不匹配则忽略此次unhook
# 如果已经不在hook状态或session_id不匹配则忽略
if not is_hooked or (session_id != -1 and session_id != hook_id):
return
_cancel_hook()
# 新增内部取消hook的方法
func _cancel_hook() -> void:
# 内部使用的取消hook方法
is_hooked = false
# 恢复到适当的状态
if sign_mark and sign_mark.activated:
speaking_sign_mode = SpeakingSignMode.SILENT
else:
speaking_sign_mode = SpeakingSignMode.HIDDEN
# 重新对齐显示状态
_align_signs_status()
# 新增检查是否正在hook播放
func is_hook_speaking() -> bool:
"""返回当前是否处于强制播放状态"""
return is_hooked
func _get(property: StringName) -> Variant:
@ -172,8 +324,9 @@ func _set(property: StringName, value: Variant) -> bool:
func _get_property_list() -> Array[Dictionary]:
var hint_str = ""
if Engine.is_editor_hint():
if Engine.is_editor_hint() and dialogue_res:
hint_str = ",".join(dialogue_res.get_ordered_titles())
return [
{
"name": "dialogue_title",

View File

@ -94,8 +94,10 @@ func pre_game_intro():
var p = $"../DeployLayer/四小孩画鬼差的对话ambush/FocusPoint"
camera.focus_node(p, 3.0)
await Util.wait(2.0)
_hook_npc3_speaking()
DialogueManager.show_dialogue_balloon(dialogue_c01, "c01_s06_四个小孩画鬼差的对话")
await DialogueManager.dialogue_ended
_unhook_npc3_speaking()
# 重置镜头
SceneManager.focus_player_and_reset_zoom(2.5)
await Util.wait(2.5)
@ -123,14 +125,17 @@ func game_intro() -> void:
# DialogueManager.show_dialogue_balloon(
# dialogue_c01, "c01_s06_谈论鬼差与猫鼠游戏", [GlobalConfig.DIALOG_IGNORE_INPUT]
# )
_hook_npc3_speaking()
DialogueManager.show_dialogue_balloon(dialogue_c01, "c01_s06_谈论鬼差与猫鼠游戏")
DialogueManager.dialogue_ended.connect(_game_counting_down, CONNECT_ONE_SHOT)
await DialogueManager.dialogue_ended
_game_counting_down()
func _game_counting_down(_res = null):
$"Sfx猫鼠游戏".play()
DialogueManager.show_dialogue_balloon(dialogue_c01, "c01_s06_猫鼠游戏BGM开始")
await DialogueManager.dialogue_ended
_unhook_npc3_speaking()
# 重置镜头
SceneManager.focus_player_and_reset_zoom(2.5)
SceneManager.release_player()
@ -145,6 +150,14 @@ func _game_counting_down(_res = null):
cat.get_node("猫咪嘶吼音效").play()
func _hook_npc3_speaking(_res = null) -> void:
game_kid.get_node("Npc对话3").hook_speaking()
func _unhook_npc3_speaking(_res = null) -> void:
game_kid.get_node("Npc对话3").unhook_speaking()
# 玩家与三个小孩的互动计数
func _on_talked(id: int):
#talk count

View File

@ -71,7 +71,7 @@ func _knock_door():
await Util.wait(2.2)
$"敲门音效".play()
await Util.wait(1.2)
var stream = preload("res://asset/audio/sfx/交互/序章/03_书店外黄昏_开门.ogg")
var stream = preload("uid://ehgd455wq8to")
AudioManager.play_sfx(stream)
@ -95,3 +95,14 @@ func seller_interacted():
# 播放获得动画
SceneManager.enable_prop_item("prop_信碎片2")
SceneManager.release_player()
func jiandu_dialog_triggered() -> void:
var jiandu = $"../DeployLayer/举碗小孩/Npc监督小孩"
jiandu.hook_speaking()
DialogueManager.dialogue_ended.connect(_on_jiandu_dialog_ended, CONNECT_ONE_SHOT)
func _on_jiandu_dialog_ended(_res) -> void:
var jiandu = $"../DeployLayer/举碗小孩/Npc监督小孩"
jiandu.unhook_speaking()

View File

@ -203,12 +203,6 @@ sprite_frames = ExtResource("6_thm8f")
animation = &"杂戏团黄昏-其余小孩"
autoplay = "杂戏团黄昏-其余小孩"
[node name="Ambush监督小孩" parent="Ground/DeployLayer/其余小孩" instance=ExtResource("9_f61dl")]
position = Vector2(-688, 53)
cooldown_time = 0.1
lock_player_on_playing_dialogue = false
hook_dialogue_title = "c01_s07_监督小孩吉祥话"
[node name="Npc吉祥话1" parent="Ground/DeployLayer/其余小孩" instance=ExtResource("6_fw22n")]
position = Vector2(-44, 78)
sign_mark_height = 23.0
@ -237,6 +231,20 @@ autoplay = "杂戏团黄昏_举碗小孩"
position = Vector2(6, 57)
note_key = "c01_s07_钱碗"
[node name="Npc监督小孩" parent="Ground/DeployLayer/举碗小孩" instance=ExtResource("6_fw22n")]
position = Vector2(6, 72)
snap_to_edge = false
enabled = false
sign_mark_height = 11.0
speaking_sign_height = 54.0
[node name="Ambush监督小孩" parent="Ground/DeployLayer/举碗小孩" instance=ExtResource("9_f61dl")]
position = Vector2(-825, 53)
cooldown_time = 0.1
lock_player_on_playing_dialogue = false
hook_dialogue_title = "c01_s07_监督小孩吉祥话"
hook_method = "jiandu_dialog_triggered"
[node name="报童" parent="Ground/DeployLayer" index="10" instance=ExtResource("9_slaub")]
position = Vector2(2080, 6)
sprite_frames = ExtResource("6_thm8f")

View File

@ -33,6 +33,7 @@ var shelf_game_success = false
var envelope_game_success = false
var manager
var mice
var fall_off
func _on_ground_ready() -> void:
@ -44,6 +45,7 @@ func _on_ground_ready() -> void:
coin = $"../DeployLayer/Ambush银元"
mice = $"../DeployLayer/自动跟随的老鼠"
manager = $"../DeployLayer/老板"
fall_off = $"../DeployLayer/小小蝶坠落"
# 首先放报纸,触发动画,领取任务
if counter.interacted_times > 0:
ladder.enabled = true
@ -127,9 +129,6 @@ func _on_shelf_game_exiting() -> void:
SceneManager.release_player()
var fall_off
func _on_shelf_game_success() -> void:
ArchiveManager.set_global_entry(&"c01_shelf_game_success", true)
shelf_game_success = true
@ -143,7 +142,6 @@ func _on_shelf_game_success() -> void:
# 相机抖动
SceneManager.get_camera_marker().shake_camera()
# 播放小蝶从书架跌倒的动画
fall_off = $"../DeployLayer/小小蝶坠落"
fall_off.visible = true
fall_off.play()
fall_off.animation_finished.connect(_on_fall_off_finished)
@ -154,11 +152,16 @@ func _on_shelf_game_success() -> void:
func _on_fall_off_finished() -> void:
fall_off.visible = false
SceneManager.get_player().hide_sprite = false
await Util.wait(0.3)
await SceneManager.pop_os_with_str("c01_s08_书架游戏完成")
# 耳鸣与眩晕
$"Sfx头痛耳鸣".play()
$"../DizzyShader".dizzy()
await Util.wait(2.5)
await SceneManager.pop_os_with_str("c01_s08_书架游戏恢复记忆")
# 最后释放玩家
SceneManager.release_player()
SceneManager.get_player().hide_sprite = false
await Util.wait(1.2)
SceneManager.pop_os_with_str("c01_s08_书架游戏完成")
func _setup_weird_bookstore() -> void:

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=21 format=3 uid="uid://cwu4dhayra8pg"]
[gd_scene load_steps=23 format=3 uid="uid://cwu4dhayra8pg"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_b3cca"]
[ext_resource type="Script" uid="uid://6q2pfbqsw10t" path="res://scene/ground/scene/c01/s08_书店.gd" id="2_0lque"]
@ -16,7 +16,9 @@
[ext_resource type="AudioStream" uid="uid://bnjyw5v85s6qe" path="res://asset/audio/sfx/交互/序章/04_书店内_主角摔倒.ogg" id="8_p6k3c"]
[ext_resource type="Texture2D" uid="uid://bho8xal4ha50l" path="res://asset/art/scene/c01/s08_书店/l_打光.png" id="9_i4dqp"]
[ext_resource type="AudioStream" uid="uid://cniawn37n8888" path="res://asset/audio/sfx/交互/序章/04_书店内_递交报纸.ogg" id="9_lfr41"]
[ext_resource type="AudioStream" uid="uid://b8sbtn3l37uh" path="res://asset/audio/sfx/旧版/c02/红屏.ogg" id="9_srknn"]
[ext_resource type="Texture2D" uid="uid://bp4y3vujvsl7r" path="res://asset/art/scene/c01/s08_书店/fg_前景.png" id="10_4e3a1"]
[ext_resource type="PackedScene" uid="uid://decfqoe5v0y6n" path="res://scene/effect/dizzy_shader.tscn" id="18_wg16e"]
[sub_resource type="AnimationLibrary" id="AnimationLibrary_xqgjo"]
@ -81,6 +83,12 @@ bus = &"game_sfx"
script = ExtResource("4_p6k3c")
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="Sfx头痛耳鸣" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="5"]
stream = ExtResource("9_srknn")
bus = &"game_sfx"
script = ExtResource("4_p6k3c")
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="BGSprite2D" parent="Ground" index="2"]
material = SubResource("ShaderMaterial_ddd5v")
texture = ExtResource("3_322m4")
@ -198,6 +206,8 @@ points = PackedVector2Array(22, 150, 545, 150)
energy = 0.0
blend_mode = 1
[node name="DizzyShader" parent="Ground" instance=ExtResource("18_wg16e")]
[node name="参考" type="Sprite2D" parent="."]
visible = false
modulate = Color(1, 1, 1, 0.580392)

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=11 format=3 uid="uid://c4ycvdsabi7lw"]
[gd_scene load_steps=12 format=3 uid="uid://c4ycvdsabi7lw"]
[ext_resource type="Script" uid="uid://b4rw4hk7ns4m8" path="res://scene/index_page.gd" id="1_c7y7r"]
[ext_resource type="Texture2D" uid="uid://bcc0bk34l5gbc" path="res://asset/art/ui/index/菜单背景.png" id="1_jxn4k"]
@ -6,6 +6,7 @@
[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="3_5oc6i"]
[ext_resource type="Script" uid="uid://bbg4vopj4apl6" path="res://scene/entity/audio/bgm_control.gd" id="4_5oc6i"]
[ext_resource type="AudioStream" uid="uid://b3b4a6nm8557i" path="res://asset/audio/专用/衔蝶_主菜单music剪辑人声版.ogg" id="5_5oc6i"]
[ext_resource type="FontFile" uid="uid://bjmhscwn1ixj1" path="res://asset/font/字体/ChillJinshuSongMedium.otf" id="7_1sxgt"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_gu56a"]
content_margin_top = 4.0
@ -137,6 +138,18 @@ theme_override_styles/pressed = SubResource("StyleBoxFlat_scxsv")
theme_override_styles/normal = SubResource("StyleBoxEmpty_vyh3d")
text = "index_退出游戏"
[node name="ButtonQuery" type="LinkButton" parent="."]
layout_mode = 0
offset_left = 439.0
offset_top = 27.0
offset_right = 535.0
offset_bottom = 67.0
theme_override_fonts/font = ExtResource("7_1sxgt")
theme_override_font_sizes/font_size = 12
text = "衔蝶内测反馈问卷"
underline = 2
uri = "https://wj.qq.com/s2/23189494/a237/"
[node name="Mask" type="ColorRect" parent="."]
visible = false
layout_mode = 1