Merge remote-tracking branch 'origin/demo'

This commit is contained in:
cakipaul 2025-07-20 20:13:12 +08:00
commit ab5b7ecf4f
40 changed files with 1317 additions and 227 deletions

View File

@ -0,0 +1,43 @@
extends CanvasLayer
@onready var quit_debug_button: Button = %QuitDebugModeButton
func _ready() -> void:
AudioManager.process_mode = Node.PROCESS_MODE_PAUSABLE
SceneManager.toggle_pause_counter(true, "debugging")
layer = GlobalConfig.CANVAS_LAYER_SETTINGS
quit_debug_button.pressed.connect(_on_quit_debug_button_pressed)
# 恢复上次打开的 tab
var tab = ArchiveManager.get_global_value(&"debug_panel_tab", 0)
%TabContainer.current_tab = tab
func _input(event: InputEvent) -> void:
if (
event.is_action_pressed("debugging")
or event.is_action_pressed("cancel")
or event.is_action_pressed("escape")
):
get_viewport().set_input_as_handled()
quit()
func _on_quit_debug_button_pressed() -> void:
# 不写入配置
GlobalConfig.DEBUG = false
quit()
func _exit_tree() -> void:
AudioManager.process_mode = Node.PROCESS_MODE_ALWAYS
SceneManager.toggle_pause_counter(false, "debugging")
func quit() -> void:
queue_free()
func _on_tab_container_tab_changed(tab: int) -> void:
ArchiveManager.set_global_entry(&"debug_panel_tab", tab)

View File

@ -0,0 +1 @@
uid://d3aitlnh5hrfc

View File

@ -0,0 +1,60 @@
[gd_scene load_steps=5 format=3 uid="uid://d4jeeteyq8kk3"]
[ext_resource type="PackedScene" uid="uid://bo4f3sdubdp61" path="res://manager/archive_manager/savings_panel.tscn" id="1_fbybo"]
[ext_resource type="Script" uid="uid://d3aitlnh5hrfc" path="res://manager/archive_manager/debug_panel.gd" id="1_k0pa6"]
[ext_resource type="PackedScene" uid="uid://b6ogrp5ec5nr3" path="res://manager/archive_manager/sfx_config_panel.tscn" id="2_t7mby"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_k0pa6"]
bg_color = Color(0, 0, 0, 1)
[node name="DebugLayer" type="CanvasLayer"]
process_mode = 3
scale = Vector2(0.5, 0.5)
transform = Transform2D(0.5, 0, 0, 0.5, 0, 0)
script = ExtResource("1_k0pa6")
[node name="PanelContainer" type="PanelContainer" parent="."]
offset_left = 68.0
offset_top = 28.0
offset_right = 1068.0
offset_bottom = 606.0
theme_override_styles/panel = SubResource("StyleBoxFlat_k0pa6")
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer"]
layout_mode = 2
[node name="HBoxContainer" type="HBoxContainer" parent="PanelContainer/VBoxContainer"]
layout_mode = 2
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 18
text = "Debug 面板"
horizontal_alignment = 1
[node name="QuitDebugModeButton" type="Button" parent="PanelContainer/VBoxContainer/HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
text = "关闭 Debug 模式"
[node name="TabContainer" type="TabContainer" parent="PanelContainer/VBoxContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(1000, 0)
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
mouse_filter = 0
current_tab = 0
[node name="存档控制" parent="PanelContainer/VBoxContainer/TabContainer" instance=ExtResource("1_fbybo")]
unique_name_in_owner = true
layout_mode = 2
[node name="音效控制" parent="PanelContainer/VBoxContainer/TabContainer" instance=ExtResource("2_t7mby")]
unique_name_in_owner = true
visible = false
layout_mode = 2
metadata/_tab_index = 1
[connection signal="tab_changed" from="PanelContainer/VBoxContainer/TabContainer" to="." method="_on_tab_container_tab_changed"]

View File

@ -1,7 +1,6 @@
extends Control
# UI References
@onready var quit_debug_button: Button = %QuitDebugModeButton
@onready var archive_grid: GridContainer = %ArchiveGrid
@onready var scroll_container: ScrollContainer = %ScrollContainer
@onready var current_archive_label: Label = %CurrentArchiveLabel
@ -18,11 +17,9 @@ var next_available_id: int = 2 # Start from 2 since 1 is reserved for main arch
func _ready() -> void:
get_parent().layer = GlobalConfig.CANVAS_LAYER_SETTINGS
# Setup UI
archive_grid.columns = GRID_COLUMNS
# Connect signals
quit_debug_button.pressed.connect(_on_quit_debug_button_pressed)
save_button.pressed.connect(_on_save_button_pressed)
refresh_button.pressed.connect(_refresh_archive_list)
name_input.text_submitted.connect(_on_name_submitted)
@ -57,12 +54,6 @@ func _on_name_submitted(_text: String) -> void:
_on_save_button_pressed()
func _on_quit_debug_button_pressed() -> void:
# 不写入配置
GlobalConfig.DEBUG = false
quit()
func _on_save_button_pressed() -> void:
# Check limit
if manual_archives.size() >= MAX_MANUAL_ARCHIVES:
@ -152,7 +143,7 @@ func _copy_current_archive(archive_name: String) -> void:
func _refresh_archive_list() -> void:
# refresh savings name
# refresh debugging name
_update_default_name()
# Clear existing items
@ -245,7 +236,7 @@ func _load_manual_archive(_id: int, data: Dictionary) -> void:
ArchiveManager.archive = saving_archive
print("Loading archive from: ", data.path, " to: ", target_path)
# Reload current scene
get_tree().reload_current_scene()
SceneManager.enter_main_scene()
else:
_show_notification("加载存档失败:" + data.name)
@ -289,26 +280,3 @@ func _load_manual_archives_data() -> void:
func _show_notification(message: String) -> void:
SceneManager.pop_notification(message)
func _enter_tree() -> void:
SceneManager.toggle_pause_counter(true, "savings")
func _exit_tree() -> void:
SceneManager.toggle_pause_counter(false, "savings")
func quit() -> void:
queue_free()
func _unhandled_input(event: InputEvent) -> void:
# savings 界面接受所有输入事件
get_viewport().set_input_as_handled()
if (
event.is_action_pressed("savings")
or event.is_action_pressed("cancel")
or event.is_action_pressed("escape")
):
quit()

View File

@ -1,85 +1,71 @@
[gd_scene load_steps=2 format=3 uid="uid://d4jeeteyq8kk3"]
[gd_scene load_steps=2 format=3 uid="uid://bo4f3sdubdp61"]
[ext_resource type="Script" uid="uid://cirf1nw72l315" path="res://manager/archive_manager/savings_panel.gd" id="1_oo2ip"]
[node name="SavingsLayer" type="CanvasLayer"]
[node name="TestArchivePanel" type="PanelContainer" parent="."]
process_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 59.0
offset_top = 21.0
offset_right = 395.0
offset_bottom = 262.0
grow_horizontal = 2
grow_vertical = 2
scale = Vector2(0.5, 0.5)
[node name="存档控制" type="PanelContainer"]
offset_right = 405.0
offset_bottom = 531.0
mouse_filter = 1
script = ExtResource("1_oo2ip")
metadata/_tab_index = 0
[node name="VBoxContainer" type="VBoxContainer" parent="TestArchivePanel"]
[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 2
[node name="HBoxContainer" type="HBoxContainer" parent="TestArchivePanel/VBoxContainer"]
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
layout_mode = 2
[node name="Title" type="Label" parent="TestArchivePanel/VBoxContainer/HBoxContainer"]
[node name="Title" type="Label" parent="VBoxContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 24
text = "存档测试管理器(测试专用)"
horizontal_alignment = 1
[node name="QuitDebugModeButton" type="Button" parent="TestArchivePanel/VBoxContainer/HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
text = "关闭 Debug 模式"
[node name="存档管理" type="VBoxContainer" parent="TestArchivePanel/VBoxContainer"]
[node name="存档管理" type="VBoxContainer" parent="VBoxContainer"]
layout_mode = 2
theme_override_constants/separation = 10
[node name="CurrentArchiveLabel" type="Label" parent="TestArchivePanel/VBoxContainer/存档管理"]
[node name="CurrentArchiveLabel" type="Label" parent="VBoxContainer/存档管理"]
unique_name_in_owner = true
layout_mode = 2
theme_override_colors/font_color = Color(0.7, 0.9, 0.7, 1)
text = "当前使用存档1号存档主存档"
[node name="HSeparator" type="HSeparator" parent="TestArchivePanel/VBoxContainer/存档管理"]
[node name="HSeparator" type="HSeparator" parent="VBoxContainer/存档管理"]
layout_mode = 2
[node name="SaveContainer" type="HBoxContainer" parent="TestArchivePanel/VBoxContainer/存档管理"]
[node name="SaveContainer" type="HBoxContainer" parent="VBoxContainer/存档管理"]
layout_mode = 2
theme_override_constants/separation = 10
[node name="NameInput" type="LineEdit" parent="TestArchivePanel/VBoxContainer/存档管理/SaveContainer"]
[node name="NameInput" type="LineEdit" parent="VBoxContainer/存档管理/SaveContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
placeholder_text = "输入存档名称"
[node name="SaveButton" type="Button" parent="TestArchivePanel/VBoxContainer/存档管理/SaveContainer"]
[node name="SaveButton" type="Button" parent="VBoxContainer/存档管理/SaveContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(120, 0)
layout_mode = 2
text = "保存当前进度"
[node name="RefreshButton" type="Button" parent="TestArchivePanel/VBoxContainer/存档管理/SaveContainer"]
[node name="RefreshButton" type="Button" parent="VBoxContainer/存档管理/SaveContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(60, 0)
layout_mode = 2
text = "刷新"
[node name="HSeparator2" type="HSeparator" parent="TestArchivePanel/VBoxContainer/存档管理"]
[node name="HSeparator2" type="HSeparator" parent="VBoxContainer/存档管理"]
layout_mode = 2
[node name="Label" type="Label" parent="TestArchivePanel/VBoxContainer/存档管理"]
[node name="Label" type="Label" parent="VBoxContainer/存档管理"]
layout_mode = 2
theme_override_colors/font_color = Color(0.8, 0.8, 0.8, 1)
text = "手动存档列表:"
[node name="ScrollContainer" type="ScrollContainer" parent="TestArchivePanel/VBoxContainer/存档管理"]
[node name="ScrollContainer" type="ScrollContainer" parent="VBoxContainer/存档管理"]
unique_name_in_owner = true
custom_minimum_size = Vector2(0, 380)
layout_mode = 2
@ -87,7 +73,7 @@ size_flags_vertical = 3
horizontal_scroll_mode = 0
vertical_scroll_mode = 2
[node name="ArchiveGrid" type="GridContainer" parent="TestArchivePanel/VBoxContainer/存档管理/ScrollContainer"]
[node name="ArchiveGrid" type="GridContainer" parent="VBoxContainer/存档管理/ScrollContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3

View File

@ -0,0 +1,526 @@
class_name SfxConfigPanel
extends Control
# signal config_changed(node_name: String, property: String, value)
# 面板相关
@onready var scroll_container: ScrollContainer = %ScrollContainer
@onready var vbox_container: VBoxContainer = %VBoxContainer
@onready var reset_button: Button = %ResetButton
@onready var import_button: Button = %ImportButton
@onready var export_button: Button = %ExportButton
# 音频预览播放器
@onready var preview_player: AudioStreamPlayer = %AudioStreamPlayer
# 文件对话框
@onready var file_dialog: FileDialog = %FileDialog
# 数据存储
var sfx_nodes: Array[Node] = []
var config_data: Dictionary = {}
var current_scene_name: String = ""
func _ready():
file_dialog.file_selected.connect(_on_file_selected)
reset_button.pressed.connect(_on_reset_pressed)
import_button.pressed.connect(_on_import_pressed)
export_button.pressed.connect(_on_export_pressed)
# 初始加载
refresh_sfx_list(SceneManager.get_ground())
# 1. 检测 current_scene 下 Sfx 节点
func refresh_sfx_list(ground: Ground2D, headless := false):
sfx_nodes.clear()
current_scene_name = GroundLoader.get_ground_scene_readable_name(ground.scene_name)
find_sfx_nodes(ground)
load_config()
if not headless:
refresh_ui()
var ignore_class_list = ["Portal2D", "Interactable2D", "Note2D", "Inspectable2D", "Pickable2D", "Npc2D", "Ambush2D"]
func find_sfx_nodes(node: Node):
var script = node.get_script()
if script:
if script.get_global_name() in ignore_class_list:
return
# if node is Sfx or node is VibeSfx:
if node is Sfx:
if node.has_method("play") and node.get("volume_db") != null and node.get("stream") != null:
sfx_nodes.append(node)
# 递归检查子节点
for child in node.get_children():
find_sfx_nodes(child)
func clear_ui():
for child in vbox_container.get_children():
child.queue_free()
# 2. 在面板生成对应条目,双向绑定
func create_ui_items():
for sfx_node in sfx_nodes:
create_sfx_item(sfx_node)
func refresh_ui():
clear_ui()
create_ui_items()
func _build_sfx_name(sfx: Sfx) -> String:
var parent_name = ""
var parent = sfx.get_parent()
while not parent_name and parent:
if parent and parent.get_script() and parent.get_script().get_global_name() in ignore_class_list:
parent_name = parent.name
else:
parent = parent.get_parent()
if parent_name:
return parent_name + " > " + sfx.name
else:
return sfx.name
func create_sfx_item(sfx_node: Node):
var item_container = VBoxContainer.new()
item_container.add_theme_constant_override("separation", 8)
vbox_container.add_child(item_container)
# 节点名称标签
var name_label = Label.new()
name_label.text = _build_sfx_name(sfx_node)
name_label.add_theme_font_size_override("font_size", 14)
item_container.add_child(name_label)
var controls_hbox = HBoxContainer.new()
controls_hbox.add_theme_constant_override("separation", 10)
item_container.add_child(controls_hbox)
# 音量滑块
var volume_vbox = VBoxContainer.new()
controls_hbox.add_child(volume_vbox)
var volume_title_hbox = HBoxContainer.new()
volume_vbox.add_child(volume_title_hbox)
var volume_label = Label.new()
volume_label.text = "音量 (dB)"
volume_title_hbox.add_child(volume_label)
# 重置音量按钮
var reset_volumn_button = Button.new()
reset_volumn_button.text = "重置音量"
reset_volumn_button.pressed.connect(reset_volumn.bind(sfx_node))
volume_title_hbox.add_child(reset_volumn_button)
var volume_slider_hbox = HBoxContainer.new()
volume_vbox.add_child(volume_slider_hbox)
var volume_slider = HSlider.new()
volume_slider.min_value = -60.0
volume_slider.max_value = 20.0
volume_slider.step = 0.1
volume_slider.value = sfx_node.volume_db
volume_slider.custom_minimum_size.x = 200
volume_slider_hbox.add_child(volume_slider)
var volume_value_label = Label.new()
volume_value_label.text = str(snapped(sfx_node.volume_db, 0.1))
volume_value_label.custom_minimum_size.x = 50
volume_slider_hbox.add_child(volume_value_label)
# 双向绑定音量
volume_slider.value_changed.connect(func(value):
sfx_node.volume_db = value
volume_value_label.text = str(snapped(value, 0.1))
save_node_config(sfx_node.get_path(), "volume_db", value)
)
# Stream 信息和控制
var stream_vbox = VBoxContainer.new()
controls_hbox.add_child(stream_vbox)
var stream_label = Label.new()
stream_label.text = "音频文件"
stream_vbox.add_child(stream_label)
var stream_hbox = HBoxContainer.new()
stream_vbox.add_child(stream_hbox)
var stream_name_label = Label.new()
stream_name_label.custom_minimum_size.x = 150
_set_stream_name_label(sfx_node, stream_name_label)
stream_hbox.add_child(stream_name_label)
# 预览播放按钮
var preview_button = Button.new()
preview_button.text = ""
preview_button.custom_minimum_size = Vector2(30, 30)
preview_button.pressed.connect(preview_audio.bind(sfx_node))
stream_hbox.add_child(preview_button)
# 恢复默认按钮
if sfx_node.stream_was_replaced():
var reset_btn = Button.new()
reset_btn.text = "恢复默认音频"
reset_btn.custom_minimum_size = Vector2(30, 30)
reset_btn.pressed.connect(reset_audio.bind(sfx_node))
stream_hbox.add_child(reset_btn)
# 3. 上传文件按钮
var upload_button = Button.new()
upload_button.text = "上传音频"
upload_button.pressed.connect(open_file_dialog.bind(sfx_node, stream_name_label))
stream_hbox.add_child(upload_button)
# 分割线
var separator = HSeparator.new()
item_container.add_child(separator)
# 存储节点引用用于后续操作
item_container.set_meta("sfx_node", sfx_node)
item_container.set_meta("stream_label", stream_name_label)
func _set_stream_name_label(sfx_node:Sfx, stream_name_label:Label) -> void:
if sfx_node.stream:
stream_name_label.text = sfx_node.stream.resource_path.get_file()
else:
stream_name_label.text = "无音频文件"
func reset_volumn(sfx_node: Sfx):
sfx_node.volume_db = sfx_node.default_db
save_config()
refresh_ui()
func preview_audio(sfx_node: Sfx):
if sfx_node.stream:
preview_player.stream = sfx_node.stream
preview_player.volume_db = sfx_node.volume_db
preview_player.play()
func reset_audio(sfx_node: Sfx):
sfx_node.reset_original_stream()
config_data.erase(sfx_node.get_path())
save_config()
refresh_ui()
var current_upload_node: Node
var current_stream_label: Label
func open_file_dialog(sfx_node: Node, stream_label: Label):
current_upload_node = sfx_node
current_stream_label = stream_label
file_dialog.popup_centered()
func _on_file_selected(path: String):
if not current_upload_node:
return
copy_and_load_audio_file(path, current_upload_node, current_stream_label)
# 3. 复制文件并加载
func copy_and_load_audio_file(source_path: String, sfx_node: Node, stream_label: Label):
var file_name = source_path.get_file()
var audio_dir = "user://audio/" + current_scene_name + "/"
var target_path = audio_dir + file_name
# 确保目录存在
DirAccess.open("user://").make_dir_recursive("audio/" + current_scene_name)
# 复制文件
var source_file = FileAccess.open(source_path, FileAccess.READ)
if not source_file:
push_error("无法读取源文件: " + source_path)
return
var target_file = FileAccess.open(target_path, FileAccess.WRITE)
if not target_file:
push_error("无法创建目标文件: " + target_path)
source_file.close()
return
target_file.store_buffer(source_file.get_buffer(source_file.get_length()))
source_file.close()
target_file.close()
# 加载新的音频流
var new_stream = AudioLoader.new().loadfile(target_path)
if new_stream:
sfx_node.replace_stream(new_stream)
stream_label.text = file_name
save_node_config(sfx_node.get_path(), "stream", target_path)
print("音频文件已更新: ", sfx_node.name, " -> ", file_name)
else:
push_error("无法加载音频文件: " + target_path)
refresh_ui()
# 4. 配置保存与加载
func save_node_config(node_path: String, property: String, value):
if not config_data.has(node_path):
config_data[node_path] = {}
config_data[node_path][property] = value
save_config()
func save_config():
var config_dir = "user://audio/" + current_scene_name + "/"
DirAccess.open("user://").make_dir_recursive("audio/" + current_scene_name)
var config_path = config_dir + "audio_config.dat"
var file = FileAccess.open(config_path, FileAccess.WRITE)
if file:
file.store_string(var_to_str(config_data))
file.close()
func load_config():
var config_path = "user://audio/" + current_scene_name + "/audio_config.dat"
var file = FileAccess.open(config_path, FileAccess.READ)
if file:
var config_str = file.get_as_text()
file.close()
config_data = str_to_var(config_str)
if not config_data:
config_data = {}
apply_config()
else:
config_data = {}
func apply_config():
for sfx_node in sfx_nodes:
var sfx_path = sfx_node.get_path()
if config_data.has(sfx_path):
var node_config = config_data[sfx_path]
if node_config.has("volume_db"):
sfx_node.volume_db = node_config["volume_db"]
if node_config.has("stream"):
var stream_path = node_config["stream"]
if FileAccess.file_exists(stream_path):
var new_stream = AudioLoader.new().loadfile(stream_path)
# var new_stream = load(stream_path)
if new_stream:
sfx_node.replace_stream(new_stream)
func _on_reset_pressed() -> void:
for sfx_node in sfx_nodes:
sfx_node.reset_original_stream()
var config_file_path = "user://audio/" + current_scene_name + "/" + "/audio_config.dat"
if FileAccess.file_exists(config_file_path):
DirAccess.remove_absolute(config_file_path)
SceneManager.enter_main_scene()
# 5. Import/Export 功能
func _on_import_pressed():
# 打开文件对话框选择导入文件夹或配置文件
var import_dialog = FileDialog.new()
import_dialog.size = Vector2(1400, 800)
import_dialog.content_scale_mode = Window.CONTENT_SCALE_MODE_CANVAS_ITEMS
import_dialog.content_scale_factor = 3
import_dialog.file_mode = FileDialog.FILE_MODE_OPEN_DIR
import_dialog.access = FileDialog.ACCESS_FILESYSTEM
import_dialog.dir_selected.connect(_on_import_folder_selected)
add_child(import_dialog)
import_dialog.popup_centered()
func _on_import_folder_selected(folder_path: String):
var config_file_path = folder_path + "/audio_config.dat"
if not FileAccess.file_exists(config_file_path):
push_error("所选文件夹中没有找到 audio_config.dat 配置文件")
return
# 确保目标目录存在
var target_dir = "user://audio/" + current_scene_name + "/"
DirAccess.open("user://").make_dir_recursive("audio/" + current_scene_name)
# 复制配置文件
copy_file(config_file_path, target_dir + "audio_config.dat")
# 复制所有音频文件
var dir = DirAccess.open(folder_path)
if dir:
dir.list_dir_begin()
var file_name = dir.get_next()
while file_name != "":
if not dir.current_is_dir():
var extension = file_name.get_extension().to_lower()
if extension in ["wav", "ogg", "mp3"]:
var source_path = folder_path + "/" + file_name
var target_path = target_dir + file_name
copy_file(source_path, target_path)
file_name = dir.get_next()
dir.list_dir_end()
# 重新加载配置
refresh_sfx_list(SceneManager.get_ground())
print("配置和音频文件已导入")
func copy_file(source_path: String, target_path: String) -> bool:
var source_file = FileAccess.open(source_path, FileAccess.READ)
if not source_file:
push_error("无法读取文件: " + source_path)
return false
var target_file = FileAccess.open(target_path, FileAccess.WRITE)
if not target_file:
push_error("无法创建文件: " + target_path)
source_file.close()
return false
target_file.store_buffer(source_file.get_buffer(source_file.get_length()))
source_file.close()
target_file.close()
return true
func _on_export_pressed():
var desktop_path = OS.get_system_dir(OS.SYSTEM_DIR_DESKTOP)
var export_folder = desktop_path + "/" + current_scene_name + "_audio_export"
var config_path = "user://audio/" + current_scene_name + "/audio_config.dat"
# 创建导出文件夹
var dir = DirAccess.open(desktop_path)
if not dir:
push_error("无法访问桌面目录")
return
# 如果文件夹已存在,先删除
if dir.dir_exists(export_folder):
remove_directory_recursive(export_folder)
dir.make_dir(current_scene_name + "_audio_export")
var exported_files = []
var failed_files = []
# 1. 导出配置文件
if FileAccess.file_exists(config_path):
var source_file = FileAccess.open(config_path, FileAccess.READ)
var target_file = FileAccess.open(export_folder + "/audio_config.dat", FileAccess.WRITE)
if source_file and target_file:
target_file.store_buffer(source_file.get_buffer(source_file.get_length()))
source_file.close()
target_file.close()
exported_files.append("audio_config.dat")
else:
failed_files.append("audio_config.dat")
push_error("配置文件导出失败")
else:
push_error("没有找到配置文件")
return
# 2. 导出所有关联的音频文件
var audio_dir = "user://audio/" + current_scene_name + "/"
# 从配置数据中收集所有音频文件路径
var audio_files_to_export = []
# 收集配置文件中引用的音频文件
for node_name in config_data.keys():
var node_config = config_data[node_name]
if node_config.has("stream"):
var stream_path = node_config["stream"]
if stream_path.begins_with("user://audio/" + current_scene_name + "/"):
audio_files_to_export.append(stream_path)
# 收集当前目录下的所有音频文件
var audio_dir_access = DirAccess.open(audio_dir)
if audio_dir_access:
audio_dir_access.list_dir_begin()
var file_name = audio_dir_access.get_next()
while file_name != "":
if not audio_dir_access.current_is_dir():
var full_path = audio_dir + file_name
var extension = file_name.get_extension().to_lower()
# 检查是否是音频文件
if extension in ["wav", "ogg", "mp3"]:
if not full_path in audio_files_to_export:
audio_files_to_export.append(full_path)
file_name = audio_dir_access.get_next()
audio_dir_access.list_dir_end()
# 导出音频文件
for audio_path in audio_files_to_export:
if FileAccess.file_exists(audio_path):
var file_name = audio_path.get_file()
var source_file = FileAccess.open(audio_path, FileAccess.READ)
var target_file = FileAccess.open(export_folder + "/" + file_name, FileAccess.WRITE)
if source_file and target_file:
target_file.store_buffer(source_file.get_buffer(source_file.get_length()))
source_file.close()
target_file.close()
exported_files.append(file_name)
else:
failed_files.append(file_name)
if source_file:
source_file.close()
if target_file:
target_file.close()
else:
failed_files.append(audio_path.get_file() + " (文件不存在)")
# 3. 创建导出说明文件
create_export_readme(export_folder, exported_files, failed_files)
# 显示导出结果
var message = "导出完成!\n导出位置: " + export_folder + "\n"
message += "成功导出 " + str(exported_files.size()) + " 个文件"
if failed_files.size() > 0:
message += "\n失败 " + str(failed_files.size()) + " 个文件: " + str(failed_files)
print(message)
# 可选:打开导出文件夹
OS.shell_open(export_folder)
func create_export_readme(export_folder: String, exported_files: Array, failed_files: Array):
var readme_path = export_folder + "/README.txt"
var readme_file = FileAccess.open(readme_path, FileAccess.WRITE)
if readme_file:
var content = "音效配置导出说明\n"
content += "===================\n\n"
content += "场景名称: " + current_scene_name + "\n"
content += "导出时间: " + Time.get_datetime_string_from_system() + "\n\n"
content += "导出文件清单:\n"
content += "-----------------\n"
for file_name in exported_files:
content += "" + file_name + "\n"
if failed_files.size() > 0:
content += "\n失败文件:\n"
content += "-----------------\n"
for file_name in failed_files:
content += "" + file_name + "\n"
content += "\n使用说明:\n"
content += "-----------------\n"
content += "1. audio_config.dat 是配置文件,包含音量和文件关联信息\n"
content += "2. 其他 .wav/.ogg/.mp3 文件是对应的音频资源\n"
content += "3. 导入时请将所有文件放在同一目录下\n"
readme_file.store_string(content)
readme_file.close()
func remove_directory_recursive(path: String):
var dir = DirAccess.open(path)
if dir:
dir.list_dir_begin()
var file_name = dir.get_next()
while file_name != "":
var full_path = path + "/" + file_name
if dir.current_is_dir():
remove_directory_recursive(full_path)
else:
dir.remove(file_name)
file_name = dir.get_next()
dir.list_dir_end()
dir.remove(path)

View File

@ -0,0 +1 @@
uid://dtwvx0vs0uoun

View File

@ -0,0 +1,68 @@
[gd_scene load_steps=2 format=3 uid="uid://b6ogrp5ec5nr3"]
[ext_resource type="Script" uid="uid://dtwvx0vs0uoun" path="res://manager/archive_manager/sfx_config_panel.gd" id="1_386ty"]
[node name="SfxConfigPanel" type="PanelContainer"]
custom_minimum_size = Vector2(500, 0)
offset_right = 508.0
offset_bottom = 335.0
mouse_filter = 1
script = ExtResource("1_386ty")
[node name="MainVBox" type="VBoxContainer" parent="."]
layout_mode = 2
[node name="HeaderHBox" type="HBoxContainer" parent="MainVBox"]
layout_mode = 2
[node name="Label" type="Label" parent="MainVBox/HeaderHBox"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 18
text = "音效配置面板"
horizontal_alignment = 1
[node name="ResetButton" type="Button" parent="MainVBox/HeaderHBox"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 8
text = "重置所有配置"
[node name="ImportButton" type="Button" parent="MainVBox/HeaderHBox"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 8
text = "导入配置"
[node name="ExportButton" type="Button" parent="MainVBox/HeaderHBox"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 8
text = "导出配置"
[node name="ScrollContainer" type="ScrollContainer" parent="MainVBox"]
unique_name_in_owner = true
custom_minimum_size = Vector2(500, 400)
layout_mode = 2
size_flags_vertical = 0
horizontal_scroll_mode = 0
vertical_scroll_mode = 2
[node name="VBoxContainer" type="VBoxContainer" parent="MainVBox/ScrollContainer"]
unique_name_in_owner = true
layout_mode = 2
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
unique_name_in_owner = true
[node name="FileDialog" type="FileDialog" parent="."]
unique_name_in_owner = true
title = "Open a File"
initial_position = 1
size = Vector2i(1500, 1000)
content_scale_mode = 1
content_scale_factor = 3.0
ok_button_text = "Open"
file_mode = 0
access = 2
filters = PackedStringArray("*.wav", "*.ogg", "*.mp3")

View File

@ -1,4 +1,4 @@
[gd_resource type="Resource" script_class="VibeGroupCollection" load_steps=22 format=3 uid="uid://bfhwn1v0c2io7"]
[gd_resource type="Resource" script_class="VibeGroupCollection" load_steps=18 format=3 uid="uid://bfhwn1v0c2io7"]
[ext_resource type="Script" uid="uid://cy1ngx5no67v" path="res://manager/audio_manager/vibe_group.gd" id="1_0bbao"]
[ext_resource type="Script" uid="uid://bo8gxwe8hfs01" path="res://manager/audio_manager/vibe_group_collection.gd" id="2_h4hph"]
@ -10,8 +10,6 @@
[ext_resource type="AudioStream" uid="uid://6oc0cgc3mbqb" path="res://asset/audio/sfx/环境音/白噪音/白噪声楼道2.ogg" id="7_lca37"]
[ext_resource type="AudioStream" uid="uid://c6ehv3lgway26" path="res://asset/audio/sfx/环境音/白噪音/白噪声诡异室外.ogg" id="8_646q0"]
[ext_resource type="AudioStream" uid="uid://s7uigovfp5g3" path="res://asset/audio/sfx/环境音/第一章/火灾演出.ogg" id="9_wuwx1"]
[ext_resource type="AudioStream" uid="uid://d0ef0felylt8d" path="res://asset/audio/sfx/环境音/第一章/氛围不受欢迎的存在.ogg" id="10_uwtc1"]
[ext_resource type="AudioStream" uid="uid://bal423qlb3jp2" path="res://asset/audio/sfx/环境音/点缀音/sfx_夜晚虫鸣.ogg" id="11_scrw7"]
[sub_resource type="Resource" id="Resource_bjndi"]
script = ExtResource("1_0bbao")
@ -76,25 +74,7 @@ base_sound_db = 0.0
embellishments = Array[ExtResource("3_scrw7")]([])
metadata/_custom_type_script = "uid://cy1ngx5no67v"
[sub_resource type="Resource" id="Resource_f75a1"]
script = ExtResource("1_0bbao")
group_name = &"氛围_不受欢迎的存在"
group_db = 0.0
base_sound = ExtResource("10_uwtc1")
base_sound_db = -12.0
embellishments = Array[ExtResource("3_scrw7")]([])
metadata/_custom_type_script = "uid://cy1ngx5no67v"
[sub_resource type="Resource" id="Resource_scrw7"]
script = ExtResource("1_0bbao")
group_name = &"夜晚虫鸣"
group_db = 0.0
base_sound = ExtResource("11_scrw7")
base_sound_db = -10.0
embellishments = Array[ExtResource("3_scrw7")]([])
metadata/_custom_type_script = "uid://cy1ngx5no67v"
[resource]
script = ExtResource("2_h4hph")
groups = Array[ExtResource("1_0bbao")]([SubResource("Resource_bjndi"), SubResource("Resource_chrc1"), SubResource("Resource_7c7wx"), SubResource("Resource_an5bn"), SubResource("Resource_egnaw"), SubResource("Resource_e3r3f"), SubResource("Resource_j0xlt"), SubResource("Resource_f75a1"), SubResource("Resource_scrw7")])
groups = Array[ExtResource("1_0bbao")]([SubResource("Resource_bjndi"), SubResource("Resource_chrc1"), SubResource("Resource_7c7wx"), SubResource("Resource_an5bn"), SubResource("Resource_egnaw"), SubResource("Resource_e3r3f"), SubResource("Resource_j0xlt")])
metadata/_custom_type_script = "uid://bo8gxwe8hfs01"

View File

@ -7,6 +7,8 @@ enum VIBE {
TOUCHING,
}
signal pause_counter_updated
# 从 ground loader 控制该信号
# 建议使用 CONNECT_ONE_SHOT 来连接 ground ready 与 start 等信号
@warning_ignore("unused_signal")
@ -362,23 +364,23 @@ var main_scene = preload("uid://dygvcmykn02n8")
func enter_main_scene() -> void:
# 防止撕裂帧
await get_tree().process_frame
get_tree().change_scene_to_packed.call_deferred(main_scene)
# get_tree().change_scene_to_file.call_deferred("uid://dygvcmykn02n8")
if pause_counter_arr.size() > 0:
printerr("enter_main_scene: pause_counter_arr is not empty, resetting pause counter")
pause_counter_arr.clear()
get_tree().paused = false
# 防止撕裂帧
await get_tree().process_frame
get_tree().change_scene_to_packed.call_deferred(main_scene)
#### Savings
#### debugging
var savings_scene = preload("uid://d4jeeteyq8kk3")
var debugging_scene = preload("uid://c2j3mxd8dbgjg")
func show_savings() -> void:
get_tree().current_scene.add_child(savings_scene.instantiate())
func show_debugging() -> void:
get_tree().current_scene.add_child(debugging_scene.instantiate())
#### UX: settings; panel: note, bag, memory ####
@ -419,7 +421,7 @@ func show_settings() -> void:
#### 游戏场景树暂停计数器设置、memory、bag 等菜单都会导致 pause
## 目前有(6类): settings, panel, bag, note, memory, savings
## 目前有(6类): settings, panel, bag, note, memory, debugging
var pause_counter_arr: Array[String] = []
var pause_counter_mutex := Mutex.new()
@ -434,6 +436,8 @@ func toggle_pause_counter(plus := true, from := "") -> void:
print("SceneTree pause_counter_arr: ", pause_counter_arr)
get_tree().paused = len(pause_counter_arr) > 0
pause_counter_mutex.unlock()
# 增删结束后再发射信号
pause_counter_updated.emit()
func quit_game() -> void:

View File

@ -212,7 +212,7 @@ panel={
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":80,"key_label":0,"unicode":112,"location":0,"echo":false,"script":null)
]
}
savings={
debugging={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":96,"key_label":0,"unicode":96,"location":0,"echo":false,"script":null)
]

View File

@ -1,8 +1,11 @@
@tool
class_name Sfx extends AudioStreamPlayer
const META_ORIGINAL_STREAM = &"original_stream"
@export_enum("交互与效果音", "BGM", "场景背景音") var mode := "交互与效果音":
set(value):
_set_up_process_mode_by_mode()
mode = value
notify_property_list_changed()
@ -13,19 +16,40 @@ var default_db := 0.0
# 只有 场景背景音 生效
var scene_loop := true
var scene_autostart := true
var scene_sense_player_mov := false
func _ready() -> void:
bus = &"game_sfx"
default_db = volume_db
process_mode = Node.PROCESS_MODE_INHERIT
if Engine.is_editor_hint():
return
# 记录原 stream
if stream:
set_meta(META_ORIGINAL_STREAM, stream)
else:
set_meta(META_ORIGINAL_STREAM, null)
_set_up_process_mode_by_mode()
finished.connect(_on_finished)
# ground 退出时process mode 切换为 alwaysease out
SceneManager.ground_transition_pre_paused.connect(_on_ground_transition_pre_paused)
SceneManager.pause_counter_updated.connect(_on_pause_counter_updated)
var playing_on_debugging_paused = false
func _on_pause_counter_updated() -> void:
_set_up_process_mode_by_mode()
func _set_up_process_mode_by_mode():
# 如果是 debug panel则 pause
if mode == "场景背景音" and not SceneManager.pause_counter_arr.has("debugging"):
process_mode = Node.PROCESS_MODE_ALWAYS
else:
if SceneManager.pause_counter_arr.has("debugging"):
playing_on_debugging_paused = playing
process_mode = Node.PROCESS_MODE_PAUSABLE
func _on_ground_transition_pre_paused():
@ -40,6 +64,24 @@ func _on_finished() -> void:
play()
func reset_original_stream(ignore_null := true):
var original_stream = get_meta(META_ORIGINAL_STREAM)
if original_stream != null:
replace_stream(original_stream)
elif not ignore_null:
stream = null
func replace_stream(new_stream: AudioStream) -> void:
stream = new_stream
if (playing_on_debugging_paused or autoplay) and is_node_ready():
play()
func stream_was_replaced() -> bool:
return get_meta(META_ORIGINAL_STREAM) != stream
func resart(ease_duration := 1.0):
easing_kill(ease_duration).tween_callback(play)
@ -75,18 +117,17 @@ func _get_property_list() -> Array[Dictionary]:
"type": TYPE_NIL,
"usage": PROPERTY_USAGE_GROUP,
},
{"name": "自动开始", "type": TYPE_BOOL},
{"name": "循环播放", "type": TYPE_BOOL},
{"name": "感应玩家操作", "type": TYPE_BOOL}
]
func _property_can_revert(property: StringName) -> bool:
return property == "自动开始" or property == "循环播放" or property == "感应玩家操作"
return property == "循环播放" or property == "感应玩家操作"
func _property_get_revert(property: StringName) -> Variant:
if property == "自动开始" or property == "循环播放":
if property == "循环播放":
return true
elif property == "感应玩家操作":
return false
@ -96,11 +137,6 @@ func _property_get_revert(property: StringName) -> Variant:
func _set(property: StringName, value: Variant) -> bool:
if mode != "场景背景音":
return false
if property == "自动开始":
if value != null:
autoplay = value
scene_autostart = value
return true
elif property == "循环播放":
scene_loop = value
return true
@ -113,8 +149,6 @@ func _set(property: StringName, value: Variant) -> bool:
func _get(property: StringName) -> Variant:
if mode != "场景背景音":
return null
if property == "自动开始":
return scene_autostart
elif property == "循环播放":
return scene_loop
elif property == "感应玩家操作":

View File

@ -1,6 +1,6 @@
[gd_scene load_steps=8 format=3 uid="uid://dnbutraty2285"]
[ext_resource type="Script" uid="uid://5y8v4ir43q3j" path="res://scene/entity/partical/particals_ash_vertical.gd" id="1_1ybs0"]
[ext_resource type="Script" path="res://scene/entity/partical/particals_ash_vertical.gd" id="1_1ybs0"]
[ext_resource type="Texture2D" uid="uid://6vh5m2p3v0t3" path="res://asset/art/scene/c01/s07_书店外/e_纸钱.png" id="1_hsa64"]
[sub_resource type="Gradient" id="Gradient_rwi0m"]

View File

@ -237,7 +237,15 @@ func _add_ground() -> void:
# 在 add child 之前,调整 ground 内部元素属性,在 on ground ready 前设置完成
if not Engine.is_editor_hint():
_setup_player_position()
add_child(ground)
# debug 模式在 ground add 之后加载音频
# 防止影响 Sfx 的 META 设置 ORIGINAL_STREAM
if GlobalConfig.DEBUG:
# headless 模式
SfxConfigPanel.new().refresh_sfx_list(ground, true)
print(
"GroundLoader add_ground finished:",
ground.scene_name,

View File

@ -169,6 +169,7 @@ script = ExtResource("4_qq2uh")
loop = true
[node name="Sfx猫鼠游戏" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="2"]
process_mode = 1
stream = SubResource("AudioStreamInteractive_af0pm")
volume_db = -17.0
bus = &"game_sfx"

View File

@ -69,13 +69,13 @@ player_y = 55
script = ExtResource("2_dhaq4")
[node name="环境音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"]
process_mode = 1
stream = ExtResource("3_na2nu")
volume_db = -4.0
autoplay = true
bus = &"game_sfx"
script = ExtResource("4_c7jb6")
mode = "场景背景音"
"自动开始" = true
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"

View File

@ -42,24 +42,24 @@ libraries = {
script = ExtResource("2_0lque")
[node name="环境音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"]
process_mode = 1
stream = ExtResource("3_0x288")
volume_db = -8.0
autoplay = true
bus = &"game_sfx"
script = ExtResource("4_p6k3c")
mode = "场景背景音"
"自动开始" = true
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="诡异环境音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"]
process_mode = 1
stream = ExtResource("5_eerhd")
volume_db = -7.0
bus = &"game_sfx"
script = ExtResource("4_p6k3c")
mode = "场景背景音"
"自动开始" = false
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"

View File

@ -156,12 +156,12 @@ bus = &"game_sfx"
script = ExtResource("3_vx53v")
[node name="黄包车背景音效" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"]
process_mode = 1
stream = SubResource("AudioStreamSynchronized_s11la")
autoplay = true
bus = &"game_sfx"
script = ExtResource("3_vx53v")
mode = "场景背景音"
"自动开始" = true
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"

View File

@ -1,10 +1,12 @@
[gd_scene load_steps=12 format=3 uid="uid://bbs7yy5aofw1v"]
[gd_scene load_steps=14 format=3 uid="uid://bbs7yy5aofw1v"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_c4tdi"]
[ext_resource type="Script" uid="uid://jkselt4d5q4r" path="res://scene/ground/scene/c02/s01_公寓门口.gd" id="2_jfumy"]
[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_bhi7l"]
[ext_resource type="AudioStream" uid="uid://dvc2emnfcmabx" path="res://asset/audio/sfx/环境音/白噪音/白噪声楼道1.ogg" id="4_ev3cr"]
[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="5_ev3cr"]
[ext_resource type="Texture2D" uid="uid://d05pqud4yoxx3" path="res://asset/art/scene/c02/s01_公寓门口/bg_公寓门口.png" id="5_j2ctx"]
[ext_resource type="PackedScene" uid="uid://jr1yd46wm5je" path="res://scene/entity/note.tscn" id="6_bhi7l"]
[ext_resource type="AudioStream" uid="uid://bal423qlb3jp2" path="res://asset/audio/sfx/环境音/点缀音/sfx_夜晚虫鸣.ogg" id="6_ev3cr"]
[ext_resource type="PackedScene" uid="uid://ci5anaxsa1apl" path="res://scene/entity/inspectable.tscn" id="7_vc2dw"]
[ext_resource type="Texture2D" uid="uid://qls0yc054048" path="res://asset/art/scene/c02/小蝉寻人启事/e_寻人启事残破.png" id="8_j2ctx"]
[ext_resource type="Texture2D" uid="uid://cuyfloebe2mht" path="res://asset/art/scene/c02/小蝉寻人启事/ux_寻人启事残破.png" id="9_bhi7l"]
@ -21,15 +23,29 @@ player_y = 60
[node name="AnimationPlayer" parent="Ground" index="0"]
script = ExtResource("2_jfumy")
[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"]
script = ExtResource("3_bhi7l")
autoplay_group = &"c02_楼道1"
metadata/_custom_type_script = "uid://cpejxlfni6n52"
[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"]
process_mode = 1
stream = ExtResource("4_ev3cr")
volume_db = -5.0
autoplay = true
bus = &"game_sfx"
script = ExtResource("5_ev3cr")
mode = "场景背景音"
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="VibeSfx虫鸣" type="Node" parent="Ground/AnimationPlayer" index="1"]
script = ExtResource("3_bhi7l")
autoplay_group = &"夜晚虫鸣"
metadata/_custom_type_script = "uid://cpejxlfni6n52"
[node name="Sfx背景虫鸣" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"]
process_mode = 1
stream = ExtResource("6_ev3cr")
volume_db = -10.0
autoplay = true
bus = &"game_sfx"
script = ExtResource("5_ev3cr")
mode = "场景背景音"
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="BGSprite2D" parent="Ground" index="2"]
texture = ExtResource("5_j2ctx")

View File

@ -7,7 +7,7 @@
[ext_resource type="Texture2D" uid="uid://5428j51dwarc" path="res://asset/art/scene/c02/s02_大门过道/bg_过道背景.png" id="3_gjwum"]
[ext_resource type="AudioStream" uid="uid://o7fj0r0fbm1h" path="res://asset/audio/sfx/交互/第一章/sfx_冷飕飕.ogg" id="4_36l5t"]
[ext_resource type="SpriteFrames" uid="uid://b7fhheih1hbvf" path="res://config/animation/entity_sprite_frames.tres" id="4_wbif8"]
[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="5_36l5t"]
[ext_resource type="AudioStream" uid="uid://bjwguxsoehrne" path="res://asset/audio/sfx/环境音/第一章/楼道场景2.ogg" id="5_2lo60"]
[ext_resource type="Texture2D" uid="uid://r0n7qy4kr3w2" path="res://asset/art/ui/action_mark/UI场景切换.png" id="5_m1xet"]
[ext_resource type="Texture2D" uid="uid://b8pcnqvdddo5g" path="res://asset/art/prop/c02/海报特写/除鼠二杰.png" id="7_jg8g0"]
[ext_resource type="Texture2D" uid="uid://cvgw2mxrlr6io" path="res://asset/art/scene/c02/旧版/s02_走道/ux_进门鼠疫海报yz.png" id="7_wdwbi"]
@ -59,14 +59,22 @@ libraries = {
script = ExtResource("2_5p8ev")
[node name="冷飕飕Sfx" parent="Ground/AnimationPlayer" index="0" instance=ExtResource("3_fvldj")]
process_mode = 1
stream = ExtResource("4_36l5t")
volume_db = -10.0
mode = "交互与效果音"
[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="1"]
script = ExtResource("5_36l5t")
autoplay_group = &"c02_楼道2"
metadata/_custom_type_script = "uid://cpejxlfni6n52"
[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"]
process_mode = 1
stream = ExtResource("5_2lo60")
volume_db = -5.0
autoplay = true
bus = &"game_sfx"
script = ExtResource("14_jg8g0")
mode = "场景背景音"
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="BGSprite2D" parent="Ground" index="2"]
self_modulate = Color(0.831373, 0.886275, 0.956863, 1)

View File

@ -56,7 +56,8 @@ func _on_ground_ready() -> void:
new_bg.modulate.a = 1.0
# 火灾开始后,无需 enable
counter.get_node("点燃").modulate.a = 1.0
$VibeSfx氛围.switch_to("c02_火灾")
$"Sfx背景音".easing_kill()
$"Sfx背景火灾".play()
$"../DirectionalLight2D".energy = 0
eavesdrop_window = $"../DeployLayer/李氏赖子房间人影"
madman_npc = $"../DeployLayer/Npc井边疯子"
@ -221,7 +222,8 @@ func _setup_bully_or_burning(reenter_scene := false):
else:
bully_layer.visible = false
burning_layer.visible = true
$VibeSfx氛围.switch_to("c02_火灾")
$"Sfx背景音".easing_kill()
$"Sfx背景火灾".play()
$"../DeployLayer/霸凌/f1/Sfx2D霸凌童谣".easing_kill()
bully_layer.get_node("Ambush点火游戏阻挡右移").enabled = false
bully_layer.get_node("wall/CollisionShape2D").disabled = true

View File

@ -1,16 +1,17 @@
[gd_scene load_steps=84 format=3 uid="uid://djc2uaefhmu7"]
[gd_scene load_steps=85 format=3 uid="uid://djc2uaefhmu7"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_0dylx"]
[ext_resource type="Script" uid="uid://dsp5plrdkrsd7" path="res://scene/ground/scene/c02/s03_院子.gd" id="2_dt5aj"]
[ext_resource type="AudioStream" uid="uid://d0ef0felylt8d" path="res://asset/audio/sfx/环境音/第一章/氛围不受欢迎的存在.ogg" id="3_2b6vx"]
[ext_resource type="Texture2D" uid="uid://b3odt4ojsvu5n" path="res://asset/art/scene/c02/s03_公寓一楼院子/bg_一楼.png" id="3_sqv8l"]
[ext_resource type="SpriteFrames" uid="uid://3nas025c2c5u" path="res://asset/art/gif/c02_杂项/c02_杂项_frames.tres" id="4_gd6xp"]
[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_ygnci"]
[ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="5_00b7a"]
[ext_resource type="AudioStream" uid="uid://s7uigovfp5g3" path="res://asset/audio/sfx/环境音/第一章/火灾演出.ogg" id="5_fxne6"]
[ext_resource type="AudioStream" uid="uid://bk5cdc06s8x10" path="res://asset/audio/sfx/bgm/第一章/打开铁门后不循环背景音.ogg" id="5_qt2qg"]
[ext_resource type="Texture2D" uid="uid://f8yjp5ggr8qw" path="res://asset/art/scene/c02/s03_公寓一楼院子/算卦布.png" id="6_1tart"]
[ext_resource type="Texture2D" uid="uid://0uh6qaalhqju" path="res://asset/art/scene/c02/s11_一楼火灾/总背景/bg_院子1楼火灾.png" id="6_d7h4s"]
[ext_resource type="AudioStream" uid="uid://bhaws2ungqaf5" path="res://asset/audio/sfx/交互/角色/sfx_哼歌.ogg" id="6_jhod7"]
[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="6_lq23y"]
[ext_resource type="PackedScene" uid="uid://jr1yd46wm5je" path="res://scene/entity/note.tscn" id="6_t48d1"]
[ext_resource type="AudioStream" uid="uid://civuwccn6v6yk" path="res://asset/audio/sfx/交互/第一章/sfx_闷雷声.ogg" id="6_vddfx"]
[ext_resource type="Texture2D" uid="uid://bxqetnlx0bpv4" path="res://asset/art/scene/c02/门_贴图/1012保卫科.png" id="6_ygnci"]
@ -287,38 +288,55 @@ libraries = {
}
script = ExtResource("2_dt5aj")
[node name="Sfx闷雷" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"]
[node name="Sfx背景火灾" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"]
process_mode = 1
stream = ExtResource("5_fxne6")
bus = &"game_sfx"
script = ExtResource("4_ygnci")
mode = "场景背景音"
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"]
process_mode = 1
stream = ExtResource("3_2b6vx")
volume_db = -12.0
autoplay = true
bus = &"game_sfx"
script = ExtResource("4_ygnci")
mode = "场景背景音"
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="Sfx闷雷" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="2"]
stream = ExtResource("6_vddfx")
bus = &"game_sfx"
script = ExtResource("4_ygnci")
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="Sfx打开铁门后" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"]
[node name="Sfx打开铁门后" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="3"]
stream = ExtResource("5_qt2qg")
volume_db = -20.0
bus = &"game_sfx"
script = ExtResource("4_ygnci")
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="Sfx小鞋落地" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="2"]
[node name="Sfx小鞋落地" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="4"]
stream = ExtResource("7_df1yo")
bus = &"game_sfx"
script = ExtResource("4_ygnci")
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="Sfx小蝉哼歌" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="3"]
[node name="Sfx小蝉哼歌" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="5"]
stream = ExtResource("6_jhod7")
volume_db = 16.0
bus = &"game_sfx"
script = ExtResource("4_ygnci")
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="VibeSfx氛围" type="Node" parent="Ground/AnimationPlayer" index="4"]
script = ExtResource("6_lq23y")
autoplay_group = &"氛围_不受欢迎的存在"
metadata/_custom_type_script = "uid://cpejxlfni6n52"
[node name="Sfx牵手演出氛围音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="5"]
[node name="Sfx牵手演出氛围音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="6"]
stream = ExtResource("9_2b6vx")
bus = &"game_sfx"
script = ExtResource("4_ygnci")

View File

@ -1,11 +1,12 @@
[gd_scene load_steps=23 format=3 uid="uid://bivc5cdap370p"]
[gd_scene load_steps=24 format=3 uid="uid://bivc5cdap370p"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_2jej0"]
[ext_resource type="Script" uid="uid://dmhh4g47bdxxy" path="res://scene/ground/scene/c02/s04_保卫科.gd" id="2_jyere"]
[ext_resource type="Texture2D" uid="uid://7jvg2flkapj3" path="res://asset/art/scene/c02/s04_保卫科/bg_保卫科.png" id="3_66gue"]
[ext_resource type="AudioStream" uid="uid://b2mudqvq1dmng" path="res://asset/audio/sfx/环境音/白噪音/白噪声房间里1.ogg" id="3_g8amr"]
[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_cq2m4"]
[ext_resource type="SpriteFrames" uid="uid://c2sjavnptjn" path="res://asset/art/gif/c02_保卫科/c02_保卫科_frames.tres" id="4_svuj3"]
[ext_resource type="Texture2D" uid="uid://bnyf8m63ltgh0" path="res://asset/art/scene/c02/s04_保卫科/l_香.png" id="5_cy26p"]
[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="5_g8amr"]
[ext_resource type="PackedScene" uid="uid://dqkxiqbq83cmq" path="res://scene/entity/closeup.tscn" id="6_66gue"]
[ext_resource type="PackedScene" uid="uid://b8i6tqwdvvddy" path="res://scene/ground/script/c02/花名册.tscn" id="6_fvlg0"]
[ext_resource type="Texture2D" uid="uid://cs14llkvr3fg8" path="res://asset/art/scene/c02/s04_保卫科/e_弹珠墙面涂鸦提示.png" id="6_gk1h4"]
@ -33,10 +34,17 @@ player_y = 60
[node name="AnimationPlayer" parent="Ground" index="0"]
script = ExtResource("2_jyere")
[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"]
script = ExtResource("5_g8amr")
autoplay_group = &"c02_房间里1"
metadata/_custom_type_script = "uid://cpejxlfni6n52"
[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"]
process_mode = 1
stream = ExtResource("3_g8amr")
volume_db = -5.0
autoplay = true
bus = &"game_sfx"
script = ExtResource("4_cq2m4")
mode = "场景背景音"
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="BGSprite2D" parent="Ground" index="2"]
light_mask = 5

View File

@ -2,7 +2,7 @@
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_6w6et"]
[ext_resource type="Script" uid="uid://dydpmjpcvt3v1" path="res://scene/ground/scene/c02/s05_一楼内侧楼道.gd" id="2_70lf6"]
[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_laquj"]
[ext_resource type="AudioStream" uid="uid://blf1rtu71vy17" path="res://asset/audio/sfx/环境音/第一章/楼道场景1.ogg" id="3_74b3r"]
[ext_resource type="Texture2D" uid="uid://dbtepltemtmy2" path="res://asset/art/scene/c02/s05_一楼内侧楼道/bg_楼道背景.png" id="3_rcuxq"]
[ext_resource type="AudioStream" uid="uid://d3tnbdx2j4tmy" path="res://asset/audio/sfx/bgm/第一章/sfx_一楼楼道记忆闪回.ogg" id="4_74b3r"]
[ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="4_tueh3"]
@ -113,10 +113,17 @@ libraries = {
}
script = ExtResource("2_70lf6")
[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"]
script = ExtResource("3_laquj")
autoplay_group = &"c02_楼道1"
metadata/_custom_type_script = "uid://cpejxlfni6n52"
[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"]
process_mode = 1
stream = ExtResource("3_74b3r")
volume_db = -5.0
autoplay = true
bus = &"game_sfx"
script = ExtResource("5_74b3r")
mode = "场景背景音"
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="Sfx记忆闪回音效" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"]
stream = ExtResource("4_74b3r")

View File

@ -2,7 +2,7 @@
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_qkymk"]
[ext_resource type="Script" uid="uid://cbt0ubygchxvv" path="res://scene/ground/scene/c02/s06_二楼.gd" id="2_4dg6u"]
[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_h3h1a"]
[ext_resource type="AudioStream" uid="uid://bjwguxsoehrne" path="res://asset/audio/sfx/环境音/第一章/楼道场景2.ogg" id="3_lipxo"]
[ext_resource type="Texture2D" uid="uid://6ol2om68cd1q" path="res://asset/art/scene/c02/s06_二楼楼道/bg_背景.png" id="3_och2w"]
[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_2e08x"]
[ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="4_haidv"]
@ -903,10 +903,17 @@ libraries = {
}
script = ExtResource("2_4dg6u")
[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"]
script = ExtResource("3_h3h1a")
autoplay_group = &"c02_楼道2"
metadata/_custom_type_script = "uid://cpejxlfni6n52"
[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"]
process_mode = 1
stream = ExtResource("3_lipxo")
volume_db = -5.0
autoplay = true
bus = &"game_sfx"
script = ExtResource("4_2e08x")
mode = "场景背景音"
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="Sfx翻找东西" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"]
stream = ExtResource("5_lh55k")

View File

@ -1,9 +1,10 @@
[gd_scene load_steps=19 format=3 uid="uid://t4xjt774ngwh"]
[gd_scene load_steps=20 format=3 uid="uid://t4xjt774ngwh"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_oao56"]
[ext_resource type="Script" uid="uid://cnjdxjni5v3cs" path="res://scene/ground/scene/c02/s07_二楼内侧楼道.gd" id="2_t0s64"]
[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_geise"]
[ext_resource type="AudioStream" uid="uid://bjwguxsoehrne" path="res://asset/audio/sfx/环境音/第一章/楼道场景2.ogg" id="3_e4bwj"]
[ext_resource type="Texture2D" uid="uid://u7rp66mboqq4" path="res://asset/art/scene/c02/s07_二楼内侧楼道/bg_背景.png" id="3_t0s64"]
[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_4anfx"]
[ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="4_5krke"]
[ext_resource type="Texture2D" uid="uid://bim6w1xp1a4bg" path="res://asset/art/scene/c02/s07_二楼内侧楼道/锡箔墙面涂鸦提示.png" id="5_6ivku"]
[ext_resource type="PackedScene" uid="uid://xovlfee503a4" path="res://scene/ground/script/c02/小手讨东西.tscn" id="6_5krke"]
@ -28,10 +29,17 @@ player_y = 60
[node name="AnimationPlayer" parent="Ground" index="0"]
script = ExtResource("2_t0s64")
[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"]
script = ExtResource("3_geise")
autoplay_group = &"c02_楼道2"
metadata/_custom_type_script = "uid://cpejxlfni6n52"
[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"]
process_mode = 1
stream = ExtResource("3_e4bwj")
volume_db = -5.0
autoplay = true
bus = &"game_sfx"
script = ExtResource("4_4anfx")
mode = "场景背景音"
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="BGSprite2D" parent="Ground" index="2"]
texture = ExtResource("3_t0s64")

View File

@ -4,6 +4,7 @@
[ext_resource type="Script" uid="uid://hbbgymjs5xte" path="res://scene/ground/scene/c02/s08_瞎子卧室.gd" id="2_m4uw8"]
[ext_resource type="Texture2D" uid="uid://v3sj36aijq5b" path="res://asset/art/scene/c03/s04_瞎子新卧室/bg_瞎子卧室.png" id="3_iares"]
[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_quq80"]
[ext_resource type="Texture2D" uid="uid://v3sj36aijq5b" path="res://asset/art/scene/c02/s08_瞎子卧室/bg_瞎子卧室.png" id="3_iares"]
[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="3_t3h08"]
[ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="4_1ws4i"]
[ext_resource type="Texture2D" uid="uid://vqyhgyka3sfo" path="res://asset/art/scene/c03/s04_瞎子新卧室/瞎子卧室前景.png" id="4_gx8oy"]
@ -12,6 +13,7 @@
[ext_resource type="Texture2D" uid="uid://7ay1ttob8qwm" path="res://asset/art/scene/c03/s04_瞎子新卧室/e_床板.png" id="5_vjjde"]
[ext_resource type="AudioStream" uid="uid://c26x8f18w6is0" path="res://asset/audio/sfx/旧版/c02/撞到柜子.mp3" id="6_nnqdd"]
[ext_resource type="Texture2D" uid="uid://vqyhgyka3sfo" path="res://asset/art/scene/c02/s08_瞎子卧室/瞎子卧室前景.png" id="4_gx8oy"]
[ext_resource type="AudioStream" uid="uid://o57tyriodr0c" path="res://asset/audio/sfx/环境音/白噪音/白噪声房间里2.ogg" id="4_quq80"]
[ext_resource type="AudioStream" uid="uid://dk3e1w3n2snur" path="res://asset/audio/sfx/旧版/c02/纸人出现.ogg" id="5_0qeqe"]
[ext_resource type="Texture2D" uid="uid://b5pwb4fm46sad" path="res://asset/art/scene/c02/s08_瞎子卧室/e_墙上纸张.png" id="5_f6mma"]
[ext_resource type="Texture2D" uid="uid://7ay1ttob8qwm" path="res://asset/art/scene/c02/s08_瞎子卧室/e_床板.png" id="5_vjjde"]
@ -116,10 +118,17 @@ libraries = {
}
script = ExtResource("2_m4uw8")
[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"]
script = ExtResource("3_quq80")
autoplay_group = &"c02_房间里2"
metadata/_custom_type_script = "uid://cpejxlfni6n52"
[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"]
process_mode = 1
stream = ExtResource("4_quq80")
volume_db = -5.0
autoplay = true
bus = &"game_sfx"
script = ExtResource("3_t3h08")
mode = "场景背景音"
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="Sfx癞子对视惊吓" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"]
stream = ExtResource("5_0qeqe")

View File

@ -186,7 +186,6 @@ autoplay = true
bus = &"game_sfx"
script = ExtResource("4_qjenp")
mode = "场景背景音"
"自动开始" = true
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
@ -196,7 +195,6 @@ stream = ExtResource("5_husb8")
bus = &"game_sfx"
script = ExtResource("4_qjenp")
mode = "场景背景音"
"自动开始" = false
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"

View File

@ -2,8 +2,8 @@
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_w7j0m"]
[ext_resource type="Script" uid="uid://dkkey7qillk15" path="res://scene/ground/scene/c02/s10_空房间.gd" id="2_egtqi"]
[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_kqj5r"]
[ext_resource type="Texture2D" uid="uid://molvyfyy63ik" path="res://asset/art/scene/c02/s10_空房间/bg_空房间.png" id="3_ox8et"]
[ext_resource type="AudioStream" uid="uid://b2mudqvq1dmng" path="res://asset/audio/sfx/环境音/白噪音/白噪声房间里1.ogg" id="4_alb6s"]
[ext_resource type="AudioStream" uid="uid://dfni8aakmmp00" path="res://asset/audio/sfx/旧版/c02/红色印记出现.ogg" id="4_nx6jy"]
[ext_resource type="AudioStream" uid="uid://bhaws2ungqaf5" path="res://asset/audio/sfx/交互/角色/sfx_哼歌.ogg" id="5_8cwaw"]
[ext_resource type="PackedScene" uid="uid://cw3q5pvciumil" path="res://scene/entity/interactable.tscn" id="5_ylhfc"]
@ -85,10 +85,17 @@ player_y = 60
[node name="AnimationPlayer" parent="Ground" index="0"]
script = ExtResource("2_egtqi")
[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"]
script = ExtResource("3_kqj5r")
autoplay_group = &"c02_房间里1"
metadata/_custom_type_script = "uid://cpejxlfni6n52"
[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"]
process_mode = 1
stream = ExtResource("4_alb6s")
volume_db = -5.0
autoplay = true
bus = &"game_sfx"
script = ExtResource("6_6uftv")
mode = "场景背景音"
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="Sfx小蝉出现" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"]
stream = ExtResource("4_nx6jy")

View File

@ -6,7 +6,7 @@
[ext_resource type="Texture2D" uid="uid://yn00uls1kvn3" path="res://asset/art/scene/c02/s12_to_s17_盒子猫/bg_初始.png" id="3_oskpk"]
[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_r3hvb"]
[ext_resource type="PackedScene" uid="uid://khwxm5qbfj3k" path="res://scene/ground/script/c02/盒子猫canvas_layer.tscn" id="4_vv3sh"]
[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="5_72mc1"]
[ext_resource type="AudioStream" uid="uid://b2mudqvq1dmng" path="res://asset/audio/sfx/环境音/白噪音/白噪声房间里1.ogg" id="5_72mc1"]
[ext_resource type="SpriteFrames" uid="uid://b85gyfhk1mg6r" path="res://asset/art/gif/c02_盒子猫/c02_盒子猫_frames.tres" id="5_ycgng"]
[node name="S12" type="Node2D"]
@ -26,10 +26,17 @@ bus = &"game_sfx"
script = ExtResource("4_r3hvb")
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="1"]
script = ExtResource("5_72mc1")
autoplay_group = &"c02_房间里1"
metadata/_custom_type_script = "uid://cpejxlfni6n52"
[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"]
process_mode = 1
stream = ExtResource("5_72mc1")
volume_db = -5.0
autoplay = true
bus = &"game_sfx"
script = ExtResource("4_r3hvb")
mode = "场景背景音"
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="BGSprite2D" parent="Ground" index="2"]
texture = ExtResource("3_oskpk")

View File

@ -7,7 +7,7 @@
[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_yywsi"]
[ext_resource type="AudioStream" uid="uid://b8sbtn3l37uh" path="res://asset/audio/sfx/旧版/c02/红屏.ogg" id="5_yywsi"]
[ext_resource type="Texture2D" uid="uid://csrfyvaufo1wb" path="res://asset/art/scene/c02/s12_to_s17_盒子猫/l_瞎子理发店光.png" id="6_gge8e"]
[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="6_kmk38"]
[ext_resource type="AudioStream" uid="uid://b2mudqvq1dmng" path="res://asset/audio/sfx/环境音/白噪音/白噪声房间里1.ogg" id="6_kmk38"]
[ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="6_yywsi"]
[ext_resource type="PackedScene" uid="uid://khwxm5qbfj3k" path="res://scene/ground/script/c02/盒子猫canvas_layer.tscn" id="7_u2fv1"]
[ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="9_yywsi"]
@ -36,10 +36,17 @@ bus = &"game_sfx"
script = ExtResource("4_yywsi")
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="2"]
script = ExtResource("6_kmk38")
autoplay_group = &"c02_房间里1"
metadata/_custom_type_script = "uid://cpejxlfni6n52"
[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="2"]
process_mode = 1
stream = ExtResource("6_kmk38")
volume_db = -5.0
autoplay = true
bus = &"game_sfx"
script = ExtResource("4_yywsi")
mode = "场景背景音"
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="BGSprite2D" parent="Ground" index="2"]
texture = ExtResource("3_miykx")

View File

@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://d0p4x5st2r315"]
[gd_scene load_steps=9 format=3 uid="uid://d0p4x5st2r315"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_cr1hi"]
[ext_resource type="Script" uid="uid://bjisuntcem2lv" path="res://scene/ground/scene/c02/s14_盒子猫二楼内侧.gd" id="2_o47bv"]
[ext_resource type="Texture2D" uid="uid://y0e47513ca22" path="res://asset/art/scene/c02/s12_to_s17_盒子猫/bg_二楼内侧楼道粉笔画.png" id="3_cr1hi"]
[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_idisw"]
[ext_resource type="AudioStream" uid="uid://b2mudqvq1dmng" path="res://asset/audio/sfx/环境音/白噪音/白噪声房间里1.ogg" id="3_kss0n"]
[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_3yfjs"]
[ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="4_o47bv"]
[ext_resource type="PackedScene" uid="uid://khwxm5qbfj3k" path="res://scene/ground/script/c02/盒子猫canvas_layer.tscn" id="5_cr1hi"]
[ext_resource type="PackedScene" uid="uid://dewbg4phd8c17" path="res://scene/ground/script/c02/追猫猪头怪.tscn" id="5_o47bv"]
@ -19,10 +20,17 @@ footstep_type = "盒子猫"
[node name="AnimationPlayer" parent="Ground" index="0"]
script = ExtResource("2_o47bv")
[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"]
script = ExtResource("3_idisw")
autoplay_group = &"c02_房间里1"
metadata/_custom_type_script = "uid://cpejxlfni6n52"
[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"]
process_mode = 1
stream = ExtResource("3_kss0n")
volume_db = -5.0
autoplay = true
bus = &"game_sfx"
script = ExtResource("4_3yfjs")
mode = "场景背景音"
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="BGSprite2D" parent="Ground" index="2"]
texture = ExtResource("3_cr1hi")

View File

@ -1,9 +1,10 @@
[gd_scene load_steps=7 format=3 uid="uid://b21p53g42j2nt"]
[gd_scene load_steps=8 format=3 uid="uid://b21p53g42j2nt"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_qxg0l"]
[ext_resource type="Script" uid="uid://ebaq235h32fd" path="res://scene/ground/scene/c02/s15_盒子猫一楼内侧.gd" id="2_etqjj"]
[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_etqjj"]
[ext_resource type="AudioStream" uid="uid://b2mudqvq1dmng" path="res://asset/audio/sfx/环境音/白噪音/白噪声房间里1.ogg" id="3_etqjj"]
[ext_resource type="Texture2D" uid="uid://c4eb71kdnqy3y" path="res://asset/art/scene/c02/s12_to_s17_盒子猫/bg_一楼内侧楼道粉笔画.png" id="3_qxg0l"]
[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_k187n"]
[ext_resource type="PackedScene" uid="uid://khwxm5qbfj3k" path="res://scene/ground/script/c02/盒子猫canvas_layer.tscn" id="5_isic3"]
[ext_resource type="PackedScene" uid="uid://dewbg4phd8c17" path="res://scene/ground/script/c02/追猫猪头怪.tscn" id="6_etqjj"]
@ -18,10 +19,17 @@ footstep_type = "盒子猫"
[node name="AnimationPlayer" parent="Ground" index="0"]
script = ExtResource("2_etqjj")
[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"]
script = ExtResource("3_etqjj")
autoplay_group = &"c02_房间里1"
metadata/_custom_type_script = "uid://cpejxlfni6n52"
[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"]
process_mode = 1
stream = ExtResource("3_etqjj")
volume_db = -5.0
autoplay = true
bus = &"game_sfx"
script = ExtResource("4_k187n")
mode = "场景背景音"
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="BGSprite2D" parent="Ground" index="2"]
texture = ExtResource("3_qxg0l")

View File

@ -1,9 +1,10 @@
[gd_scene load_steps=9 format=3 uid="uid://22hc3oe8t0id"]
[gd_scene load_steps=10 format=3 uid="uid://22hc3oe8t0id"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_umyae"]
[ext_resource type="Script" uid="uid://dx2w5v1erjyls" path="res://scene/ground/scene/c02/s16_盒子猫三楼内侧.gd" id="2_tmnwc"]
[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_r8qm5"]
[ext_resource type="AudioStream" uid="uid://b2mudqvq1dmng" path="res://asset/audio/sfx/环境音/白噪音/白噪声房间里1.ogg" id="3_7w00y"]
[ext_resource type="Texture2D" uid="uid://by4ymjhnma8c6" path="res://asset/art/scene/c02/s12_to_s17_盒子猫/bg_三楼内侧楼道粉笔画.png" id="3_tmnwc"]
[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_1h6hi"]
[ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="4_qkv3g"]
[ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="5_qkv3g"]
[ext_resource type="PackedScene" uid="uid://khwxm5qbfj3k" path="res://scene/ground/script/c02/盒子猫canvas_layer.tscn" id="5_tmnwc"]
@ -20,10 +21,17 @@ footstep_type = "盒子猫"
[node name="AnimationPlayer" parent="Ground" index="0"]
script = ExtResource("2_tmnwc")
[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"]
script = ExtResource("3_r8qm5")
autoplay_group = &"c02_房间里1"
metadata/_custom_type_script = "uid://cpejxlfni6n52"
[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"]
process_mode = 1
stream = ExtResource("3_7w00y")
volume_db = -5.0
autoplay = true
bus = &"game_sfx"
script = ExtResource("4_1h6hi")
mode = "场景背景音"
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="BGSprite2D" parent="Ground" index="2"]
texture = ExtResource("3_tmnwc")

View File

@ -1,10 +1,11 @@
[gd_scene load_steps=9 format=3 uid="uid://cbr6gbgrl2wb1"]
[gd_scene load_steps=10 format=3 uid="uid://cbr6gbgrl2wb1"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_e436a"]
[ext_resource type="Script" uid="uid://bkkhxiyblu2lo" path="res://scene/ground/scene/c02/s17_盒子猫三楼.gd" id="2_e436a"]
[ext_resource type="AudioStream" uid="uid://b2mudqvq1dmng" path="res://asset/audio/sfx/环境音/白噪音/白噪声房间里1.ogg" id="3_4yexs"]
[ext_resource type="Texture2D" uid="uid://iyeqjguyrhog" path="res://asset/art/scene/c02/s12_to_s17_盒子猫/bg_三楼楼道粉笔画.png" id="3_e436a"]
[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_uua76"]
[ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="4_e436a"]
[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_m6dyn"]
[ext_resource type="PackedScene" uid="uid://khwxm5qbfj3k" path="res://scene/ground/script/c02/盒子猫canvas_layer.tscn" id="4_n3bxc"]
[ext_resource type="PackedScene" uid="uid://dewbg4phd8c17" path="res://scene/ground/script/c02/追猫猪头怪.tscn" id="6_pfgbg"]
[ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="8_m6dyn"]
@ -20,10 +21,17 @@ footstep_type = "盒子猫"
[node name="AnimationPlayer" parent="Ground" index="0"]
script = ExtResource("2_e436a")
[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"]
script = ExtResource("3_uua76")
autoplay_group = &"c02_房间里1"
metadata/_custom_type_script = "uid://cpejxlfni6n52"
[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"]
process_mode = 1
stream = ExtResource("3_4yexs")
volume_db = -5.0
autoplay = true
bus = &"game_sfx"
script = ExtResource("4_m6dyn")
mode = "场景背景音"
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="BGSprite2D" parent="Ground" index="2"]
texture = ExtResource("3_e436a")

View File

@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://d27gv3pbkn4b8"]
[gd_scene load_steps=9 format=3 uid="uid://d27gv3pbkn4b8"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_4bsvj"]
[ext_resource type="Script" uid="uid://b3mak700k2qwt" path="res://scene/ground/scene/c02/s18_盒子猫一楼.gd" id="2_4bsvj"]
[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_4bsvj"]
[ext_resource type="AudioStream" uid="uid://b2mudqvq1dmng" path="res://asset/audio/sfx/环境音/白噪音/白噪声房间里1.ogg" id="3_bbmua"]
[ext_resource type="Texture2D" uid="uid://ttocw3erg8jv" path="res://asset/art/scene/c02/s12_to_s17_盒子猫/bg_一楼楼道粉笔画.png" id="3_owpnf"]
[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_po2lv"]
[ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="5_emyx1"]
[ext_resource type="PackedScene" uid="uid://dewbg4phd8c17" path="res://scene/ground/script/c02/追猫猪头怪.tscn" id="6_xoyld"]
[ext_resource type="PackedScene" uid="uid://khwxm5qbfj3k" path="res://scene/ground/script/c02/盒子猫canvas_layer.tscn" id="7_8eo7o"]
@ -19,10 +20,17 @@ footstep_type = "盒子猫"
[node name="AnimationPlayer" parent="Ground" index="0"]
script = ExtResource("2_4bsvj")
[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"]
script = ExtResource("3_4bsvj")
autoplay_group = &"c02_房间里1"
metadata/_custom_type_script = "uid://cpejxlfni6n52"
[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"]
process_mode = 1
stream = ExtResource("3_bbmua")
volume_db = -5.0
autoplay = true
bus = &"game_sfx"
script = ExtResource("4_po2lv")
mode = "场景背景音"
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="BGSprite2D" parent="Ground" index="2"]
texture = ExtResource("3_owpnf")

View File

@ -1,8 +1,10 @@
[gd_scene load_steps=30 format=3 uid="uid://dlrbhfvnd3cs0"]
[gd_scene load_steps=33 format=3 uid="uid://dlrbhfvnd3cs0"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_eb2op"]
[ext_resource type="Script" uid="uid://c0rh2n36ait6i" path="res://scene/ground/scene/c03/s01_三楼.gd" id="2_ow08b"]
[ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="3_lb1oo"]
[ext_resource type="AudioStream" uid="uid://bjwguxsoehrne" path="res://asset/audio/sfx/环境音/第一章/楼道场景2.ogg" id="3_hmme5"]
[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_1ebn8"]
[ext_resource type="Texture2D" uid="uid://cpjd3dqri51fq" path="res://asset/art/scene/c03/s01_三楼/bg_三楼走廊.png" id="4_ow08b"]
[ext_resource type="Texture2D" uid="uid://b7t2sfe5ugtsc" path="res://asset/art/scene/c03/引导纸人/指引纸人3.png" id="5_fnwup"]
[ext_resource type="Texture2D" uid="uid://djoft6600kly6" path="res://asset/art/scene/c03/s01_三楼/fg_前景.png" id="5_ow08b"]
@ -84,10 +86,17 @@ libraries = {
}
script = ExtResource("2_ow08b")
[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"]
script = ExtResource("3_lb1oo")
autoplay_group = &"c02_楼道2"
metadata/_custom_type_script = "uid://cpejxlfni6n52"
[node name="Sfx背景音" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"]
process_mode = 1
stream = ExtResource("3_hmme5")
volume_db = -5.0
autoplay = true
bus = &"game_sfx"
script = ExtResource("4_1ebn8")
mode = "场景背景音"
"循环播放" = true
"感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="BGSprite2D" parent="Ground" index="2"]
light_mask = 5
@ -101,7 +110,7 @@ position = Vector2(34, 8)
[node name="portal_right" parent="Ground/DeployLayer" index="1"]
position = Vector2(697, 18)
target_scene = "c02_s06"
target_portal = "right"
target_portal = "3"
[node name="Note治病木牌" parent="Ground/DeployLayer" index="2" instance=ExtResource("18_0xq6i")]
position = Vector2(456, 47)

View File

@ -37,10 +37,10 @@ func _unhandled_input(event: InputEvent) -> void:
elif event.is_action_pressed("panel"):
get_viewport().set_input_as_handled()
SceneManager.show_panel()
elif event.is_action_pressed("savings"):
elif event.is_action_pressed("debugging"):
if GlobalConfig.DEBUG:
get_viewport().set_input_as_handled()
SceneManager.show_savings()
SceneManager.show_debugging()
else:
# 连续按 5 次开启 debug mode
var time = Time.get_ticks_msec()
@ -53,7 +53,7 @@ func _unhandled_input(event: InputEvent) -> void:
get_viewport().set_input_as_handled()
# 不写入配置
GlobalConfig.DEBUG = true
SceneManager.show_savings()
SceneManager.show_debugging()
var vignette_tween: Tween

258
util/audio_loader.gd Normal file
View File

@ -0,0 +1,258 @@
#GDScriptAudioImport v0.1
#MIT License
#
#Copyright (c) 2020 Gianclgar (Giannino Clemente) gianclgar@gmail.com
#
#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
#in the Software without restriction, including without limitation the rights
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#copies of the Software, and to permit persons to whom the Software is
#furnished to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in all
#copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
#SOFTWARE.
#I honestly don't care that much, Kopimi ftw, but it's my little baby and I want it to look nice :3
class_name AudioLoader
func report_errors(err, filepath):
# See: https://docs.godotengine.org/en/latest/classes/class_@globalscope.html#enum-globalscope-error
var result_hash = {
ERR_FILE_NOT_FOUND: "File: not found",
ERR_FILE_BAD_DRIVE: "File: Bad drive error",
ERR_FILE_BAD_PATH: "File: Bad path error.",
ERR_FILE_NO_PERMISSION: "File: No permission error.",
ERR_FILE_ALREADY_IN_USE: "File: Already in use error.",
ERR_FILE_CANT_OPEN: "File: Can't open error.",
ERR_FILE_CANT_WRITE: "File: Can't write error.",
ERR_FILE_CANT_READ: "File: Can't read error.",
ERR_FILE_UNRECOGNIZED: "File: Unrecognized error.",
ERR_FILE_CORRUPT: "File: Corrupt error.",
ERR_FILE_MISSING_DEPENDENCIES: "File: Missing dependencies error.",
ERR_FILE_EOF: "File: End of file (EOF) error."
}
if err in result_hash:
print("Error: ", result_hash[err], " ", filepath)
else:
print("Unknown error with file ", filepath, " error code: ", err)
func loadfile(filepath):
var file_access = FileAccess.open(filepath, FileAccess.READ)
if file_access.get_error() != OK:
report_errors(file_access.get_error(), filepath)
file_access.close()
return AudioSample.new()
var bytes = FileAccess.get_file_as_bytes(filepath)
# if File is wav
if filepath.ends_with(".wav"):
var newstream = AudioStreamWAV.load_from_buffer(bytes)
newstream.take_over_path(filepath)
# #---------------------------
# #parrrrseeeeee!!! :D
# var bits_per_sample = 0
# var i = 0
# while true:
# if i >= len(bytes) - 4: # Failsafe, if there is no data bytes
# print("Data byte not found")
# break
# var those4bytes = str(char(bytes[i])+char(bytes[i+1])+char(bytes[i+2])+char(bytes[i+3]))
# if those4bytes == "RIFF":
# print ("RIFF OK at bytes " + str(i) + "-" + str(i+3))
# #RIP bytes 4-7 integer for now
# if those4bytes == "WAVE":
# print ("WAVE OK at bytes " + str(i) + "-" + str(i+3))
# if those4bytes == "fmt ":
# print ("fmt OK at bytes " + str(i) + "-" + str(i+3))
# #get format subchunk size, 4 bytes next to "fmt " are an int32
# var formatsubchunksize = bytes[i+4] + (bytes[i+5] << 8) + (bytes[i+6] << 16) + (bytes[i+7] << 24)
# print ("Format subchunk size: " + str(formatsubchunksize))
# #using formatsubchunk index so it's easier to understand what's going on
# var fsc0 = i+8 #fsc0 is byte 8 after start of "fmt "
# #get format code [Bytes 0-1]
# var format_code = bytes[fsc0] + (bytes[fsc0+1] << 8)
# var format_name
# if format_code == 0: format_name = "8_BITS"
# elif format_code == 1: format_name = "16_BITS"
# elif format_code == 2: format_name = "IMA_ADPCM"
# else:
# format_name = "UNKNOWN (trying to interpret as 16_BITS)"
# format_code = 1
# print ("Format: " + str(format_code) + " " + format_name)
# #assign format to our AudioSample
# newstream.format = format_code
# #get channel num [Bytes 2-3]
# var channel_num = bytes[fsc0+2] + (bytes[fsc0+3] << 8)
# print ("Number of channels: " + str(channel_num))
# #set our AudioSample to stereo if needed
# if channel_num == 2: newstream.stereo = true
# #get sample rate [Bytes 4-7]
# var sample_rate = bytes[fsc0+4] + (bytes[fsc0+5] << 8) + (bytes[fsc0+6] << 16) + (bytes[fsc0+7] << 24)
# print ("Sample rate: " + str(sample_rate))
# #set our AudioSample mixrate
# newstream.mix_rate = sample_rate
# #get byte_rate [Bytes 8-11] because we can
# var byte_rate = bytes[fsc0+8] + (bytes[fsc0+9] << 8) + (bytes[fsc0+10] << 16) + (bytes[fsc0+11] << 24)
# print ("Byte rate: " + str(byte_rate))
# #same with bits*sample*channel [Bytes 12-13]
# var bits_sample_channel = bytes[fsc0+12] + (bytes[fsc0+13] << 8)
# print ("BitsPerSample * Channel / 8: " + str(bits_sample_channel))
# #aaaand bits per sample/bitrate [Bytes 14-15]
# bits_per_sample = bytes[fsc0+14] + (bytes[fsc0+15] << 8)
# print ("Bits per sample: " + str(bits_per_sample))
# if those4bytes == "data":
# assert(bits_per_sample != 0)
# var audio_data_size = bytes[i+4] + (bytes[i+5] << 8) + (bytes[i+6] << 16) + (bytes[i+7] << 24)
# print ("Audio data/stream size is " + str(audio_data_size) + " bytes")
# var data_entry_point = (i+8)
# print ("Audio data starts at byte " + str(data_entry_point))
# var data = bytes.subarray(data_entry_point, data_entry_point+audio_data_size-1)
# if bits_per_sample in [24, 32]:
# newstream.data = convert_to_16bit(data, bits_per_sample)
# else:
# newstream.data = data
# break # the data will be at the end, end searching here
# i += 1
# # end of parsing
# #---------------------------
# #get samples and set loop end
# var samplenum = newstream.data.size() / 4
# newstream.loop_end = samplenum
# newstream.loop_mode = 1 #change to 0 or delete this line if you don't want loop, also check out modes 2 and 3 in the docs
return newstream #:D
#if file is ogg
elif filepath.ends_with(".ogg"):
var newstream = AudioStreamOggVorbis.load_from_buffer(bytes)
newstream.take_over_path(filepath)
# newstream.loop = true #set to false or delete this line if you don't want to loop
return newstream
#if file is mp3
elif filepath.ends_with(".mp3"):
var newstream = AudioStreamMP3.load_from_buffer(bytes)
newstream.take_over_path(filepath)
# newstream.loop = true #set to false or delete this line if you don't want to loop
return newstream
else:
print ("ERROR: Wrong filetype or format")
# # Converts .wav data from 24 or 32 bits to 16
# #
# # These conversions are SLOW in GDScript
# # on my one test song, 32 -> 16 was around 3x slower than 24 -> 16
# #
# # I couldn't get threads to help very much
# # They made the 24bit case about 2x faster in my test file
# # And the 32bit case abour 50% slower
# # I don't wanna risk it always being slower on other files
# # And really, the solution would be to handle it in a low-level language
# func convert_to_16bit(data: PackedByteArray, from: int) -> PackedByteArray:
# print("converting to 16-bit from %d" % from)
# var time = Time.get_ticks_msec()
# # 24 bit .wav's are typically stored as integers
# # so we just grab the 2 most significant bytes and ignore the other
# if from == 24:
# var j = 0
# for i in range(0, data.size(), 3):
# data[j] = data[i+1]
# data[j+1] = data[i+2]
# j += 2
# data.resize(data.size() * 2 / 3)
# # 32 bit .wav's are typically stored as floating point numbers
# # so we need to grab all 4 bytes and interpret them as a float first
# if from == 32:
# var spb := StreamPeerBuffer.new()
# var single_float: float
# var value: int
# for i in range(0, data.size(), 4):
# # spb.data_array = data.subarray(i, i+3)
# spb.data_array = data.slice(i, i+4)
# single_float = spb.get_float()
# value = single_float * 32768
# data[i/2] = value
# data[i/2+1] = value >> 8
# data.resize(data.size() / 2)
# print("Took %f seconds for slow conversion" % ((Time.get_ticks_msec() - time) / 1000.0))
# return data
# ---------- REFERENCE ---------------
# note: typical values doesn't always match
#Positions Typical Value Description
#
#1 - 4 "RIFF" Marks the file as a RIFF multimedia file.
# Characters are each 1 byte long.
#
#5 - 8 (integer) The overall file size in bytes (32-bit integer)
# minus 8 bytes. Typically, you'd fill this in after
# file creation is complete.
#
#9 - 12 "WAVE" RIFF file format header. For our purposes, it
# always equals "WAVE".
#
#13-16 "fmt " Format sub-chunk marker. Includes trailing null.
#
#17-20 16 Length of the rest of the format sub-chunk below.
#
#21-22 1 Audio format code, a 2 byte (16 bit) integer.
# 1 = PCM (pulse code modulation).
#
#23-24 2 Number of channels as a 2 byte (16 bit) integer.
# 1 = mono, 2 = stereo, etc.
#
#25-28 44100 Sample rate as a 4 byte (32 bit) integer. Common
# values are 44100 (CD), 48000 (DAT). Sample rate =
# number of samples per second, or Hertz.
#
#29-32 176400 (SampleRate * BitsPerSample * Channels) / 8
# This is the Byte rate.
#
#33-34 4 (BitsPerSample * Channels) / 8
# 1 = 8 bit mono, 2 = 8 bit stereo or 16 bit mono, 4
# = 16 bit stereo.
#
#35-36 16 Bits per sample.
#
#37-40 "data" Data sub-chunk header. Marks the beginning of the
# raw data section.
#
#41-44 (integer) The number of bytes of the data section below this
# point. Also equal to (#ofSamples * #ofChannels *
# BitsPerSample) / 8
#
#45+ The raw audio data.

1
util/audio_loader.gd.uid Normal file
View File

@ -0,0 +1 @@
uid://dho44deftogm8