demo 0.1 细节优化
@ -127,7 +127,7 @@ func _on_animation_finished() -> void:
|
||||
var next = auto_checkout_dict[intro].animation_next
|
||||
if wait_time > 0:
|
||||
pause()
|
||||
get_tree().create_timer(wait_time).timeout.connect(play.bind(next))
|
||||
Util.timer(wait_time, play.bind(next))
|
||||
else:
|
||||
play(next)
|
||||
|
||||
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.8 KiB |
BIN
asset/art/prop/c02/海报特写/青岛啤酒.png
Executable file → Normal file
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 19 KiB |
BIN
asset/art/prop/c02/海报特写/青岛啤酒(未用).png
Executable file
After Width: | Height: | Size: 23 KiB |
34
asset/art/prop/c02/海报特写/青岛啤酒(未用).png.import
Normal file
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://b0bkwqv86sc0"
|
||||
path="res://.godot/imported/青岛啤酒(未用).png-80f5ab64f6d0a693fa9d7a06bf9521c2.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://asset/art/prop/c02/海报特写/青岛啤酒(未用).png"
|
||||
dest_files=["res://.godot/imported/青岛啤酒(未用).png-80f5ab64f6d0a693fa9d7a06bf9521c2.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
@ -43,7 +43,7 @@ c01_7老板_7,手脚麻利点,不要耽误店里的生意。,书店老板,,,
|
||||
c01_8监督小孩_1,发赏钱喽!发赏钱喽!,监督小孩,,,,
|
||||
c01_8监督小孩_2,哟,吕萍?你咋表演结束了才回来...,监督小孩,,,,
|
||||
c01_8监督小孩_3,你手里攥的什么东西?给我看看,不然我就找班主告状!,监督小孩,,,,
|
||||
c01_8监督小孩_4,这上头咋还刻着个人哩,脑袋圆圆的,一根毛都没有!,监督小孩,,[#wait=3.0],,
|
||||
c01_8监督小孩_4,这上头咋还刻着个人哩,脑袋圆圆的,一根毛都没有!,监督小孩,,[#wait=1.0],,
|
||||
c01_8监督小孩_5,吕萍,你从哪弄来的?,监督小孩,,,,
|
||||
c01_8小小蝶_1,你们...都看见了吗?,吕萍,,,,
|
||||
c01_8幼年陆仁_1,它要来了,快跑!,陆仁,,,,
|
||||
|
|
@ -85,7 +85,7 @@
|
||||
|
||||
|
||||
~ c01_s12_鬼差来之前对话
|
||||
监督小孩: 这上头咋还刻着个人哩,脑袋圆圆的,一根毛都没有! [#wait=3.0] [ID:c01_8监督小孩_4]
|
||||
监督小孩: 这上头咋还刻着个人哩,脑袋圆圆的,一根毛都没有! [#wait=1.0] [ID:c01_8监督小孩_4]
|
||||
监督小孩: 吕萍,你从哪弄来的? [ID:c01_8监督小孩_5]
|
||||
=> END
|
||||
|
||||
|
@ -19,11 +19,12 @@ setting_日志,笔记(B),,,,,Open the Log
|
||||
setting_记忆,记忆(G),,,,,
|
||||
setting_全屏游戏,全屏游戏,,,,,Full Screen
|
||||
setting_窗口置顶,窗口置顶,,,,,Top Window
|
||||
ux_panel_笔记,线索,,,,,
|
||||
index_新游戏,新游戏,,,,,New Game
|
||||
index_继续游戏,继续游戏,,,,,Resume
|
||||
index_退出游戏,退出游戏,,,,,Exit
|
||||
ux_panel_继续,继续,,,,,
|
||||
ux_panel_笔记,笔记,,,,,
|
||||
ux_panel_线索笔记,线索,,,,,
|
||||
ux_panel_设置,设置,,,,,
|
||||
ux_panel_返回主菜单,返回主菜单,,,,,
|
||||
ux_panel_退出游戏,退出游戏,,,,,
|
||||
|
|
@ -5,7 +5,7 @@
|
||||
退出游戏[ID:index_退出游戏]
|
||||
|
||||
继续 [ID:ux_panel_继续]
|
||||
笔记 [ID:ux_panel_笔记]
|
||||
线索 [ID:ux_panel_线索笔记]
|
||||
设置 [ID:ux_panel_设置]
|
||||
返回主菜单 [ID:ux_panel_返回主菜单]
|
||||
退出游戏 [ID:ux_panel_退出游戏]
|
||||
|
@ -25,7 +25,7 @@ func c02_cat_play_with_door():
|
||||
var knock_stream = preload("uid://6q5qi1qon35r")
|
||||
AudioManager.play_sfx(knock_stream)
|
||||
SceneManager.lock_player(1.5, 6, true)
|
||||
await get_tree().create_timer(1.5).timeout
|
||||
await Util.wait(1.5)
|
||||
knocking = false
|
||||
|
||||
|
||||
@ -59,14 +59,14 @@ func _on_c02_fire_count_down_timeout():
|
||||
c02_fire_count_down_timer.stop()
|
||||
AudioManager.stop_bgm_music("霸凌救小蝉倒计时")
|
||||
DialogueManager.show_dialogue_balloon(dialogue_c02, "c02_未完成拯救小蝉的游戏", [GlobalConfig.DIALOG_IGNORE_INPUT])
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
await Util.wait(1.0)
|
||||
SceneManager.show_black_hand(true, 0.5)
|
||||
await get_tree().create_timer(3.0).timeout
|
||||
await Util.wait(3)
|
||||
SceneManager.unlock_player()
|
||||
SceneManager.get_ground_loader().transition_to_scene("c02_s03", "4")
|
||||
# TODO 音效
|
||||
# res://asset/audio/BGM/心跳背景音.mp3
|
||||
await get_tree().create_timer(3.0).timeout
|
||||
await Util.wait(3)
|
||||
SceneManager.pop_debug_dialog_info("音效", "霸凌救小蝉倒计时")
|
||||
AudioManager.loop_bgm_music("霸凌救小蝉倒计时", c02_fire_count_down_sfx, 5)
|
||||
c02_fire_count_down_timer.start()
|
||||
|
@ -9,7 +9,7 @@ enum VIBE {
|
||||
|
||||
# 从 ground loader 控制该信号
|
||||
signal ground_ready(ground: Ground2D)
|
||||
signal ground_start(ground: Ground2D)
|
||||
signal ground_start()
|
||||
|
||||
|
||||
func _ready():
|
||||
@ -25,6 +25,12 @@ func get_ground_loader() -> GroundLoader:
|
||||
return get_node_or_null("/root/Main/GroundLoader") as GroundLoader
|
||||
|
||||
|
||||
func toggle_ground_mask(
|
||||
display: bool, wait_time := 1.5, ease_min_duration := 0.5, mask_color := Color.BLACK
|
||||
) -> Tween:
|
||||
return get_ground_loader().toggle_mask(display, wait_time, ease_min_duration, mask_color)
|
||||
|
||||
|
||||
# restart scene in debug launch...
|
||||
func is_restarting() -> bool:
|
||||
var ground = get_ground()
|
||||
@ -233,7 +239,7 @@ func pop_os_with_str(translation_key: String, auto_lock := true, auto_unlock :=
|
||||
var player = get_player() as MainPlayer
|
||||
if player:
|
||||
var msg = tr(translation_key).replace("<br>", "\n")
|
||||
var lines = await DialogueUtil.generate_lines(msg)
|
||||
var lines = await Util.generate_lines(msg)
|
||||
player.pop_os(lines, auto_lock, auto_unlock)
|
||||
else:
|
||||
printerr("Player node not found")
|
||||
@ -293,12 +299,9 @@ func checkout_index_page(transition := true):
|
||||
# 保存后,渐隐切换场景
|
||||
ArchiveManager.save_all()
|
||||
if transition:
|
||||
var ground = get_ground()
|
||||
if ground:
|
||||
var tween = create_tween()
|
||||
if GlobalConfig.DEBUG:
|
||||
print("transition to index page")
|
||||
tween.tween_property(ground, "modulate:a", 0.0, 1.0)
|
||||
var ground_loader = get_ground_loader() as GroundLoader
|
||||
if ground_loader:
|
||||
var tween = toggle_ground_mask(true)
|
||||
tween.tween_callback(_jump_back_to_index_and_quit_main)
|
||||
else:
|
||||
_jump_back_to_index_and_quit_main()
|
||||
@ -387,12 +390,11 @@ func toggle_pause_counter(plus := true):
|
||||
|
||||
func quit_game():
|
||||
ArchiveManager.save_all()
|
||||
var ground = get_ground()
|
||||
if ground:
|
||||
var tween = create_tween()
|
||||
var ground_loader = get_ground_loader() as GroundLoader
|
||||
if ground_loader:
|
||||
var tween = toggle_ground_mask(true, 2.0, 1.0)
|
||||
if GlobalConfig.DEBUG:
|
||||
print("quit_game with transition")
|
||||
tween.tween_property(ground, "modulate:a", 0.0, 1.5)
|
||||
tween.tween_callback(get_tree().quit)
|
||||
else:
|
||||
get_tree().quit()
|
||||
|
@ -43,6 +43,7 @@ buses/default_bus_layout="res://config/default_bus_layout.tres"
|
||||
|
||||
[autoload]
|
||||
|
||||
Util="*res://util/util.gd"
|
||||
DebugMenu="*res://addons/debug_menu/debug_menu.tscn"
|
||||
GlobalConfigManager="*res://manager/config_manager/global_config_manager.gd"
|
||||
ArchiveManager="*res://manager/archive_manager/archive_manager.gd"
|
||||
|
@ -424,8 +424,7 @@ func _os_load_line(line, duration):
|
||||
os_tween.pause()
|
||||
if os_pausing_timer and os_pausing_timer.timeout.is_connected(os_tween.play):
|
||||
os_pausing_timer.timeout.disconnect(os_tween.play)
|
||||
os_pausing_timer = get_tree().create_timer(duration)
|
||||
os_pausing_timer.timeout.connect(_on_os_line_timeout, CONNECT_ONE_SHOT)
|
||||
Util.timer(duration, _on_os_line_timeout)
|
||||
|
||||
|
||||
func _on_os_line_timeout(naturally := true):
|
||||
|
@ -44,7 +44,7 @@ func _exit_tree() -> void:
|
||||
|
||||
func _create_timer(duration: float, callable: Callable):
|
||||
if duration > 0 and callable:
|
||||
get_tree().create_timer(duration).timeout.connect(callable)
|
||||
Util.timer(duration, callable)
|
||||
|
||||
|
||||
# Freeze 相关方法
|
||||
|
@ -243,23 +243,11 @@ func apply_dialogue_line() -> void:
|
||||
# eg. [#wait=2.5]
|
||||
if wait:
|
||||
wait_time = wait.to_float()
|
||||
await get_tree().create_timer(wait_time).timeout
|
||||
await Util.wait(wait_time)
|
||||
# 在 translation key 仍旧是当前 line 时跳转;如果不再是当前 line,则不跳转
|
||||
if dialogue_line.translation_key == initial_translation_key:
|
||||
next(dialogue_line.next_id)
|
||||
|
||||
# var time = next_dialogue_line.text.length() * 0.2 if next_dialogue_line.time == "auto" else next_dialogue_line.time.to_float()
|
||||
# await get_tree().create_timer(time).timeout
|
||||
|
||||
# elif dialogue_line.time != "":
|
||||
# var time = dialogue_line.text.length() * 0.02 if dialogue_line.time == "auto" else dialogue_line.time.to_float()
|
||||
# await get_tree().create_timer(time).timeout
|
||||
# next(dialogue_line.next_id)
|
||||
# else:
|
||||
# is_waiting_for_input = true
|
||||
# balloon.focus_mode = Control.FOCUS_ALL
|
||||
# balloon.grab_focus()
|
||||
|
||||
|
||||
## Go to the next line
|
||||
func next(next_id: String) -> void:
|
||||
|
@ -148,7 +148,7 @@ func apply_dialogue_line() -> void:
|
||||
is_waiting_for_input = true
|
||||
# balloon.focus_mode = Control.FOCUS_ALL
|
||||
# balloon.grab_focus()
|
||||
await get_tree().create_timer(2.0).timeout
|
||||
await Util.wait(2.0)
|
||||
# debug line 不需要下一行,直接释放(避免触发 dialogue_ended 信号)
|
||||
queue_free()
|
||||
|
||||
|
@ -210,11 +210,11 @@ func flash_palette(duration := 0.5) -> void:
|
||||
if not is_node_ready():
|
||||
return
|
||||
add_mode("palette")
|
||||
get_tree().create_timer(duration).timeout.connect(erase_mode.bind("palette"))
|
||||
Util.timer(duration, erase_mode.bind("palette"))
|
||||
|
||||
# glitch 闪烁
|
||||
func flash_glitch(duration := 1.0) -> void:
|
||||
if not is_node_ready():
|
||||
return
|
||||
add_mode("glitch")
|
||||
get_tree().create_timer(duration).timeout.connect(erase_mode.bind("glitch"))
|
||||
Util.timer(duration, erase_mode.bind("glitch"))
|
||||
|
@ -17,5 +17,5 @@ func run_effect(play_sfx := true, queue_free_delay := 0.0):
|
||||
|
||||
func _on_animation_finished(_a, queue_free_delay):
|
||||
if queue_free_delay > 0:
|
||||
await get_tree().create_timer(queue_free_delay).timeout
|
||||
await Util.wait(queue_free_delay)
|
||||
queue_free()
|
||||
|
@ -55,6 +55,31 @@ 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:
|
||||
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)
|
||||
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")
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
# sign position
|
||||
@ -69,10 +94,14 @@ func _ready() -> void:
|
||||
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
|
||||
if Engine.is_editor_hint():
|
||||
# editor 下都显示
|
||||
speaking_sign.visible = true
|
||||
speaking_sign.modulate.a = 1
|
||||
speaking_sign.modulate.a = 1.0
|
||||
speaking_sign.get_node("Sprite2D").position.x = -60.0
|
||||
speaking_sign.get_node("Sprite2D").frame = 2
|
||||
sign_mark.display_sign = true
|
||||
@ -80,10 +109,6 @@ func _ready() -> void:
|
||||
# setup default value
|
||||
ground_archive = ArchiveManager.archive.ground_archive()
|
||||
icount = ground_archive.get_value(name, "icount", 0)
|
||||
# 默认为 0
|
||||
speaking_sign.modulate.a = 0.0
|
||||
base_scale = speaking_sign.scale
|
||||
base_mod = speaking_sign.modulate
|
||||
if snap_to_edge:
|
||||
sign_snapper.arrived.connect(_on_interacted)
|
||||
else:
|
||||
@ -106,10 +131,10 @@ func _align_signs_status():
|
||||
|
||||
|
||||
func _on_toggle_active(activated: bool) -> void:
|
||||
if activated:
|
||||
speaking_animation.play("speaking")
|
||||
# icount 影响 visible; activated 影响 modulate
|
||||
speaking_sign.modulate.a = 1 if activated else 0
|
||||
if activated and speaking_sign_mode == 0:
|
||||
speaking_sign_mode = 1
|
||||
elif not activated and speaking_sign_mode > 0:
|
||||
speaking_sign_mode = 0
|
||||
|
||||
|
||||
func _on_interacted() -> void:
|
||||
@ -122,13 +147,9 @@ func _on_interacted() -> void:
|
||||
ground_archive.set_pair(name, "icount", icount)
|
||||
DialogueManager.show_dialogue_balloon(dialogue_res, dialogue_title)
|
||||
interacted.emit()
|
||||
var tween = create_tween()
|
||||
tween.tween_property(speaking_sign, "modulate", Color.WHITE, 0.5)
|
||||
tween.parallel().tween_property(speaking_sign, "scale", base_scale * 1.3, 0.3)
|
||||
speaking_sign_mode = 2
|
||||
await DialogueManager.dialogue_ended
|
||||
tween = create_tween()
|
||||
tween.tween_property(speaking_sign, "modulate", base_mod, 0.5)
|
||||
tween.parallel().tween_property(speaking_sign, "scale", base_scale, 0.3)
|
||||
speaking_sign_mode = 1
|
||||
if GlobalConfig.DEBUG:
|
||||
print("[" + name + "] call lock")
|
||||
SceneManager.unlock_player()
|
||||
|
@ -116,7 +116,7 @@ script = ExtResource("4_j5svs")
|
||||
|
||||
[node name="Sign" parent="." instance=ExtResource("4_nokx4")]
|
||||
unique_name_in_owner = true
|
||||
sign_mark_offset = Vector2(0, -60)
|
||||
sign_mark_offset = Vector2(0, -10)
|
||||
|
||||
[node name="SpeakingAnimationPlayer" type="AnimationPlayer" parent="."]
|
||||
unique_name_in_owner = true
|
||||
@ -141,7 +141,7 @@ scale = Vector2(0.07, 0.07)
|
||||
|
||||
[node name="Sprite2D" type="AnimatedSprite2D" parent="SpeakingSign2D"]
|
||||
light_mask = 16
|
||||
position = Vector2(60, 0)
|
||||
position = Vector2(-60, 0)
|
||||
sprite_frames = SubResource("SpriteFrames_k7dca")
|
||||
offset = Vector2(60, 0)
|
||||
|
||||
@ -158,5 +158,6 @@ unique_name_in_owner = true
|
||||
script = ExtResource("8_7lwt5")
|
||||
radius = 25.0
|
||||
walk_to_edge = true
|
||||
face_inside_on_edge = true
|
||||
action_on_arrived = 4
|
||||
metadata/_custom_type_script = "uid://cnt01hiw52bmn"
|
||||
|
@ -13,6 +13,8 @@ signal arrived
|
||||
@export_range(0.0, 20.0, 0.1) var radius := 0.0
|
||||
# 让玩家走到边缘,特别适用于 npc 对话等情景
|
||||
@export var walk_to_edge := false
|
||||
# 如果 walk_to_edge 为 true,那么走到 edge 后面朝内侧
|
||||
@export var face_inside_on_edge := false
|
||||
@export var action_on_arrived := 3
|
||||
@export_tool_button("debug 检查玩家触发位置") var debug_check_player_pos = _debug_check_player_pos
|
||||
|
||||
@ -65,6 +67,12 @@ func _on_interacted():
|
||||
tween = create_tween()
|
||||
else:
|
||||
tween = player.walk_to(target_pos)
|
||||
if walk_to_edge and face_inside_on_edge:
|
||||
# 玩家向右走到 target_pos.x 后,向左看向 global_position.x
|
||||
if player_x < target_pos.x and target_pos.x > global_position.x:
|
||||
tween.tween_callback(player.set_facing_direction.bind(Vector2(-1, 0)))
|
||||
elif player_x > target_pos.x and target_pos.x < global_position.x:
|
||||
tween.tween_callback(player.set_facing_direction.bind(Vector2(1, 0)))
|
||||
if delay_arrived > 0:
|
||||
tween.tween_interval(delay_arrived)
|
||||
if action_on_arrived != 3:
|
||||
|
@ -22,7 +22,6 @@ var _tweeked_position := Vector2.ZERO
|
||||
|
||||
var zoom_tween: Tween
|
||||
var focus_offset := Vector2.ZERO
|
||||
var shaked_offset := Vector2.ZERO
|
||||
var shake_ignore_boundary := false
|
||||
|
||||
|
||||
@ -31,7 +30,7 @@ func _ready() -> void:
|
||||
push_error("Focusing node not found")
|
||||
|
||||
|
||||
func shake_camera(strength := 7.0, recovery_speed := 4.0, ignore_boundary := false):
|
||||
func shake_camera(strength := 6.0, recovery_speed := 2.0, ignore_boundary := true):
|
||||
shake_strength = strength
|
||||
shake_recovery_speed = recovery_speed
|
||||
shake_ignore_boundary = ignore_boundary
|
||||
@ -56,43 +55,56 @@ func tweak_position(velocity, facing_direction):
|
||||
_tweeked_position.y = facing_direction.y * abs(velocity.y) * 0.2
|
||||
|
||||
|
||||
# 处理过程的当下理想位置
|
||||
var progressing_position: Vector2
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if not focusing_node:
|
||||
return
|
||||
# handle shake, via _shaked_position
|
||||
if shake_strength > 0.0:
|
||||
shake_strength = lerpf(shake_strength, 0.0, shake_recovery_speed * delta)
|
||||
shaked_offset = Vector2(
|
||||
randf_range(-shake_strength, shake_strength),
|
||||
randf_range(-shake_strength, shake_strength)
|
||||
)
|
||||
else:
|
||||
shaked_offset = Vector2.ZERO
|
||||
shake_ignore_boundary = false
|
||||
# set camera's position
|
||||
var target_position = (
|
||||
focusing_node.global_position
|
||||
+ _tweeked_position
|
||||
+ force_offset
|
||||
+ focus_offset
|
||||
+ shaked_offset
|
||||
)
|
||||
# 最终目标位置
|
||||
var target_position = focusing_node.global_position + _tweeked_position + force_offset
|
||||
if focusing_node is MainPlayer:
|
||||
# player 的焦点在脚底,所以需要偏移 player 的高度。注意 y 轴是向下的,所以是减去 player 的高度
|
||||
target_position.y -= focusing_node.current_animation_config.os_height * 0.7
|
||||
# clamp the position
|
||||
if not shake_ignore_boundary:
|
||||
var margin = half_screen_size / zoom_ratio
|
||||
margin.y += shaded_height
|
||||
target_position.x = clamp(target_position.x, limit_left + margin.x, limit_right - margin.x)
|
||||
target_position.y = clamp(target_position.y, limit_top + margin.y, limit_bottom - margin.y)
|
||||
target_position = _clamp_boundary(target_position)
|
||||
# easing with speed
|
||||
global_position = lerp(global_position, target_position, speed * delta)
|
||||
progressing_position = lerp(progressing_position, target_position, speed * delta)
|
||||
global_position = progressing_position
|
||||
|
||||
# handle shake
|
||||
if shake_strength > 0.0:
|
||||
# 让 shake_strength 逐帧衰减
|
||||
shake_strength = lerpf(shake_strength, 0.0, shake_recovery_speed * delta)
|
||||
# [-shake_strength, +shake_strength] 范围内的同时,尽可能偏离中心
|
||||
# 在 0 – 2π 之间随机一个方向,在 _last_shake_angle 的对角范围
|
||||
# _last_shake_angle = wrapf(_last_shake_angle + randf_range(-2.0, 2.0), 0, TAU) # TAU = 2π
|
||||
var _last_shake_angle := randf_range(-TAU, TAU) # TAU = 2π
|
||||
var shaked_offset := (
|
||||
Vector2(cos(_last_shake_angle), sin(_last_shake_angle)) * shake_strength
|
||||
)
|
||||
# var shaked_offset := Vector2(
|
||||
# randf_range(-shake_strength, shake_strength),
|
||||
# randf_range(-shake_strength, shake_strength)
|
||||
# )
|
||||
global_position += shaked_offset
|
||||
if not shake_ignore_boundary:
|
||||
global_position = _clamp_boundary(global_position)
|
||||
|
||||
# var taget_zoom = lerpf(zoom.x, zoom_ratio, speed * delta)
|
||||
# zoom = Vector2(taget_zoom, taget_zoom)
|
||||
zoom = Vector2(zoom_ratio, zoom_ratio)
|
||||
|
||||
|
||||
func _clamp_boundary(target: Vector2) -> Vector2:
|
||||
var margin = half_screen_size / zoom_ratio
|
||||
margin.y += shaded_height
|
||||
target.x = clamp(target.x, limit_left + margin.x, limit_right - margin.x)
|
||||
target.y = clamp(target.y, limit_top + margin.y, limit_bottom - margin.y)
|
||||
return target
|
||||
|
||||
|
||||
func tween_zoom(ratio: float, duration := 1.5):
|
||||
if zoom_tween and zoom_tween.is_running():
|
||||
zoom_tween.kill()
|
||||
|
@ -3,5 +3,5 @@
|
||||
[ext_resource type="Script" uid="uid://dphabatkubjgf" path="res://scene/ground/camera/camera_focus_marker.gd" id="1_7t4e6"]
|
||||
|
||||
[node name="CameraFocusMarker" type="Camera2D"]
|
||||
process_mode = 3
|
||||
process_mode = 1
|
||||
script = ExtResource("1_7t4e6")
|
||||
|
@ -18,7 +18,6 @@ class_name GroundLoader extends Node2D
|
||||
|
||||
var has_entered := false
|
||||
var ground: Ground2D
|
||||
var display_mask_sec = 0.0
|
||||
|
||||
# 场景名字映射到路径
|
||||
static var GROUND_SCENE_PATH_DICT = {
|
||||
@ -52,9 +51,11 @@ static var GROUND_SCENE_PATH_DICT = {
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
mask_layer.layer = GlobalConfig.CANVAS_LAYER_GROUND_MASK
|
||||
mask.visible = true
|
||||
mask.color.a = 0.0
|
||||
mask_layer.layer = GlobalConfig.CANVAS_LAYER_GROUND_MASK
|
||||
# mask layer 独立的 always 处理模式,可以保证转场正常运行
|
||||
# toggle_mask = mask_layer.toggle_mask
|
||||
ground = get_node_or_null("Ground") as Ground2D
|
||||
if ground:
|
||||
print("GroundLoader remove old ground:", ground.scene_name)
|
||||
@ -69,6 +70,35 @@ func _ready() -> void:
|
||||
# transition_to_scene(current_scene, entrance_portal, 0.0)
|
||||
|
||||
|
||||
# # var toggle_mask:Callable
|
||||
# func toggle_mask(display: bool, mask_color: Color, wait_time: float) -> Tween:
|
||||
# return mask_layer.toggle_mask(display, mask_color, wait_time)
|
||||
|
||||
var display_start_sec = 0.0
|
||||
|
||||
# wait_time 包含 ease in + wait + ease out 完整时长
|
||||
# ease duration = min(ease_min_duration, wait_time * 0.5)
|
||||
func toggle_mask(
|
||||
display: bool, wait_time: float, ease_min_duration := 0.3, mask_color:= Color.BLACK
|
||||
) -> Tween:
|
||||
var tween = get_tree().create_tween()
|
||||
mask_color.a = mask.color.a
|
||||
mask.color = mask_color
|
||||
var duration = min(ease_min_duration, wait_time * 0.5)
|
||||
if display:
|
||||
display_start_sec = Time.get_ticks_msec() * 0.001
|
||||
tween.tween_property(mask, "color:a", 1.0, duration).set_trans(Tween.TRANS_CUBIC)
|
||||
else:
|
||||
# 转场至少 0.6s, 除去 0.3s 最后的淡出,需要 0.3s 的等待时间(包含 mask 的淡入)
|
||||
if wait_time:
|
||||
var time = Time.get_ticks_msec() * 0.001
|
||||
wait_time = max(wait_time + display_start_sec - time - 0.3, 0.0)
|
||||
if wait_time:
|
||||
tween.tween_interval(wait_time)
|
||||
tween.tween_property(mask, "color:a", 0.0, duration).set_trans(Tween.TRANS_CUBIC)
|
||||
return tween
|
||||
|
||||
|
||||
func _load_save():
|
||||
# 强制覆盖 archive 记录
|
||||
if force_archive_scene or force_archive_portal:
|
||||
@ -82,27 +112,8 @@ func _load_save():
|
||||
entrance_portal = ArchiveManager.archive.entrance_portal
|
||||
|
||||
|
||||
func toggle_mask(display: bool, mask_color: Color, wait_time: float) -> Tween:
|
||||
var tween = get_tree().create_tween()
|
||||
mask_color.a = mask.color.a
|
||||
mask.color = mask_color
|
||||
var duration = min(0.3, wait_time * 0.5)
|
||||
if display:
|
||||
tween.tween_property(mask, "color:a", 1.0, duration).set_trans(Tween.TRANS_CUBIC)
|
||||
display_mask_sec = Time.get_ticks_msec() * 0.001
|
||||
else:
|
||||
# 转场至少 0.6s, 除去 0.3s 最后的淡出,需要 0.3s 的等待时间(包含 mask 的淡入)
|
||||
if wait_time:
|
||||
var time = Time.get_ticks_msec() * 0.001
|
||||
wait_time = max(wait_time + display_mask_sec - time - 0.3, 0.0)
|
||||
if wait_time:
|
||||
tween.tween_interval(wait_time)
|
||||
tween.tween_property(mask, "color:a", 0.0, duration).set_trans(Tween.TRANS_CUBIC)
|
||||
return tween
|
||||
|
||||
|
||||
func transition_to_scene(
|
||||
scene_name: String, portal: String, wait_time := 1.4, mask_color := Color.BLACK
|
||||
scene_name: String, portal: String, wait_time := 1.4
|
||||
) -> void:
|
||||
if ground:
|
||||
print("GroundLoader transition_to_scene: pause prev ground.")
|
||||
@ -119,11 +130,11 @@ func transition_to_scene(
|
||||
_update_archive()
|
||||
if wait_time > 0.0:
|
||||
# 转场效果,在 _load_ground_node 之前播放
|
||||
var tween = toggle_mask(true, mask_color, wait_time)
|
||||
var tween = toggle_mask(true, wait_time)
|
||||
tween.tween_callback(_do_transition.call_deferred.bind(scene_name))
|
||||
_allow_ground_start = false
|
||||
# 等到 toggle_mask 结束,再重置 freeze 状态
|
||||
toggle_mask(false, mask_color, wait_time).tween_callback(
|
||||
toggle_mask(false, wait_time).tween_callback(
|
||||
func(): _allow_ground_start = true
|
||||
)
|
||||
else:
|
||||
@ -141,7 +152,7 @@ var _allow_ground_start := false:
|
||||
if val:
|
||||
if ground.process_mode != Node.PROCESS_MODE_INHERIT:
|
||||
# ground_start 信号
|
||||
SceneManager.ground_start.emit(ground)
|
||||
SceneManager.ground_start.emit()
|
||||
ground.process_mode = Node.PROCESS_MODE_INHERIT
|
||||
print(
|
||||
"GroundLoader _allow_ground_start: unfrozen. frozen duration(ms):",
|
||||
@ -177,7 +188,7 @@ func _do_transition(scene_name: String) -> void:
|
||||
_add_ground()
|
||||
if _allow_ground_start:
|
||||
# 如果不阻塞,直接 ground_start 信号
|
||||
SceneManager.ground_start.emit(ground)
|
||||
SceneManager.ground_start.emit()
|
||||
# 预先加载邻居场景
|
||||
_post_transition()
|
||||
if GlobalConfig.DEBUG and not Engine.is_editor_hint():
|
||||
|
@ -25,6 +25,7 @@ color = Color(0, 0, 0, 1)
|
||||
|
||||
[node name="MaskLayer" type="CanvasLayer" parent="."]
|
||||
unique_name_in_owner = true
|
||||
process_mode = 3
|
||||
layer = 14
|
||||
|
||||
[node name="Mask" type="ColorRect" parent="MaskLayer"]
|
||||
|
@ -56,10 +56,6 @@ func _on_ground_ready() -> void:
|
||||
pass
|
||||
|
||||
|
||||
func _on_ground_start() -> void:
|
||||
pass
|
||||
|
||||
|
||||
func _on_ready() -> void:
|
||||
if Engine.is_editor_hint():
|
||||
return
|
||||
|
@ -21,7 +21,7 @@ func intro_start():
|
||||
await animation_finished
|
||||
SceneManager.release_player()
|
||||
$"../DeployLayer/床".enabled = true
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
await Util.wait(1)
|
||||
show_interact_help()
|
||||
|
||||
func play_intro_dialogue():
|
||||
@ -37,7 +37,7 @@ func _on_ground_ready() -> void:
|
||||
piano = $"../DeployLayer/钢琴"
|
||||
if data["oneshot_animation_played"]:
|
||||
$"../DeployLayer/床".enabled = true
|
||||
get_tree().create_timer(1.0).timeout.connect(show_interact_help)
|
||||
Util.timer(1.0, show_interact_help)
|
||||
# 画框是否已经正位
|
||||
data.frame_relocated = ambush.played and ambush.one_shot
|
||||
# 禁用鸡毛掸子
|
||||
@ -81,15 +81,15 @@ func cant_read():
|
||||
func _on_note_read():
|
||||
frame.enabled = false
|
||||
# 稍加延时后显示鸡毛掸子
|
||||
get_tree().create_timer(4.5).timeout.connect(func(): ambush.enabled = true)
|
||||
Util.timer(4.5, func(): ambush.enabled = true)
|
||||
|
||||
|
||||
func _on_ambush_triggered():
|
||||
ambush.enabled = false
|
||||
frame.note_key = "c01_摆正的洋相片"
|
||||
get_tree().create_timer(5.5).timeout.connect(func(): frame.enabled = true)
|
||||
Util.timer(5.5, func(): frame.enabled = true)
|
||||
# 鸡毛掸子 4.5s,再等待 3s 后掉落纸片
|
||||
get_tree().create_timer(8).timeout.connect(_play_paper_animation)
|
||||
Util.timer(8, _play_paper_animation)
|
||||
|
||||
func lock_on_use_stick():
|
||||
SceneManager.lock_player(4.0)
|
||||
|
@ -97,12 +97,12 @@ func pre_game_intro():
|
||||
camera.tween_zoom(1.5, 3.0)
|
||||
var p = $"../DeployLayer/四小孩画鬼差的对话ambush/FocusPoint"
|
||||
camera.focus_node(p, 3.0)
|
||||
await get_tree().create_timer(1.5).timeout
|
||||
await Util.wait(1.5)
|
||||
DialogueManager.show_dialogue_balloon(dialogue_c01, "c01_s06_四个小孩画鬼差的对话")
|
||||
await DialogueManager.dialogue_ended
|
||||
# 重置镜头
|
||||
SceneManager.focus_player_and_reset_zoom(2.5)
|
||||
await get_tree().create_timer(1.5).timeout
|
||||
await Util.wait(1.5)
|
||||
await SceneManager.pop_os_with_str("c01_s06_熟悉的墙画")
|
||||
SceneManager.unlock_player()
|
||||
|
||||
@ -117,7 +117,6 @@ func game_intro() -> void:
|
||||
var camera = SceneManager.get_camera_marker() as CameraFocusMarker
|
||||
camera.tween_zoom(1.5, 3.0)
|
||||
camera.focus_node(focus_point, 3.0)
|
||||
# get_tree().create_timer(1.0).timeout.connect(camera.focus_node.bind(focus_point, 3.))
|
||||
standing_kid1.play("【站立小孩-1】挠痒呼吸")
|
||||
standing_kid2.play("【站立小孩-2】转身")
|
||||
# 只有 1、2 是跟班,3 不参与
|
||||
@ -144,7 +143,7 @@ func _game_counting_down(_res = null):
|
||||
var player = SceneManager.get_player() as MainPlayer
|
||||
var left = player.global_position.x
|
||||
player.player_movement_rect.position.x = left
|
||||
get_tree().create_timer(2.0).timeout.connect(_kids_start_run)
|
||||
Util.timer(2.0, _kids_start_run)
|
||||
cat.visible = true
|
||||
cat.play("【墙上黑猫】跑步")
|
||||
cat.get_node("猫咪嘶吼音效").play()
|
||||
@ -175,7 +174,7 @@ func _on_talked():
|
||||
# 三个小孩都对话完毕
|
||||
await DialogueManager.dialogue_ended
|
||||
SceneManager.lock_player()
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
await Util.wait(1)
|
||||
await SceneManager.pop_os_with_str("c01_s06_四小孩对话结束")
|
||||
SceneManager.unlock_player()
|
||||
|
||||
@ -243,6 +242,7 @@ func obstacles_ambush3_triggered():
|
||||
game_kid.sprite_frames.set_animation_loop("【胖小孩背着残疾小孩】摔倒", false)
|
||||
game_kid.animation_finished.connect(_on_kid_fall_finished, CONNECT_ONE_SHOT)
|
||||
|
||||
|
||||
# 残疾小孩冲刺
|
||||
func _on_kid_fall_finished():
|
||||
obstacles.get_node("遮盖").visible = true
|
||||
@ -258,7 +258,6 @@ func _on_kid_fall_finished():
|
||||
tween.tween_property(cat_shadow, "modulate:a", 0.0, 4.0)
|
||||
|
||||
|
||||
|
||||
func _on_mid_ambush_success():
|
||||
obstacles_success = true
|
||||
# TODO 获得成就
|
||||
@ -273,11 +272,10 @@ func game_restart():
|
||||
game_kid.play("【胖小孩背着残疾小孩】侧面呼吸")
|
||||
SceneManager.freeze_player(0)
|
||||
SceneManager.pop_debug_dialog_info("音效", "玩家被抓住,猫鼠游戏重新开始")
|
||||
await get_tree().create_timer(1.5).timeout
|
||||
var ground_loader = SceneManager.get_ground_loader()
|
||||
await Util.wait(1.5)
|
||||
# 过场黑屏
|
||||
ground_loader.toggle_mask(true, Color.BLACK, 0.5)
|
||||
await get_tree().create_timer(0.5).timeout
|
||||
SceneManager.toggle_ground_mask(true)
|
||||
await Util.wait(0.5)
|
||||
# 重置桌椅
|
||||
obstacles_pushed = false
|
||||
obstacles_success = false
|
||||
@ -288,13 +286,13 @@ func game_restart():
|
||||
standing_kid1.global_position.x = kids_start_run_initial_x[0]
|
||||
standing_kid2.global_position.x = kids_start_run_initial_x[1]
|
||||
game_kid.global_position.x = kids_start_run_initial_x[2]
|
||||
ground_loader.toggle_mask(false, Color.BLACK, 1.0)
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
SceneManager.toggle_ground_mask(false)
|
||||
await Util.wait(1.0)
|
||||
# 开始跑
|
||||
SceneManager.release_player()
|
||||
$"Sfx猫鼠游戏".set("parameters/switch_to_clip", "Intro")
|
||||
DialogueManager.show_dialogue_balloon(dialogue_c01, "c01_s06_猫鼠游戏倒计时")
|
||||
await get_tree().create_timer(1.5).timeout
|
||||
await Util.wait(1.5)
|
||||
_kids_start_run()
|
||||
|
||||
|
||||
@ -369,7 +367,7 @@ func transport_player_to_next_scene(win: bool):
|
||||
_show_next_scene(true)
|
||||
SceneManager.pop_debug_dialog_info("音效", "猫鼠游戏胜利,无缝转场")
|
||||
else:
|
||||
get_tree().create_timer(0.7).timeout.connect(_show_next_scene.bind(false))
|
||||
Util.timer(0.7, _show_next_scene.bind(false))
|
||||
SceneManager.pop_debug_dialog_info("音效", "猫鼠游戏失败,传送下一场景")
|
||||
|
||||
|
||||
|
@ -34,7 +34,7 @@ func _on_ground_ready() -> void:
|
||||
var camera = SceneManager.get_camera_marker()
|
||||
camera.limit_left = -400
|
||||
create_tween().tween_property(camera, "limit_left", 0, 5.0)
|
||||
get_tree().create_timer(5.0).timeout.connect(_on_fog_disappear)
|
||||
Util.timer(5.0, _on_fog_disappear)
|
||||
seller = $"../DeployLayer/报童" as AnimatedSprite2D
|
||||
ambush_seller = $"../DeployLayer/报童/Ambush报童" as Ambush2D
|
||||
bookstore_portal = $"../DeployLayer/portal_2"
|
||||
@ -67,9 +67,9 @@ func _on_luren_animation_finished() -> void:
|
||||
func _knock_door():
|
||||
# 6 号动作:敲门
|
||||
SceneManager.lock_player(3.5, 6)
|
||||
await get_tree().create_timer(2.2).timeout
|
||||
await Util.wait(2.2)
|
||||
$"敲门音效".play()
|
||||
await get_tree().create_timer(1.2).timeout
|
||||
await Util.wait(1.2)
|
||||
var stream = preload("res://asset/audio/sfx/交互/序章/03_书店外黄昏_开门.wav")
|
||||
AudioManager.play_sfx(stream)
|
||||
|
||||
@ -80,8 +80,6 @@ func _on_fog_disappear() -> void:
|
||||
var chapter_title = preload("res://asset/art/scene/c01/s02_旧版序章/f_序章标题.png")
|
||||
SceneManager.pop_center_texture(chapter_title)
|
||||
fog.tween_fog(0, Color.TRANSPARENT, Fog2D.FOG_OFFSET_DEFAULT, 15.0, true)
|
||||
# await get_tree().create_timer(5.0).timeout
|
||||
|
||||
|
||||
func seller_interacted():
|
||||
bookstore_portal.holding = false
|
||||
@ -90,7 +88,7 @@ func seller_interacted():
|
||||
seller.play("报童给报纸")
|
||||
# 提前写入 prop 中,防止存档 bug,稍后播放获得动画
|
||||
SceneManager.enable_prop_item_silently("prop_信碎片2")
|
||||
await get_tree().create_timer(1.5).timeout
|
||||
await Util.wait(1.5)
|
||||
$"报童音效".play()
|
||||
SceneManager.pop_os_with_str("c01_s07_获得报纸")
|
||||
await SceneManager.get_player().os_finished
|
||||
|
@ -210,7 +210,7 @@ loop = true
|
||||
metadata/_custom_type_script = "uid://wapo47a1oddf"
|
||||
|
||||
[node name="Npc吉祥话4" parent="Ground/DeployLayer/陆仁舞刀" instance=ExtResource("6_fw22n")]
|
||||
position = Vector2(-22, 51)
|
||||
position = Vector2(-14, 51)
|
||||
enabled = false
|
||||
speaking_sign_height = 47.0
|
||||
dialogue_title = "c01_s07_陆仁吉祥话"
|
||||
|
@ -91,7 +91,7 @@ func _on_envolope_table_interacted() -> void:
|
||||
|
||||
func first_enter_door() -> void:
|
||||
SceneManager.freeze_player(0)
|
||||
await get_tree().create_timer(1.5).timeout
|
||||
await Util.wait(1.5)
|
||||
DialogueManager.show_dialogue_balloon(dialogue_c01, "c01_s08_书店进门老板台词")
|
||||
await DialogueManager.dialogue_ended
|
||||
SceneManager.release_player()
|
||||
@ -100,7 +100,7 @@ func first_enter_door() -> void:
|
||||
func assign_tasks() -> void:
|
||||
# 放报纸动作
|
||||
SceneManager.freeze_player(0, 8, false)
|
||||
await get_tree().create_timer(4.5).timeout
|
||||
await Util.wait(4.5)
|
||||
$"放报纸音效".play()
|
||||
DialogueManager.show_dialogue_balloon(dialogue_c01, "c01_s08_书店老板任务")
|
||||
await DialogueManager.dialogue_ended
|
||||
@ -126,7 +126,9 @@ func _on_shelf_game_exiting() -> void:
|
||||
create_tween().tween_property(mask, "color:a", 0.0, 1.0).from(1.0)
|
||||
SceneManager.release_player()
|
||||
|
||||
var fall_off
|
||||
|
||||
var fall_off
|
||||
|
||||
|
||||
func _on_shelf_game_success() -> void:
|
||||
ArchiveManager.archive.set_global_entry(&"c01_shelf_game_success", true)
|
||||
@ -146,31 +148,35 @@ func _on_shelf_game_success() -> void:
|
||||
fall_off.play()
|
||||
fall_off.animation_finished.connect(_on_fall_off_finished)
|
||||
# 从 sfx_生死簿演出 中退出时播放不出来,需要在此处播放
|
||||
$"摔倒音效".play()
|
||||
Util.timer(0.5, $"摔倒音效".play)
|
||||
_check_portal()
|
||||
|
||||
|
||||
func _on_fall_off_finished() -> void:
|
||||
fall_off.visible = false
|
||||
# 最后释放玩家
|
||||
SceneManager.release_player()
|
||||
SceneManager.get_player().hide_sprite = false
|
||||
await get_tree().create_timer(1.2).timeout
|
||||
await Util.wait(1.2)
|
||||
SceneManager.pop_os_with_str("c01_s08_书架游戏完成")
|
||||
|
||||
|
||||
func _setup_weird_bookstore() -> void:
|
||||
# 切换背景音效
|
||||
$"环境音".stop()
|
||||
$"诡异环境音".play()
|
||||
# 光变红
|
||||
$"../AmbientLayer/PointLight2D".color = Color.html("#ff2719")
|
||||
|
||||
|
||||
coin.enabled = true
|
||||
ladder.enabled = false
|
||||
manager.visible = false
|
||||
mice.visible = true
|
||||
$"../DirectionalLight2D".energy = 0.7
|
||||
$"../BGSprite2D".texture = preload("res://asset/art/scene/c01/s08_书店/夜晚版/bg_书店夜晚.png")
|
||||
$"../ParallaxForeground/FGParallaxLayer/FGSprite2D".texture = preload("res://asset/art/scene/c01/s08_书店/夜晚版/fg_书店夜晚前景.png")
|
||||
$"../ParallaxForeground/FGParallaxLayer/FGSprite2D".texture = preload(
|
||||
"res://asset/art/scene/c01/s08_书店/夜晚版/fg_书店夜晚前景.png"
|
||||
)
|
||||
ladder.texture = preload("res://asset/art/scene/c01/s08_书店/夜晚版/e_梯子 夜晚.png")
|
||||
|
||||
|
||||
@ -199,10 +205,9 @@ func _on_envelope_game_success() -> void:
|
||||
func pay_off_wage() -> void:
|
||||
SceneManager.enable_prop_item("prop_银元")
|
||||
SceneManager.enable_important_item("prop_银元")
|
||||
SceneManager.get_inspector().quit_and_hidden.connect(
|
||||
_on_quit_inspect_coin, CONNECT_ONE_SHOT
|
||||
)
|
||||
SceneManager.get_inspector().quit_and_hidden.connect(_on_quit_inspect_coin, CONNECT_ONE_SHOT)
|
||||
_check_portal()
|
||||
|
||||
|
||||
func _on_quit_inspect_coin() -> void:
|
||||
SceneManager.pop_os_with_str("c01_s08_获得袁大头后")
|
||||
|
@ -27,25 +27,26 @@ func _ready() -> void:
|
||||
|
||||
|
||||
func _on_ground_ready() -> void:
|
||||
var camera = SceneManager.get_camera_marker()
|
||||
camera.limit_top = -1000
|
||||
camera.limit_bottom = 158
|
||||
await Util.wait(1.0)
|
||||
# 相机抖动
|
||||
camera.shake_camera()
|
||||
# 不显示玩家,锁定玩家移动
|
||||
SceneManager.freeze_player(0)
|
||||
main_character = $"../DeployLayer/车夫与吕萍"
|
||||
footstep_sfx = $"黄包车Sfx"
|
||||
chapter_sfx = $chapter_sfx
|
||||
SceneManager.get_camera_marker().limit_bottom = 158
|
||||
SceneManager.get_camera_marker().limit_top = -158
|
||||
SceneManager.set_camera_boundary(Rect2(0, -1000, 11360, 1158))
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
# 相机抖动
|
||||
SceneManager.get_camera_marker().shake_camera(8.0, 2.0)
|
||||
# 注意第一段 dialog 在鬼差探头阶段播放
|
||||
play("intro")
|
||||
|
||||
|
||||
# ## test 测试最后运镜 ##
|
||||
# main_character.global_position.x = target_x
|
||||
# await get_tree().create_timer(1.0).timeout
|
||||
# _on_finished()
|
||||
|
||||
|
||||
func dialog1() -> void:
|
||||
DialogueManager.dialogue_ended.connect(_start_running, CONNECT_ONE_SHOT)
|
||||
# 注意第一段 dialog 在鬼差探头阶段播放
|
||||
@ -102,6 +103,7 @@ func dialog3() -> void:
|
||||
dialogue_c01, "c01_s11_车夫对话3", [GlobalConfig.DIALOG_IGNORE_INPUT]
|
||||
)
|
||||
|
||||
|
||||
func dialog4() -> void:
|
||||
DialogueManager.show_dialogue_balloon(
|
||||
dialogue_c01, "c01_s11_车夫对话4", [GlobalConfig.DIALOG_IGNORE_INPUT]
|
||||
@ -126,17 +128,19 @@ func _on_finished():
|
||||
tween.tween_property(marker, "global_position:y", target_y, building_duration)
|
||||
tween.tween_callback(_show_chapter)
|
||||
|
||||
|
||||
func final_dialog():
|
||||
await get_tree().create_timer(2.0).timeout
|
||||
await Util.wait(2.0)
|
||||
DialogueManager.show_dialogue_balloon(
|
||||
dialogue_c01, "c01_s11_车夫对话5", [GlobalConfig.DIALOG_IGNORE_INPUT]
|
||||
)
|
||||
|
||||
|
||||
# 展示章节转场
|
||||
func _show_chapter():
|
||||
chapter_sfx.play()
|
||||
SceneManager.pop_center_texture(chapter_title)
|
||||
get_tree().create_timer(3.5).timeout.connect(_transition)
|
||||
Util.timer(3.5, _transition)
|
||||
|
||||
|
||||
func _transition():
|
||||
|
@ -547,7 +547,7 @@ character = "小小蝶"
|
||||
|
||||
[node name="CameraFocusMarker" parent="Ground" index="6" node_paths=PackedStringArray("focusing_node")]
|
||||
focusing_node = NodePath("../DeployLayer/车夫与吕萍")
|
||||
force_offset = Vector2(50, -48)
|
||||
force_offset = Vector2(30, -30)
|
||||
|
||||
[node name="点缀 黄包车车夫" type="Sprite2D" parent="Ground/ParallaxForeground/BGParallaxLayer" index="0"]
|
||||
position = Vector2(687, 77)
|
||||
|
@ -56,7 +56,7 @@ func intro() -> void:
|
||||
begger.play("杂戏团夜晚_小孩举碗呼吸")
|
||||
# SceneManager.freeze_player(0)
|
||||
# SceneManager.focus_node(begger, 5.)
|
||||
get_tree().create_timer(1.).timeout.connect(_intro_dialog)
|
||||
Util.timer(1., _intro_dialog)
|
||||
|
||||
|
||||
func _intro_dialog() -> void:
|
||||
@ -70,7 +70,7 @@ func _intro_dialog() -> void:
|
||||
func ambush_begger_interacted():
|
||||
begger.play("杂戏团夜晚_小孩放下碗")
|
||||
SceneManager.lock_player(0)
|
||||
await get_tree().create_timer(1.).timeout
|
||||
await Util.wait(1)
|
||||
DialogueManager.show_dialogue_balloon(dialogue_c01, "c01_s12_小孩放下碗")
|
||||
await DialogueManager.dialogue_ended
|
||||
SceneManager.unlock_player()
|
||||
@ -83,7 +83,7 @@ func _on_interactable_bowl_interacted() -> void:
|
||||
DialogueManager.show_dialogue_balloon(dialogue_c01, "c01_s12_鬼差来之前对话")
|
||||
await DialogueManager.dialogue_ended
|
||||
_ghost_move()
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
await Util.wait(1)
|
||||
# 害怕过渡 -> 害怕
|
||||
begger.play("举碗小孩害怕过渡")
|
||||
var kids = $"../DeployLayer/其余小孩"
|
||||
@ -91,7 +91,7 @@ func _on_interactable_bowl_interacted() -> void:
|
||||
var kid = $"../DeployLayer/举腿小孩"
|
||||
kid.play("夜晚举腿小孩杂耍到害怕过渡")
|
||||
$"Sfx鬼差出场".play()
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
await Util.wait(1)
|
||||
DialogueManager.show_dialogue_balloon(dialogue_c01, "c01_s12_鬼差来了")
|
||||
var tween = create_tween()
|
||||
var camera = SceneManager.get_camera_marker()
|
||||
@ -143,14 +143,12 @@ func player_been_catched(transition := true) -> void:
|
||||
SceneManager.pop_debug_dialog_info("美术", "玩家被鬼差抓住")
|
||||
# 等待动画播放完成
|
||||
# TODO 添加转场前效果?
|
||||
await get_tree().create_timer(1.5).timeout
|
||||
var ground_loader = SceneManager.get_ground_loader()
|
||||
await Util.wait(1.5)
|
||||
# 传送到起点,继续跑
|
||||
ground_loader.toggle_mask(true, Color.BLACK, 0.5)
|
||||
await get_tree().create_timer(0.5).timeout
|
||||
await SceneManager.toggle_ground_mask(true).finished
|
||||
# 恢复花朵
|
||||
flower.reset_all_blooming()
|
||||
ground_loader.toggle_mask(false, Color.BLACK, 1.0)
|
||||
await SceneManager.toggle_ground_mask(false).finished
|
||||
# reset player and ghost position
|
||||
ghost.global_position.x = ghost_start_x + 100.0
|
||||
SceneManager.get_player().global_position.x = player_start_x
|
||||
|
@ -14,7 +14,7 @@ func _ready() -> void:
|
||||
return
|
||||
# if not data["received_letter"]:
|
||||
# SceneManager.freeze_player(1.5)
|
||||
# get_tree().create_timer(1.5).timeout.connect(_give_letter)
|
||||
# Util.timer(1.5, _give_letter)
|
||||
# elif GlobalConfig.DEBUG:
|
||||
# print("_give_letter 已发放")
|
||||
|
||||
|
@ -86,7 +86,7 @@ func _on_ground_ready() -> void:
|
||||
if EventManager.get_stage("c02_madman_interacted") == 1:
|
||||
SceneManager.lock_player(0)
|
||||
# 等待转场
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
await Util.wait(1)
|
||||
small_shoe.enabled = true
|
||||
var y2 = small_shoe.position.y
|
||||
var y1 = y2 - 150
|
||||
@ -175,16 +175,16 @@ func eavesdrop() -> void:
|
||||
# 12 c00_吕萍_蹲下 13 c00_吕萍_蹲下呼吸 14 c00_吕萍_起立
|
||||
SceneManager.lock_player(0, 12)
|
||||
# play("eavesdrop")
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
await Util.wait(1)
|
||||
SceneManager.player_action(13)
|
||||
# 对话
|
||||
DialogueManager.show_dialogue_balloon(dialogue_c02, "c02_04_李氏癞子")
|
||||
await DialogueManager.dialogue_ended
|
||||
eavesdrop_window.visible = false
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
await Util.wait(1)
|
||||
SceneManager.player_action(14, true)
|
||||
ArchiveManager.set_global_entry(&"c02_eavesdrop_finished", true)
|
||||
await get_tree().create_timer(1.5).timeout
|
||||
await Util.wait(1.5)
|
||||
SceneManager.unlock_player()
|
||||
|
||||
|
||||
|
@ -27,5 +27,5 @@ func _on_closeup_tin_coin_exited(arg = null):
|
||||
if arg == true:
|
||||
ArchiveManager.set_global_entry(&"c02_tin_coin_taken", true)
|
||||
SceneManager.enable_prop_item_silently("prop_锡箔元宝")
|
||||
await get_tree().create_timer(0.5).timeout
|
||||
await Util.wait(0.5)
|
||||
SceneManager.enable_prop_item("prop_锡箔元宝")
|
||||
|
@ -44,7 +44,7 @@ func _on_ground_ready() -> void:
|
||||
mice_hole.enabled = false
|
||||
gas_light_upon_hole.lighted.connect(func():
|
||||
mice_hole.enabled = true
|
||||
get_tree().create_timer(1.5).timeout.connect(
|
||||
Util.timer(1.5,
|
||||
SceneManager.pop_os_with_str.bind("c02_二楼血脚印")
|
||||
)
|
||||
)
|
||||
|
@ -43,12 +43,4 @@ func take_off_flyer(immediatelly = false):
|
||||
flyer.visible = false
|
||||
var hand = $"../DeployLayer/小手讨东西"
|
||||
hand.enabled = true
|
||||
# if hand.icount == 0:
|
||||
# await get_tree().create_timer(1.0).timeout
|
||||
# hand.icount += 1
|
||||
# SceneManager.lock_player()
|
||||
# await hand.do_first_interact(immediatelly)
|
||||
# SceneManager.unlock_player()
|
||||
|
||||
|
||||
|
||||
|
@ -98,7 +98,7 @@ func eavesdrop_start() -> void:
|
||||
var node = $"../DeployLayer/瞎子小蝉对话"
|
||||
node.visible = true
|
||||
# 偷听动作
|
||||
await get_tree().create_timer(2.0).timeout
|
||||
await Util.wait(2.0)
|
||||
# 动作后先出声音
|
||||
DialogueManager.show_dialogue_balloon(dialogue_c02, "c02_05_瞎子与小蝉")
|
||||
var tween = create_tween()
|
||||
|
@ -36,7 +36,7 @@ func _on_ground_ready() -> void:
|
||||
var half_length = rope_length / 2.0
|
||||
rope_range.x = rope.global_position.x - half_length
|
||||
rope_range.y = rope.global_position.x + half_length
|
||||
await get_tree().create_timer(0.1).timeout
|
||||
await Util.wait(0.1)
|
||||
var player = %MainPlayer
|
||||
# 玩家位置更新时,更新麻绳隆起
|
||||
player.position_updated.connect(_on_player_position_updated)
|
||||
|
@ -24,12 +24,12 @@ func knock_light_door():
|
||||
for _i in range(100):
|
||||
AudioManager.play_sfx(knock_stream)
|
||||
SceneManager.lock_player(0, 6)
|
||||
await get_tree().create_timer(0.5).timeout
|
||||
await Util.wait(0.5)
|
||||
# 被抓时打断
|
||||
if not player.visible or player.hide_sprite:
|
||||
_outtro_show()
|
||||
break
|
||||
await get_tree().create_timer(0.5).timeout
|
||||
await Util.wait(0.5)
|
||||
# 被抓时打断
|
||||
if not player.visible or player.hide_sprite:
|
||||
_outtro_show()
|
||||
@ -42,10 +42,10 @@ func _outtro_show():
|
||||
# 禁止猪头怪动画播放结束后重开游戏
|
||||
$"../DeployLayer/追猫猪头怪_传送".allow_restart_game = false
|
||||
$"Sfx结尾演出".play()
|
||||
await get_tree().create_timer(8.0).timeout
|
||||
await Util.wait(8.0)
|
||||
$"../盒子猫CanvasLayer".show_footprint()
|
||||
$"Sfx脚印".play()
|
||||
# 盒子猫逃脱成功/被抓走,游戏结束,解锁瞎子卧室门
|
||||
await get_tree().create_timer(10.0).timeout
|
||||
await Util.wait(10.0)
|
||||
ArchiveManager.set_global_entry(&"c02_the_blind_room_unlocked", true)
|
||||
SceneManager.get_ground_loader().transition_to_scene("c02_s08", "1")
|
||||
|
@ -22,7 +22,7 @@ func play_bgm():
|
||||
|
||||
func pre_finished():
|
||||
# 在 animation player 结束前 1 秒调用
|
||||
CanvasUtil.shake_layer(self, 2.0, 4.0, 15.0)
|
||||
Util.shake_layer(self, 2.0, 4.0, 15.0)
|
||||
# debug 模式允许跳过
|
||||
if GlobalConfig.DEBUG:
|
||||
DialogueManager.show_dialogue_balloon(dialogue_c01, "c01_s11_车夫对话1")
|
||||
|
@ -71,8 +71,8 @@ func _on_interacted() -> void:
|
||||
$SfxOpen.play()
|
||||
var inspect_texture = preload("res://asset/art/scene/c01/s07_书店外/纸片_正面.png")
|
||||
var res = preload("res://asset/dialogue/inspect_content.dialogue")
|
||||
var lines = await DialogueUtil.get_lines(res, "c01_飘落的寻人启事")
|
||||
var note = DialogueUtil.concact_content_from_lines(lines)
|
||||
var lines = await Util.get_lines(res, "c01_飘落的寻人启事")
|
||||
var note = Util.concact_content_from_lines(lines)
|
||||
SceneManager.get_inspector().pop_standard_inspection(inspect_texture, null, note, false)
|
||||
|
||||
|
||||
|
@ -135,14 +135,14 @@ func _gaslight_interacted():
|
||||
else:
|
||||
# 高位 5 号
|
||||
SceneManager.freeze_player(2.0, 5)
|
||||
await get_tree().create_timer(0.8).timeout
|
||||
await Util.wait(0.8)
|
||||
sfx_success.play()
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
await Util.wait(1)
|
||||
_switch_gaslight(true, true)
|
||||
lighted.emit()
|
||||
if not ArchiveManager.get_global_value(&"c02_gaslight_first_lighted"):
|
||||
ArchiveManager.set_global_entry(&"c02_gaslight_first_lighted", true)
|
||||
var scene = ArchiveManager.archive.current_scene
|
||||
if scene == "c02_s02" or scene == "c02_s03":
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
await Util.wait(1)
|
||||
SceneManager.pop_os_with_str("c02_使用煤油灯")
|
||||
|
@ -52,6 +52,7 @@ texture = SubResource("ImageTexture_cffxi")
|
||||
stretch_mode = 5
|
||||
|
||||
[node name="Sfx撕海报" type="AudioStreamPlayer" parent="."]
|
||||
process_mode = 1
|
||||
stream = ExtResource("5_xjg44")
|
||||
bus = &"game_sfx"
|
||||
script = ExtResource("6_cffxi")
|
||||
|
@ -66,7 +66,7 @@ var icount: int:
|
||||
# 9 小手交互,吓摔倒
|
||||
SceneManager.lock_player(0, 9, true)
|
||||
SceneManager.pop_os_with_str("c02_小手出现摔倒")
|
||||
get_tree().create_timer(1.5).timeout.connect($"Sfx摔倒".play)
|
||||
Util.timer(1.5, $"Sfx摔倒".play)
|
||||
await SceneManager.get_player().animation_finished
|
||||
SceneManager.unlock_player()
|
||||
elif stage == 1:
|
||||
@ -194,7 +194,7 @@ func _on_interacted() -> void:
|
||||
SceneManager.pop_debug_dialog_info(
|
||||
"美术", "叠成纸杯: 小手_锡箔_hide + 小手_纸杯_show + 小手_纸杯_idle"
|
||||
)
|
||||
await get_tree().create_timer(2).timeout
|
||||
await Util.wait(2.0)
|
||||
# 稍等片刻再给小鞋子
|
||||
SceneManager.enable_prop_item("prop_小鞋子1")
|
||||
await SceneManager.get_inspector().quit_and_hidden
|
||||
@ -210,7 +210,7 @@ func _on_interacted() -> void:
|
||||
# 先设置允许 pickable,然后再设置可见性,等待动画播完再显示
|
||||
tin_coin_drop = true
|
||||
coin.visible = false
|
||||
await get_tree().create_timer(1.5).timeout
|
||||
await Util.wait(1.5)
|
||||
coin.visible = true
|
||||
if not ArchiveManager.get_global_value(&"c02_little_hand_dropped_tin"):
|
||||
SceneManager.pop_os_with_str("c02_小手要东西")
|
||||
@ -224,7 +224,7 @@ func _on_interacted() -> void:
|
||||
SceneManager.disable_prop_item("prop_老虎钳")
|
||||
animated_sprite.play("小手_老虎钳_hide")
|
||||
SceneManager.pop_debug_dialog_info("美术", "小手_老虎钳_hide + 小手_弹珠_show + 小手_弹珠_idle")
|
||||
await get_tree().create_timer(1.5).timeout
|
||||
await Util.wait(1.5)
|
||||
holding_prop = "prop_弹珠"
|
||||
EventManager.set_stage_if_greater("handnote_stage", 4)
|
||||
elif id == 0 and key == "prop_弹珠" and not pliers_to_ball:
|
||||
@ -233,7 +233,7 @@ func _on_interacted() -> void:
|
||||
SceneManager.disable_prop_item("prop_弹珠")
|
||||
animated_sprite.play("小手_弹珠_hide")
|
||||
SceneManager.pop_debug_dialog_info("美术", "小手_弹珠_hide + 小手_老虎钳_show + 小手_老虎钳_idle")
|
||||
await get_tree().create_timer(1.5).timeout
|
||||
await Util.wait(1.5)
|
||||
holding_prop = "prop_老虎钳"
|
||||
|
||||
if interacted_success:
|
||||
|
@ -59,7 +59,7 @@ func _on_button_pressed() -> void:
|
||||
button.disabled = true
|
||||
# 肉落下的声音,然后自动退出界面
|
||||
SceneManager.pop_debug_dialog_info("音效", "肉落下的声音(敲门游戏成功)")
|
||||
await get_tree().create_timer(2.0).timeout
|
||||
await Util.wait(2)
|
||||
exit.emit(true)
|
||||
else:
|
||||
SceneManager.pop_debug_dialog_info("音效", "敲门:" + str(current_id))
|
||||
|
@ -25,7 +25,7 @@ func _ready() -> void:
|
||||
tween.tween_property(child_sprite, "modulate:a", 0.0, 0.5)
|
||||
else:
|
||||
child_sprite.modulate.a = 0
|
||||
await get_tree().create_timer(1.5).timeout
|
||||
await Util.wait(1.5)
|
||||
_try_ripple()
|
||||
|
||||
func _try_ripple():
|
||||
|
@ -28,7 +28,7 @@ func _on_area_entered(_body):
|
||||
if not _body is MainPlayer:
|
||||
return
|
||||
label.visible = true
|
||||
await get_tree().create_timer(randf()).timeout
|
||||
await Util.wait(randf())
|
||||
var tween = create_tween()
|
||||
tween.tween_property(label, "position:y", 3.0, 0.6).set_trans(Tween.TRANS_BOUNCE)
|
||||
tween.tween_property(label, "position:y", 0.0, 0.6).set_trans(Tween.TRANS_BOUNCE)
|
||||
|
@ -72,7 +72,7 @@ func start():
|
||||
#### part3: 小蝉捂眼,瞎子、胖子声音
|
||||
# 小蝉身体回正、捂眼
|
||||
DialogueManager.show_dialogue_balloon(dialogue_c02, "c02_s11_谢幕交谈2")
|
||||
get_tree().create_timer(5.0).timeout.connect(_hand_cover_eyes)
|
||||
Util.timer(5.0, _hand_cover_eyes)
|
||||
await DialogueManager.dialogue_ended
|
||||
SceneManager.pop_debug_dialog_info("音效", "小蝉笑声/耳鸣")
|
||||
await create_tween().tween_interval(3.0).finished
|
||||
@ -100,9 +100,9 @@ func _on_got_dialogue(line: DialogueLine):
|
||||
if speak:
|
||||
if first_speak:
|
||||
first_speak = false
|
||||
await get_tree().create_timer(2.0).timeout
|
||||
await Util.wait(2)
|
||||
else:
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
await Util.wait(1)
|
||||
toggle_speak(speak)
|
||||
|
||||
|
||||
|
@ -92,7 +92,7 @@ func _on_ground_ready():
|
||||
# 禁用传送过来的 portal 3s
|
||||
_disable_portal_a_few_seconds(portal_node)
|
||||
# 3 秒后传送
|
||||
get_tree().create_timer(1.0).timeout.connect(_do_transfer)
|
||||
Util.timer(1.0, _do_transfer)
|
||||
if GlobalConfig.DEBUG:
|
||||
print("猪头怪 Transfer to: " + portal)
|
||||
else:
|
||||
@ -108,7 +108,7 @@ func _on_footstep_timer_timeout() -> void:
|
||||
footstep_count += 1
|
||||
if footstep_count % 2 == 0:
|
||||
# shake camera
|
||||
camera.shake_camera(4.0, 5.0)
|
||||
camera.shake_camera()
|
||||
if abs(signed_x_diff) > 250:
|
||||
if footstep_count % 3 == 0:
|
||||
sfx_footstep.play()
|
||||
@ -177,7 +177,7 @@ func do_catch(front: bool):
|
||||
# 其次 catch_nearby 播放 猪头怪抓盒子猫后段
|
||||
sprite2d.play("猪头怪抓盒子猫后段")
|
||||
# 被抓音效
|
||||
get_tree().create_timer(0.5).timeout.connect($"Sfx猫被抓".play)
|
||||
Util.timer(0.5, $"Sfx猫被抓".play)
|
||||
# 呼吸声渐隐
|
||||
$"Sfx喘气".easing_kill()
|
||||
SceneManager.pop_debug_dialog_info("音效", "抓取过程。 从捡小猫开始=" + str(front))
|
||||
|
@ -249,7 +249,7 @@ func _success() -> void:
|
||||
|
||||
func _on_target_book_pressed():
|
||||
$"Shelf/生死簿".play("书架扶正")
|
||||
await get_tree().create_timer(1.5).timeout
|
||||
await Util.wait(1.5)
|
||||
$"生死簿".show()
|
||||
# 完成后释放信号
|
||||
$"生死簿".finished.connect(_on_success_finished)
|
||||
|
@ -119,7 +119,7 @@ func _on_drawer_picked(_node):
|
||||
box_animation.play()
|
||||
drawer_btn.visible = false
|
||||
await box_animation.animation_finished
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
await Util.wait(1)
|
||||
box_animation.visible = false
|
||||
box_broken.visible = false
|
||||
box_drawer.visible = true
|
||||
@ -200,7 +200,7 @@ func _on_wheel_rotated(radiant: float) -> void:
|
||||
sfx_music.play()
|
||||
else:
|
||||
sfx_music.stream_paused = false
|
||||
get_tree().create_timer(playing_step_sec).timeout.connect(_on_playing_step_finished)
|
||||
Util.timer(playing_step_sec, _on_playing_step_finished)
|
||||
|
||||
|
||||
func _on_playing_step_finished():
|
||||
@ -211,7 +211,7 @@ func _on_playing_step_finished():
|
||||
return
|
||||
if continue_playing:
|
||||
continue_playing = false
|
||||
get_tree().create_timer(playing_step_sec).timeout.connect(_on_playing_step_finished)
|
||||
Util.timer(playing_step_sec, _on_playing_step_finished)
|
||||
else:
|
||||
playing = false
|
||||
sfx_music.stream_paused = true
|
||||
@ -226,7 +226,7 @@ func _checkout_auto_play():
|
||||
# var audio_len = audio_auto.get_length()
|
||||
# 音效 9.5 秒时关闭盒子
|
||||
var audio_len = 9.5
|
||||
get_tree().create_timer(audio_len).timeout.connect(_on_auto_play_finished)
|
||||
Util.timer(audio_len, _on_auto_play_finished)
|
||||
|
||||
|
||||
func _on_auto_play_finished():
|
||||
|
@ -66,7 +66,7 @@ func _ready() -> void:
|
||||
# # test close shaking effect
|
||||
# ArchiveManager.archive.bayinhe_mode = "playing"
|
||||
# _chechout_mode(true)
|
||||
# get_tree().create_timer(1.0).timeout.connect(_on_auto_play_finished)
|
||||
# Util.timer(1.0, _on_auto_play_finished)
|
||||
|
||||
|
||||
func _on_visibility_changed() -> void:
|
||||
@ -224,7 +224,7 @@ func _on_wheel_rotated(radiant: float) -> void:
|
||||
audio_player.play()
|
||||
else:
|
||||
audio_player.stream_paused = false
|
||||
get_tree().create_timer(playing_step_sec).timeout.connect(_on_playing_step_finished)
|
||||
Util.timer(playing_step_sec, _on_playing_step_finished)
|
||||
|
||||
|
||||
func _on_playing_step_finished():
|
||||
@ -235,7 +235,7 @@ func _on_playing_step_finished():
|
||||
return
|
||||
if continue_playing:
|
||||
continue_playing = false
|
||||
get_tree().create_timer(playing_step_sec).timeout.connect(_on_playing_step_finished)
|
||||
Util.timer(playing_step_sec, _on_playing_step_finished)
|
||||
else:
|
||||
playing = false
|
||||
audio_player.stream_paused = true
|
||||
@ -250,7 +250,7 @@ func _checkout_auto_play():
|
||||
# var audio_len = audio_auto.get_length()
|
||||
# 音效 9.5 秒时关闭盒子
|
||||
var audio_len = 9.5
|
||||
get_tree().create_timer(audio_len).timeout.connect(_on_auto_play_finished)
|
||||
Util.timer(audio_len, _on_auto_play_finished)
|
||||
|
||||
|
||||
func _on_auto_play_finished():
|
||||
|
@ -245,13 +245,13 @@ func game_win() -> void:
|
||||
# 0:默认 1:寻找弹珠(老虎钳可以换弹珠) 2:给出弹珠 3:游戏结束
|
||||
ArchiveManager.set_global_entry(&"c02_ball_game_stage", 3)
|
||||
%"Sfx结尾小孩跑".play()
|
||||
CanvasUtil.shake_layer(self, 2.0)
|
||||
Util.shake_layer(self, 2.0)
|
||||
# 弹珠雨
|
||||
$BallsFalling.emitting = true
|
||||
pivot.visible = false
|
||||
DialogueManager.show_dialogue_balloon_scene(self, dialogue_c02, "c02_弹珠游戏4")
|
||||
await ball_dialogue_ended
|
||||
await get_tree().create_timer(3.0).timeout
|
||||
await Util.wait(3.0)
|
||||
exit.emit(true)
|
||||
|
||||
|
||||
@ -303,15 +303,4 @@ func apply_dialogue_line() -> void:
|
||||
tween.tween_property(label, "modulate:a", 1.0, 0.5)
|
||||
tween.tween_interval(2.0)
|
||||
tween.tween_property(label, "modulate:a", 0.0, 0.5)
|
||||
# # 因为版权问题,有些 mp3 文件打不开,所以使用 ogg 格式
|
||||
# var audio_path = "res://asset/audio/peiyin/ogg/%s.ogg" % translation_key
|
||||
# if FileAccess.file_exists(audio_path):
|
||||
# var stream = load(audio_path)
|
||||
# audio_player.stream = stream
|
||||
# audio_player.play()
|
||||
# await audio_player.finished
|
||||
# await get_tree().create_timer(1.0).timeout
|
||||
# else:
|
||||
# push_warning("No audio file found for " + translation_key)
|
||||
# await get_tree().create_timer(3.0).timeout
|
||||
ball_dialogue_ended.emit()
|
||||
|
@ -32,7 +32,7 @@ func _ready() -> void:
|
||||
|
||||
func _enter_tree() -> void:
|
||||
SceneManager.pop_center_notification(tr("input_拼凑信件"))
|
||||
await get_tree().create_timer(4.0).timeout
|
||||
await Util.wait(4.0)
|
||||
SceneManager.pop_center_notification(tr("ui_press_q_to_exit"))
|
||||
|
||||
func _setup() -> void:
|
||||
@ -144,7 +144,7 @@ func _post_success():
|
||||
SceneManager.enable_important_item("prop_院长的信")
|
||||
whole.visible = false
|
||||
# 1s 后退出
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
await Util.wait(1.0)
|
||||
if get_parent() != null:
|
||||
success.emit()
|
||||
get_parent().remove_child(self)
|
||||
|
@ -76,9 +76,9 @@ func _ready():
|
||||
# navigation
|
||||
return_btn.pressed.connect(_on_return_btn_pressed)
|
||||
return_btn.grab_focus()
|
||||
SceneManager.toggle_pause_counter(true)
|
||||
# open
|
||||
$"Sfx打开".play()
|
||||
SceneManager.toggle_pause_counter(true)
|
||||
|
||||
|
||||
func _on_master_bus_slider_value_changed(value: float) -> void:
|
||||
|
@ -11,7 +11,7 @@ func run_clip(card_mode: bool):
|
||||
tween.tween_interval(5.0)
|
||||
tween.tween_property($"井", "modulate:a", 1.0, 5.0)
|
||||
if not card_mode:
|
||||
await get_tree().create_timer(3.0).timeout
|
||||
await Util.wait(3.0)
|
||||
# 增加配音
|
||||
dialog_node = DialogueManager.show_dialogue_balloon(dialogue_res, "c02_s11_井边疯子对话")
|
||||
dialog_node.process_mode = Node.PROCESS_MODE_ALWAYS
|
||||
|
@ -12,10 +12,10 @@ func _ready() -> void:
|
||||
$SfxOpen.play()
|
||||
layer = GlobalConfig.CANVAS_LAYER_UX_PANEL
|
||||
SceneManager.toggle_pause_counter(true)
|
||||
continue_btn.pressed.connect(quit)
|
||||
continue_btn.pressed.connect(_continue)
|
||||
note_btn.pressed.connect(SceneManager.show_note)
|
||||
settings_btn.pressed.connect(SceneManager.show_settings)
|
||||
main_menu_btn.pressed.connect(SceneManager.checkout_index_page)
|
||||
main_menu_btn.pressed.connect(_index_menu)
|
||||
quit_btn.pressed.connect(_quit_game)
|
||||
|
||||
func _quit_game() -> void:
|
||||
@ -23,16 +23,22 @@ func _quit_game() -> void:
|
||||
ArchiveManager.notification(NOTIFICATION_WM_CLOSE_REQUEST)
|
||||
# 退出游戏过程隐藏界面
|
||||
# 隐藏 panel
|
||||
quit()
|
||||
_continue()
|
||||
|
||||
func quit():
|
||||
$SfxOpen.global_play()
|
||||
func _continue():
|
||||
$SfxClose.global_play()
|
||||
SceneManager.toggle_pause_counter(false)
|
||||
queue_free()
|
||||
|
||||
|
||||
func _index_menu():
|
||||
SceneManager.checkout_index_page()
|
||||
# 允许 ground loader 运行 transition
|
||||
_continue()
|
||||
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
# panel 界面接受所有输入事件
|
||||
get_viewport().set_input_as_handled()
|
||||
if event.is_action_pressed("cancel") or event.is_action_pressed("escape"):
|
||||
quit()
|
||||
_continue()
|
||||
|
@ -99,7 +99,7 @@ theme_override_fonts/font = ExtResource("4_mns6r")
|
||||
theme_override_font_sizes/font_size = 20
|
||||
theme_override_styles/hover = SubResource("StyleBoxLine_v1oku")
|
||||
theme_override_styles/pressed = SubResource("StyleBoxLine_a3uyd")
|
||||
text = "ux_panel_笔记"
|
||||
text = "ux_panel_线索笔记"
|
||||
flat = true
|
||||
|
||||
[node name="MarginContainer3" type="MarginContainer" parent="Bag"]
|
||||
|
@ -81,10 +81,23 @@ func _on_tab_memory_pressed():
|
||||
root.quit()
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
sfx_close.global_play()
|
||||
var play_close_on_exit_tree = true
|
||||
|
||||
# func _unhandled_input(event: InputEvent) -> void:
|
||||
# if event.is_action_pressed("memory") and current_type != "回忆":
|
||||
# get_viewport().set_input_as_handled()
|
||||
# SceneManager.show_memory()
|
||||
func _exit_tree() -> void:
|
||||
if play_close_on_exit_tree:
|
||||
sfx_close.global_play()
|
||||
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed("memory") and current_type != "回忆":
|
||||
get_viewport().set_input_as_handled()
|
||||
play_close_on_exit_tree = false
|
||||
_on_tab_memory_pressed()
|
||||
elif event.is_action_pressed("note") and current_type != "线索":
|
||||
get_viewport().set_input_as_handled()
|
||||
play_close_on_exit_tree = false
|
||||
_on_tab_note_pressed()
|
||||
elif event.is_action_pressed("bag") and current_type != "物品":
|
||||
get_viewport().set_input_as_handled()
|
||||
play_close_on_exit_tree = false
|
||||
_on_tab_bag_pressed()
|
||||
|
@ -1,14 +0,0 @@
|
||||
class_name CanvasUtil extends Object
|
||||
|
||||
|
||||
static func shake_layer(layer: CanvasLayer, duration: float, delta := 2.0, fps := 20.0) -> void:
|
||||
var tween = layer.create_tween()
|
||||
# shake layer's offset
|
||||
var origin_offset = layer.offset
|
||||
var count = int(duration * fps)
|
||||
var delta_t = 1.0 / fps
|
||||
for i in range(count):
|
||||
var offset = Vector2(randf_range(-delta, delta), randf_range(-delta, delta))
|
||||
tween.tween_property(layer, "offset", origin_offset + offset, delta_t)
|
||||
# tween back to origin
|
||||
tween.tween_property(layer, "offset", origin_offset, delta_t)
|
@ -1 +0,0 @@
|
||||
uid://l4egv2jc0vjb
|
@ -1,22 +0,0 @@
|
||||
class_name DebugLabel extends Label
|
||||
|
||||
@export var enabled := false:
|
||||
set(value):
|
||||
enabled = value
|
||||
if enabled:
|
||||
_display()
|
||||
else:
|
||||
_hide()
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if not GlobalConfig.DEBUG:
|
||||
return
|
||||
|
||||
|
||||
func _hide():
|
||||
visible = false
|
||||
|
||||
|
||||
func _display():
|
||||
pass
|
@ -1 +0,0 @@
|
||||
uid://cgi8uhk7ii5o6
|
@ -1,30 +0,0 @@
|
||||
class_name DialogueUtil extends RefCounted
|
||||
|
||||
static func concact_content_from_lines(lines:=[]):
|
||||
if lines.is_empty():
|
||||
return ""
|
||||
var content = ""
|
||||
for i in range(len(lines) - 1):
|
||||
var line = lines[i] as DialogueLine
|
||||
content += TranslationServer.tr(line.translation_key) + "\n"
|
||||
# last line without "\n"
|
||||
content += TranslationServer.tr(lines[-1].translation_key)
|
||||
return content
|
||||
|
||||
static func get_lines(res: DialogueResource, title: String) -> Array:
|
||||
var lines = []
|
||||
var current_line = await res.get_next_dialogue_line(title)
|
||||
while current_line:
|
||||
lines.append(current_line)
|
||||
if current_line.next_id != "end":
|
||||
current_line = await res.get_next_dialogue_line(current_line.next_id)
|
||||
else:
|
||||
break
|
||||
return lines
|
||||
|
||||
# pop os lines
|
||||
static func generate_lines(content: String) -> Array:
|
||||
var text = "~ title\n" + content + "\n=> END"
|
||||
var res = DialogueManager.create_resource_from_text(text)
|
||||
return await get_lines(res, "title")
|
||||
|
@ -1 +0,0 @@
|
||||
uid://ckwvshyrj4vns
|
58
util/util.gd
Normal file
@ -0,0 +1,58 @@
|
||||
extends Node
|
||||
|
||||
|
||||
#### Timer
|
||||
func wait(duration: float) -> void:
|
||||
await get_tree().create_timer(duration).timeout
|
||||
|
||||
|
||||
func timer(duration: float, callable: Callable) -> SceneTreeTimer:
|
||||
var t = get_tree().create_timer(duration, false)
|
||||
t.timeout.connect(callable)
|
||||
return t
|
||||
|
||||
|
||||
#### Canvas
|
||||
func shake_layer(layer: CanvasLayer, duration: float, delta := 2.0, fps := 20.0) -> void:
|
||||
var tween = layer.create_tween()
|
||||
# shake layer's offset
|
||||
var origin_offset = layer.offset
|
||||
var count = int(duration * fps)
|
||||
var delta_t = 1.0 / fps
|
||||
for i in range(count):
|
||||
var offset = Vector2(randf_range(-delta, delta), randf_range(-delta, delta))
|
||||
tween.tween_property(layer, "offset", origin_offset + offset, delta_t)
|
||||
# tween back to origin
|
||||
tween.tween_property(layer, "offset", origin_offset, delta_t)
|
||||
|
||||
|
||||
###### Dialogue
|
||||
func concact_content_from_lines(lines := []):
|
||||
if lines.is_empty():
|
||||
return ""
|
||||
var content = ""
|
||||
for i in range(len(lines) - 1):
|
||||
var line = lines[i] as DialogueLine
|
||||
content += TranslationServer.tr(line.translation_key) + "\n"
|
||||
# last line without "\n"
|
||||
content += TranslationServer.tr(lines[-1].translation_key)
|
||||
return content
|
||||
|
||||
|
||||
func get_lines(res: DialogueResource, title: String) -> Array:
|
||||
var lines = []
|
||||
var current_line = await res.get_next_dialogue_line(title)
|
||||
while current_line:
|
||||
lines.append(current_line)
|
||||
if current_line.next_id != "end":
|
||||
current_line = await res.get_next_dialogue_line(current_line.next_id)
|
||||
else:
|
||||
break
|
||||
return lines
|
||||
|
||||
|
||||
# pop os lines
|
||||
func generate_lines(content: String) -> Array:
|
||||
var text = "~ title\n" + content + "\n=> END"
|
||||
var res = DialogueManager.create_resource_from_text(text)
|
||||
return await get_lines(res, "title")
|
1
util/util.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://cqkbvu00n5ao8
|