更新道具监视页面;groundloader实时加载更新;音效导入sfx节点优化

This commit is contained in:
cakipaul 2024-12-30 21:19:10 +08:00
parent 77a180091c
commit a8b947f9a5
106 changed files with 828 additions and 327 deletions

File diff suppressed because one or more lines are too long

View File

@ -16,5 +16,5 @@ func play_random():
if stream == null: if stream == null:
push_error("empty stream in audio_collection", audio_collection) push_error("empty stream in audio_collection", audio_collection)
return return
pitch_scale = randf_range(.8, 1) # pitch_scale = randf_range(.8, 1)
play() play()

View File

@ -0,0 +1,11 @@
[gd_resource type="Resource" script_class="AudioStreamCollection" load_steps=6 format=3 uid="uid://df3raqjjpxokx"]
[ext_resource type="AudioStream" uid="uid://2flq0ji8qdty" path="res://asset/audio/sfx/lvping/爬行_1.mp3" id="1_6m3uo"]
[ext_resource type="AudioStream" uid="uid://bj2nccns1akat" path="res://asset/audio/sfx/lvping/爬行.mp3" id="2_e530w"]
[ext_resource type="AudioStream" uid="uid://cfvee3c27t458" path="res://asset/audio/sfx/lvping/爬行_2.mp3" id="3_u6hi2"]
[ext_resource type="AudioStream" uid="uid://cv85bbmp3dh6w" path="res://asset/audio/sfx/lvping/爬行_3.mp3" id="4_cpnk0"]
[ext_resource type="Script" path="res://config/audio/audio_stream_collection.gd" id="5_urhav"]
[resource]
script = ExtResource("5_urhav")
audios = Array[AudioStream]([ExtResource("1_6m3uo"), ExtResource("2_e530w"), ExtResource("3_u6hi2"), ExtResource("4_cpnk0")])

View File

@ -0,0 +1,11 @@
[gd_resource type="Resource" script_class="AudioStreamCollection" load_steps=6 format=3 uid="uid://wq2csakuohtm"]
[ext_resource type="AudioStream" uid="uid://b2hmd4ilf3sr" path="res://asset/audio/sfx/ghost/footstep_ghost_1.wav" id="1_86s4j"]
[ext_resource type="AudioStream" uid="uid://bhnc86jadd47f" path="res://asset/audio/sfx/ghost/footstep_ghost_2.wav" id="2_rycqk"]
[ext_resource type="AudioStream" uid="uid://n7pf2xy2kb5s" path="res://asset/audio/sfx/ghost/footstep_ghost_3.wav" id="3_vymt5"]
[ext_resource type="AudioStream" uid="uid://dikj2lqu1hxfo" path="res://asset/audio/sfx/ghost/footstep_ghost_4.wav" id="4_axblh"]
[ext_resource type="Script" path="res://config/audio/audio_stream_collection.gd" id="5_mhwew"]
[resource]
script = ExtResource("5_mhwew")
audios = Array[AudioStream]([ExtResource("1_86s4j"), ExtResource("2_rycqk"), ExtResource("3_vymt5"), ExtResource("4_axblh")])

View File

@ -0,0 +1,9 @@
[gd_resource type="Resource" script_class="AudioStreamCollection" load_steps=4 format=3 uid="uid://dt331dop6er5q"]
[ext_resource type="AudioStream" uid="uid://djccgco6u2ns7" path="res://asset/audio/sfx/lvping/奔跑-右.wav" id="3_oqsbq"]
[ext_resource type="AudioStream" uid="uid://by6m4uu5tjt0b" path="res://asset/audio/sfx/lvping/奔跑-左.wav" id="4_6cfdb"]
[ext_resource type="Script" path="res://config/audio/audio_stream_collection.gd" id="5_dum3n"]
[resource]
script = ExtResource("5_dum3n")
audios = Array[AudioStream]([ExtResource("3_oqsbq"), ExtResource("4_6cfdb")])

View File

@ -0,0 +1,9 @@
[gd_resource type="Resource" script_class="AudioStreamCollection" load_steps=4 format=3 uid="uid://cqugawm84d37j"]
[ext_resource type="AudioStream" uid="uid://ca5ngmv2ettjt" path="res://asset/audio/sfx/lvping/footstep_earth_left.wav" id="1_qnuyr"]
[ext_resource type="AudioStream" uid="uid://tbivv8yyxw7d" path="res://asset/audio/sfx/lvping/footstep_earth_right.wav" id="2_kpwj5"]
[ext_resource type="Script" path="res://config/audio/audio_stream_collection.gd" id="3_ja105"]
[resource]
script = ExtResource("3_ja105")
audios = Array[AudioStream]([ExtResource("1_qnuyr"), ExtResource("2_kpwj5")])

View File

@ -1,11 +1,15 @@
class_name SceneConfig extends Resource class_name SceneConfig extends Resource
const FOOTSTEP_AUDIO = { const FOOTSTEP_AUDIO = {
"wood": preload("res://config/audio/footstep/footstep_wood.tres"), #"wood": preload("res://config/audio/footstep/footstep_wood.tres"),
"carpet": preload("res://config/audio/footstep/footstep_carpet.tres"), #"carpet": preload("res://config/audio/footstep/footstep_carpet.tres"),
"concrete": preload("res://config/audio/footstep/footstep_concrete.tres"), "concrete": preload("res://config/audio/footstep/footstep_concrete.tres"),
"grass": preload("res://config/audio/footstep/footstep_grass.tres"), #"grass": preload("res://config/audio/footstep/footstep_grass.tres"),
"snow": preload("res://config/audio/footstep/footstep_snow.tres"), #"snow": preload("res://config/audio/footstep/footstep_snow.tres"),
"ghost": preload("res://config/audio/sfx/footstep_ghost.tres"),
"walking": preload("res://config/audio/sfx/footstep_walking.tres"),
"running": preload("res://config/audio/sfx/footstep_running.tres"),
"crawling": preload("res://config/audio/sfx/footstep_crawling.tres"),
} }
@export var scene_name: String = "" @export var scene_name: String = ""
@ -25,6 +29,6 @@ const FOOTSTEP_AUDIO = {
@export var camera_rect: Rect2 = Rect2(0, -1000, 664, 2317) # 564*317, 16:9 @export var camera_rect: Rect2 = Rect2(0, -1000, 664, 2317) # 564*317, 16:9
## sound ## sound
@export_enum("none", "wood", "carpet", "concrete", "grass", "snow") @export_enum("none", "ghost", "walking", "running", "crawling", "concrete")
var footstep_type: String = "concrete" var footstep_type: String = "concrete"
var bgm: String = "" var bgm: String = ""

View File

@ -32,11 +32,6 @@ func _ready() -> void:
func _notification(what): func _notification(what):
# handle window close request # handle window close request
if what == NOTIFICATION_WM_CLOSE_REQUEST: if what == NOTIFICATION_WM_CLOSE_REQUEST:
# player_global_position
var player = SceneManager.get_player() as MainPlayer
if archive and player:
archive.player_global_position = player.global_position
archive.player_direction = player.facing_direction
save_all() save_all()
print("Saved all success before Quit") print("Saved all success before Quit")
SceneManager.pop_notification("已保存所有数据") SceneManager.pop_notification("已保存所有数据")
@ -132,6 +127,12 @@ func save_all() -> void:
var config = GlobalConfigManager.config var config = GlobalConfigManager.config
if config: if config:
ResourceSaver.save(config) ResourceSaver.save(config)
# player_global_position
var player = SceneManager.get_player() as MainPlayer
if archive and player:
archive.player_global_position = player.global_position
archive.player_direction = player.facing_direction
if archive: if archive:
ResourceSaver.save(archive) ResourceSaver.save(archive)
# reset autosave timer # reset autosave timer
@ -162,7 +163,7 @@ func load_archive() -> void:
_handle_load_error(str(selected_id) + " 号存档", "查找") _handle_load_error(str(selected_id) + " 号存档", "查找")
return return
var path = archive_dir + archive_prefix + str(selected_id) + GlobalConfig.RES_FILE_FORMAT var path = archive_dir + archive_prefix + str(selected_id) + GlobalConfig.RES_FILE_FORMAT
archive = ResourceLoader.load(path) archive = ResourceLoader.load(path, "", ResourceLoader.CACHE_MODE_REPLACE_DEEP)
if !archive: if !archive:
_handle_load_error(str(selected_id) + " 号存档", "加载") _handle_load_error(str(selected_id) + " 号存档", "加载")
return return

View File

@ -1,10 +1,24 @@
extends Node extends Node
var sfx_players = [] as Array[AudioStreamPlayer]
var idx = 0
func _ready() -> void:
for i in range(5):
var sfx_player = RandomAudioStreamPlayer.new()
sfx_players.append(sfx_player)
sfx_player.bus = "game_sfx"
add_child(sfx_player)
func play_animation_sound(animation): func play_animation_sound(animation):
#TODO #TODO
print("Playing sound for animation: ", animation) print("Playing sound for animation: ", animation)
func play_sfx(sfx: String) -> void: func play_sfx(sfx: AudioStream, db := 1.0) -> void:
pass sfx_players[idx].stream = sfx
sfx_players[idx].volume_db = db
sfx_players[idx].play()
idx = wrapi(idx + 1, 0, 5)

View File

@ -1,11 +0,0 @@
extends Node
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass

View File

@ -1,3 +1,57 @@
extends Node extends Node
var config: GlobalConfig var config: GlobalConfig
var timer = Timer.new()
func _ready() -> void:
timer.wait_time = 5
timer.one_shot = false
timer.timeout.connect(_on_timer_timeout)
add_child(timer)
timer.start()
func _on_timer_timeout():
var archive = ArchiveManager.archive
if archive:
archive.game_seconds_all += 5
archive.game_seconds_current += 5
if config:
config.game_total_seconds += 5
func pack_current_time():
var packed_time = PackedTime.new()
packed_time.time = Time.get_datetime_string_from_system(false, true)
var archive = ArchiveManager.archive
if archive:
packed_time.chapter = archive.current_chapter
packed_time.section = archive.current_section
packed_time.game_archive_id = archive.archive_id
packed_time.game_seconds_all = archive.game_seconds_all
packed_time.game_seconds_current = archive.game_seconds_current
# for log use
func get_concise_timemark() -> String:
var archive = ArchiveManager.archive
if not archive:
return "r0_c0_s0 00:00:00"
var hour = archive.game_seconds_current / 3600 as int
var minute = (archive.game_seconds_current % 3600) / 60 as int
var second = archive.game_seconds_current % 60
return (
"r"
+ str(ArchiveManager.current_archive_id)
+ "_c"
+ str(archive.current_chapter)
+ "_s"
+ str(archive.current_section)
+ " "
+ str(hour)
+ ":"
+ str(minute)
+ ":"
+ str(second)
)

View File

@ -1,11 +0,0 @@
extends Node
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass

View File

@ -1,13 +1,30 @@
extends Node extends Node
# SceneManager.set_camera_boundary(bg.texture.get_size()) enum VIBE {
# SceneManager.set_player_boundary(bg.texture.get_size()) NORAML,
MYSTERY,
DANGEROUS,
TOUCHING,
}
func get_camera() -> MainCamera:
return get_node_or_null("/root/Main/MainPlayer/CameraFocusMarker/MainCamera") as MainCamera
func get_player() -> MainPlayer:
return get_node_or_null("/root/Main/MainPlayer") as MainPlayer
# lock_time: the time to lock the player action. 0 means lock forever, thus the player will be locked until release_player is called.
func freeze_player(lock_time: float, animation := ""):
var player = get_player()
if player:
player.freeze_player(lock_time, animation)
func set_camera_boundary(size: Vector2) -> void: func set_camera_boundary(size: Vector2) -> void:
var camera = ( var camera = get_camera()
get_node_or_null("/root/Main/MainPlayer/CameraFocusMarker/MainCamera") as MainCamera
)
if camera: if camera:
camera.limit_left = 0 camera.limit_left = 0
camera.limit_right = size.x camera.limit_right = size.x
@ -20,7 +37,7 @@ func set_camera_boundary(size: Vector2) -> void:
func set_player_boundary(size: Vector2) -> void: func set_player_boundary(size: Vector2) -> void:
var player = get_node_or_null("/root/Main/MainPlayer") as MainPlayer var player = get_player()
if player: if player:
size.x = size.x - 30 size.x = size.x - 30
var rect = Rect2(Vector2(15, -size.y / 2), size) var rect = Rect2(Vector2(15, -size.y / 2), size)
@ -31,10 +48,6 @@ func set_player_boundary(size: Vector2) -> void:
printerr("Player node not found") printerr("Player node not found")
func get_player() -> MainPlayer:
return get_node_or_null("/root/Main/MainPlayer") as MainPlayer
func get_ground_loader() -> GroundLoader: func get_ground_loader() -> GroundLoader:
return get_node_or_null("/root/Main/GroundLoader") as GroundLoader return get_node_or_null("/root/Main/GroundLoader") as GroundLoader
@ -67,3 +80,8 @@ func pop_note(note: String, note_color := "white", duration := 2.5) -> void:
dialog_node.append_note(note, note_color, duration) dialog_node.append_note(note, note_color, duration)
else: else:
printerr("Dialog node not found") printerr("Dialog node not found")
func get_inspector() -> PropInspector:
return get_node_or_null("/root/Main/PropInspector") as PropInspector

View File

@ -1,56 +0,0 @@
extends Node
var timer: Timer
func _ready() -> void:
timer = Timer.new()
timer.wait_time = 5
timer.one_shot = false
timer.timeout.connect(_on_timer_timeout)
add_child(timer)
timer.start()
func _on_timer_timeout():
var archive = ArchiveManager.archive
if archive:
archive.game_seconds_all += 5
archive.game_seconds_current += 5
GlobalConfigManager.config.game_total_seconds += 5
func pack_current_time():
var packed_time = PackedTime.new()
packed_time.time = Time.get_datetime_string_from_system(false, true)
var archive = ArchiveManager.archive
if archive:
packed_time.chapter = archive.current_chapter
packed_time.section = archive.current_section
packed_time.game_archive_id = archive.archive_id
packed_time.game_seconds_all = archive.game_seconds_all
packed_time.game_seconds_current = archive.game_seconds_current
# for log use
func get_concise_timemark() -> String:
var archive = ArchiveManager.archive
if not archive:
return "r0_c0_s0 00:00:00"
var hour = archive.game_seconds_current / 3600 as int
var minute = (archive.game_seconds_current % 3600) / 60 as int
var second = archive.game_seconds_current % 60
return (
"r"
+ str(ArchiveManager.current_archive_id)
+ "_c"
+ str(archive.current_chapter)
+ "_s"
+ str(archive.current_section)
+ " "
+ str(hour)
+ ":"
+ str(minute)
+ ":"
+ str(second)
)

View File

@ -1,10 +0,0 @@
extends Node
enum VIBE {
NORAML,
MYSTERY,
DANGEROUS,
TOUCHING,
}
# light and wind

View File

@ -33,16 +33,12 @@ buses/default_bus_layout="res://config/default_bus_layout.tres"
DebugMenu="*res://addons/debug_menu/debug_menu.tscn" DebugMenu="*res://addons/debug_menu/debug_menu.tscn"
GlobalConfigManager="*res://manager/config_manager/global_config_manager.gd" GlobalConfigManager="*res://manager/config_manager/global_config_manager.gd"
TimeManager="*res://manager/time_manager/time_manager.gd"
EntityManager="*res://manager/deploy/entity/entity_manager.gd"
SceneManager="*res://manager/deploy/scene/scene_manager.gd" SceneManager="*res://manager/deploy/scene/scene_manager.gd"
AudioManager="*res://manager/audio_manager/audio_manager.gd" AudioManager="*res://manager/audio_manager/audio_manager.gd"
EventManager="*res://manager/event_manager/event_manager.gd" EventManager="*res://manager/event_manager/event_manager.gd"
DialogManager="*res://manager/deploy/dialog/dialog_manager.gd" DialogManager="*res://manager/deploy/dialog/dialog_manager.gd"
CameraManager="*res://manager/camera_manager/camera_manager.gd"
CgManager="*res://manager/cg_manager/cg_manager.gd" CgManager="*res://manager/cg_manager/cg_manager.gd"
InputManager="*res://manager/input/input_manager.gd" InputManager="*res://manager/input/input_manager.gd"
VibeManager="*res://manager/vibe/vibe_manager.gd"
ArchiveManager="*res://manager/archive_manager/archive_manager.gd" ArchiveManager="*res://manager/archive_manager/archive_manager.gd"
[display] [display]
@ -120,6 +116,7 @@ cancel={
2d_physics/layer_1="player" 2d_physics/layer_1="player"
2d_physics/layer_2="wall" 2d_physics/layer_2="wall"
2d_physics/layer_3="interactable"
[rendering] [rendering]

View File

@ -3,8 +3,8 @@ extends Marker2D
@export var lock_horizontal = true @export var lock_horizontal = true
func tweak_position(velocity, facing_direction): func tweak_position(velocity, facing_direction):
position.x = facing_direction.x * abs(velocity.x) * 0.4 position.x = facing_direction.x * abs(velocity.x) * 0.3
if lock_horizontal: if lock_horizontal:
global_position.y = 0 global_position.y = 0
else: else:
position.y = facing_direction.y * abs(velocity.y) * 0.4 position.y = facing_direction.y * abs(velocity.y) * 0.3

View File

@ -16,15 +16,15 @@ func _ready():
func test(): func test():
# append_dialog("吕萍", "Hello, 2! very very long message, very very loooonnnggggggg!") # append_dialog("吕萍", "Hello, 2! very very long message, very very loooonnnggggggg!")
# append_note("Hello, 3!") append_note("Hello, 3!")
# append_note("Hello, blue!", "blue", 1) # append_note("Hello, blue!", "blue", 1)
# append_dialog("车夫", "你好!", "green") append_dialog("车夫", "你好!", "green")
pass pass
func append_note(note: String, note_color := "white", duration := 2.5) -> void: func append_note(note: String, note_color := "white", duration := 2.5) -> void:
pending_bbcode.append( pending_bbcode.append(
["[center][color=" + note_color + "]" + note + "[/color][/center]", duration] ["[center][color=" + note_color + "]" + note + "[/color][/center]", duration, false]
) )
_show() _show()
@ -36,6 +36,12 @@ func append_dialog(
content_color := "white", content_color := "white",
duration := 2.5 duration := 2.5
) -> void: ) -> void:
# remove non-dialog notifications
for _i in range(pending_bbcode.size()):
var triple = pending_bbcode.pop_front()
if not triple[2]:
continue
pending_bbcode.append(triple)
pending_bbcode.append( pending_bbcode.append(
[ [
( (
@ -49,7 +55,8 @@ func append_dialog(
+ content + content
+ "[/color][/center]" + "[/color][/center]"
), ),
duration duration,
true
] ]
) )
_show() _show()
@ -57,19 +64,24 @@ func append_dialog(
func _show() -> void: func _show() -> void:
if not tweening and pending_bbcode.size() > 0: if not tweening and pending_bbcode.size() > 0:
var tuple = pending_bbcode.pop_front() var triple = pending_bbcode.pop_front()
label.parse_bbcode(tuple[0]) label.parse_bbcode(triple[0])
if triple[2]:
label.add_theme_color_override("font_shadow_color", Color(0.2, 0.2, 0.2, 0.6))
else:
label.remove_theme_color_override("font_shadow_color")
tweening = true tweening = true
var tween = create_tween() var tween = create_tween()
# 0.5s to show the notification # 0.5s to show the notification
tween.tween_property(self, "modulate:a", 1, 0.2).set_trans(Tween.TRANS_CUBIC) tween.tween_property(self, "modulate:a", 1, 0.2).set_trans(Tween.TRANS_CUBIC)
# keep the notification # keep the notification
tween.tween_interval(max(tuple[1] - 0.4, 0)) tween.tween_interval(max(triple[1] - 0.4, 0))
# 0.5s to hide the notification # 0.5s to hide the notification
tween.tween_property(self, "modulate:a", 0, 0.2).set_trans(Tween.TRANS_CUBIC) tween.tween_property(self, "modulate:a", 0, 0.2).set_trans(Tween.TRANS_CUBIC)
# callback # callback
tween.tween_callback(_check_next) tween.tween_callback(_check_next)
func _check_next(): func _check_next():
tweening = false tweening = false
_show() _show()

View File

@ -25,6 +25,9 @@ layout_mode = 2
size_flags_horizontal = 4 size_flags_horizontal = 4
size_flags_vertical = 4 size_flags_vertical = 4
mouse_filter = 2 mouse_filter = 2
theme_override_colors/font_shadow_color = Color(0.174626, 0.174626, 0.174626, 1)
theme_override_constants/shadow_offset_y = 1
theme_override_constants/shadow_offset_x = 1
bbcode_enabled = true bbcode_enabled = true
text = " [center][b][color=orange]吕萍:[/color][/b]「你好呀」[/center]" text = " [center][b][color=orange]吕萍:[/color][/b]「你好呀」[/center]"
fit_content = true fit_content = true

View File

@ -6,14 +6,15 @@ extends Sprite2D
@export var entity_name: String = "" @export var entity_name: String = ""
@export var entity_title: String = "" @export var entity_title: String = ""
@export var inspection_texture: Texture2D @export var texture_cover: Texture2D
@export var inspection_note: String = "" @export var texture_note: Texture2D
@export_multiline var inspection_note: String = ""
@onready var sprite2d = %AnimatedSoundSprite2D as AnimatedSoundSprite2D @onready var sprite2d = %AnimatedSoundSprite2D as AnimatedSoundSprite2D
@onready var sign_mark = %Sign as Sprite2D @onready var sign_mark = %Sign as Sprite2D
@onready var area2d = %Area2D as Area2D @onready var area2d = %Area2D as Area2D
var listening = false var inspecting = false
func _ready() -> void: func _ready() -> void:
@ -28,15 +29,38 @@ func _ready() -> void:
func _on_interacted() -> void: func _on_interacted() -> void:
pass if not texture_cover or not texture_note:
push_error("entity/inspectable.gd: texture_cover or texture_note is not set")
return
if inspecting:
return
%Sfx.play()
# connect inspector quit signal
var inspector = SceneManager.get_inspector()
if inspector:
inspector.quit.connect(_on_quit_inspector)
if not texture_note:
texture_note = texture_cover
inspector.pop_inspection(texture_cover, texture_note, inspection_note)
inspecting = true
sign_mark.show_sign = false
func _on_quit_inspector():
var inspector = SceneManager.get_inspector()
if inspector:
# disconnect inspector quit signal
inspector.quit.disconnect(_on_quit_inspector)
inspecting = false
sign_mark.show_sign = true
func _on_cancel(_body = null): func _on_cancel(_body = null):
pass inspecting = false
func _reset(_body): func _reset(_body):
pass inspecting = false
# _reload() # _reload()

View File

@ -2,11 +2,11 @@
[ext_resource type="Script" path="res://scene/entity/inspectable.gd" id="1_0pc4s"] [ext_resource type="Script" path="res://scene/entity/inspectable.gd" id="1_0pc4s"]
[ext_resource type="Script" path="res://scene/entity/ux/sign.gd" id="2_fcru3"] [ext_resource type="Script" path="res://scene/entity/ux/sign.gd" id="2_fcru3"]
[ext_resource type="PackedScene" uid="uid://c85t6stvytvjn" path="res://scene/entity/ux/sfx.tscn" id="2_wrnix"]
[ext_resource type="Texture2D" uid="uid://dvg6wjwn1qxiv" path="res://asset/art/ui/action_mark/探索ui.png" id="3_s7dto"] [ext_resource type="Texture2D" uid="uid://dvg6wjwn1qxiv" path="res://asset/art/ui/action_mark/探索ui.png" id="3_s7dto"]
[ext_resource type="Texture2D" uid="uid://t526pexw4ng4" path="res://asset/art/neutral_point_light.webp" id="3_vbivp"] [ext_resource type="Texture2D" uid="uid://t526pexw4ng4" path="res://asset/art/neutral_point_light.webp" id="3_vbivp"]
[ext_resource type="Resource" uid="uid://d0wynwv8stclg" path="res://config/audio/action/action_book_open.tres" id="4_v1qpa"]
[ext_resource type="SpriteFrames" uid="uid://c3s8u4ifaucpj" path="res://config/animation/entity_sprite_frames.tres" id="7_njjhh"] [ext_resource type="SpriteFrames" uid="uid://c3s8u4ifaucpj" path="res://config/animation/entity_sprite_frames.tres" id="7_njjhh"]
[ext_resource type="Script" path="res://manager/deploy/entity/animated_sound_sprite_2d.gd" id="8_wntgt"] [ext_resource type="Script" path="res://scene/entity/ux/animated_sound_sprite_2d.gd" id="8_wntgt"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_4fuic"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_4fuic"]
resource_local_to_scene = true resource_local_to_scene = true
@ -15,6 +15,10 @@ size = Vector2(35, 70)
[node name="Inspectable" type="Sprite2D"] [node name="Inspectable" type="Sprite2D"]
script = ExtResource("1_0pc4s") script = ExtResource("1_0pc4s")
[node name="Sfx" parent="." instance=ExtResource("2_wrnix")]
unique_name_in_owner = true
file = "物品查看.mp3"
[node name="PointLight2D" type="PointLight2D" parent="."] [node name="PointLight2D" type="PointLight2D" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
position = Vector2(0, -35) position = Vector2(0, -35)
@ -25,11 +29,11 @@ texture_scale = 0.5
[node name="Sign" type="Sprite2D" parent="."] [node name="Sign" type="Sprite2D" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
position = Vector2(0, -52) modulate = Color(1, 1, 1, 0)
position = Vector2(0, -9)
scale = Vector2(0.2, 0.2) scale = Vector2(0.2, 0.2)
texture = ExtResource("3_s7dto") texture = ExtResource("3_s7dto")
script = ExtResource("2_fcru3") script = ExtResource("2_fcru3")
audio_collection = ExtResource("4_v1qpa")
[node name="AnimatedSoundSprite2D" type="AnimatedSprite2D" parent="."] [node name="AnimatedSoundSprite2D" type="AnimatedSprite2D" parent="."]
unique_name_in_owner = true unique_name_in_owner = true

View File

@ -0,0 +1,2 @@
extends StaticBody2D

View File

@ -0,0 +1,14 @@
[gd_scene load_steps=2 format=3 uid="uid://cw3q5pvciumil"]
[ext_resource type="Script" path="res://scene/entity/interactable.gd" id="1_6nrd3"]
[node name="Interactable" type="StaticBody2D"]
collision_layer = 4
collision_mask = 5
input_pickable = true
script = ExtResource("1_6nrd3")
[node name="Sprite2D" type="Sprite2D" parent="."]
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="."]
polygon = PackedVector2Array(-11, -18, -21, 2, -14, 23, 19, 19, 21, 0, 18, -20)

View File

@ -1,7 +1,9 @@
extends Marker2D extends Sprite2D
# @export var title := "" # @export var title := ""
@export var notes := [] as Array[String] @export var notes := [] as Array[String]
@export var dialogs := [] as Array[String]
@onready var sign_mark = %Sign as Sprite2D @onready var sign_mark = %Sign as Sprite2D
@onready var area2d = %Area2D as Area2D @onready var area2d = %Area2D as Area2D
@ -20,18 +22,21 @@ func _ready() -> void:
func _on_interacted() -> void: func _on_interacted() -> void:
if notes.is_empty(): if notes.is_empty():
return return
var note_time = notes.size() * 2.5 var note_time = notes.size() * 2.0
# 0.5s 内锁定播放 # 0.5s 内锁定播放
mutex.lock() mutex.lock()
if Time.get_ticks_msec() - played_time < note_time * 1000 + 500: if Time.get_ticks_msec() - played_time < note_time * 1000 + 500:
mutex.unlock()
return return
# show note # show note
played_time = Time.get_ticks_msec() played_time = Time.get_ticks_msec()
mutex.unlock() mutex.unlock()
%Sfx.play()
for note in notes: for note in notes:
SceneManager.pop_note(note, "white", 2.5) SceneManager.pop_note(note, "white", 2.0)
var player = SceneManager.get_player() var player = SceneManager.get_player()
player.check_note(note_time) # TODO note viewing animation
player.freeze_player(note_time, "")
func _on_cancel(_body = null): func _on_cancel(_body = null):

View File

@ -3,24 +3,28 @@
[ext_resource type="Script" path="res://scene/entity/note.gd" id="1_3igk8"] [ext_resource type="Script" path="res://scene/entity/note.gd" id="1_3igk8"]
[ext_resource type="Texture2D" uid="uid://dvg6wjwn1qxiv" path="res://asset/art/ui/action_mark/探索ui.png" id="1_eew1k"] [ext_resource type="Texture2D" uid="uid://dvg6wjwn1qxiv" path="res://asset/art/ui/action_mark/探索ui.png" id="1_eew1k"]
[ext_resource type="Script" path="res://scene/entity/ux/sign.gd" id="2_36okt"] [ext_resource type="Script" path="res://scene/entity/ux/sign.gd" id="2_36okt"]
[ext_resource type="PackedScene" uid="uid://c85t6stvytvjn" path="res://scene/entity/ux/sfx.tscn" id="2_qocmg"]
[ext_resource type="Texture2D" uid="uid://t526pexw4ng4" path="res://asset/art/neutral_point_light.webp" id="3_xb81s"] [ext_resource type="Texture2D" uid="uid://t526pexw4ng4" path="res://asset/art/neutral_point_light.webp" id="3_xb81s"]
[ext_resource type="Resource" uid="uid://d0wynwv8stclg" path="res://config/audio/action/action_book_open.tres" id="4_14cx5"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_k6och"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_k6och"]
resource_local_to_scene = true resource_local_to_scene = true
size = Vector2(40, 60) size = Vector2(40, 60)
[node name="Note" type="Marker2D"] [node name="Note" type="Sprite2D"]
script = ExtResource("1_3igk8") script = ExtResource("1_3igk8")
notes = Array[String](["(note)"]) notes = Array[String]([])
[node name="Sfx" parent="." instance=ExtResource("2_qocmg")]
unique_name_in_owner = true
file = "纸条.mp3"
[node name="Sign" type="Sprite2D" parent="."] [node name="Sign" type="Sprite2D" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
modulate = Color(1, 1, 1, 0)
position = Vector2(0, -3.8147e-06) position = Vector2(0, -3.8147e-06)
scale = Vector2(0.2, 0.2) scale = Vector2(0.2, 0.2)
texture = ExtResource("1_eew1k") texture = ExtResource("1_eew1k")
script = ExtResource("2_36okt") script = ExtResource("2_36okt")
audio_collection = ExtResource("4_14cx5")
[node name="PointLight2D" type="PointLight2D" parent="."] [node name="PointLight2D" type="PointLight2D" parent="."]
unique_name_in_owner = true unique_name_in_owner = true

View File

@ -19,6 +19,7 @@ func _ready() -> void:
func _on_interacted() -> void: func _on_interacted() -> void:
%Sfx.play()
print("npc interacted") print("npc interacted")

View File

@ -1,7 +1,8 @@
[gd_scene load_steps=12 format=3 uid="uid://0sofmhrl358m"] [gd_scene load_steps=13 format=3 uid="uid://0sofmhrl358m"]
[ext_resource type="Script" path="res://scene/entity/npc.gd" id="1_jegr2"] [ext_resource type="Script" path="res://scene/entity/npc.gd" id="1_jegr2"]
[ext_resource type="SpriteFrames" uid="uid://c3s8u4ifaucpj" path="res://config/animation/entity_sprite_frames.tres" id="3_1e8sl"] [ext_resource type="SpriteFrames" uid="uid://c3s8u4ifaucpj" path="res://config/animation/entity_sprite_frames.tres" id="3_1e8sl"]
[ext_resource type="PackedScene" uid="uid://c85t6stvytvjn" path="res://scene/entity/ux/sfx.tscn" id="3_4d53s"]
[ext_resource type="Script" path="res://scene/entity/ux/sign.gd" id="3_kgq8p"] [ext_resource type="Script" path="res://scene/entity/ux/sign.gd" id="3_kgq8p"]
[ext_resource type="Texture2D" uid="uid://t526pexw4ng4" path="res://asset/art/neutral_point_light.webp" id="4_jrmg5"] [ext_resource type="Texture2D" uid="uid://t526pexw4ng4" path="res://asset/art/neutral_point_light.webp" id="4_jrmg5"]
[ext_resource type="Texture2D" uid="uid://gb3p6ry0bs5x" path="res://asset/art/ui/action_mark/说话标识1.png" id="5_foitt"] [ext_resource type="Texture2D" uid="uid://gb3p6ry0bs5x" path="res://asset/art/ui/action_mark/说话标识1.png" id="5_foitt"]
@ -79,6 +80,9 @@ sprite_frames = ExtResource("3_1e8sl")
animation = &"c02_张胖子_idle" animation = &"c02_张胖子_idle"
script = ExtResource("1_jegr2") script = ExtResource("1_jegr2")
[node name="Sfx" parent="." instance=ExtResource("3_4d53s")]
unique_name_in_owner = true
[node name="SpeakingAnimationPlayer" type="AnimationPlayer" parent="."] [node name="SpeakingAnimationPlayer" type="AnimationPlayer" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
libraries = { libraries = {
@ -94,6 +98,7 @@ texture_scale = 0.1
[node name="Sign" type="Sprite2D" parent="."] [node name="Sign" type="Sprite2D" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
modulate = Color(1, 1, 1, 0)
script = ExtResource("3_kgq8p") script = ExtResource("3_kgq8p")
[node name="SpeakingSign2D" type="Node2D" parent="."] [node name="SpeakingSign2D" type="Node2D" parent="."]

31
scene/entity/pickable.gd Normal file
View File

@ -0,0 +1,31 @@
extends Sprite2D
# @export var title := ""
@export var entity_name := ""
@export var entity_title := ""
@export var inpect_texture: Texture2D
@export var hud_texture: Texture2D
@onready var sign_mark = %Sign as Sprite2D
@onready var area2d = %Area2D as Area2D
var played_time = 0
func _ready() -> void:
area2d.body_entered.connect(_reset)
area2d.body_exited.connect(_on_cancel)
sign_mark.interacted.connect(_on_interacted)
sign_mark.cancel.connect(_on_cancel)
func _on_interacted() -> void:
%Sfx.play()
# SceneManager.pop_inspect(entity_name, entity_title, inpect_texture, hud_texture)
func _on_cancel(_body = null):
pass
func _reset(_body):
pass

View File

@ -0,0 +1,40 @@
[gd_scene load_steps=7 format=3 uid="uid://dsa6frlw6e6gg"]
[ext_resource type="Script" path="res://scene/entity/pickable.gd" id="1_jk1u0"]
[ext_resource type="PackedScene" uid="uid://c85t6stvytvjn" path="res://scene/entity/ux/sfx.tscn" id="2_8s5wk"]
[ext_resource type="Texture2D" uid="uid://dvg6wjwn1qxiv" path="res://asset/art/ui/action_mark/探索ui.png" id="2_bggcm"]
[ext_resource type="Script" path="res://scene/entity/ux/sign.gd" id="3_hpbqf"]
[ext_resource type="Texture2D" uid="uid://t526pexw4ng4" path="res://asset/art/neutral_point_light.webp" id="5_yhysn"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_k6och"]
resource_local_to_scene = true
size = Vector2(40, 60)
[node name="Pickable" type="Sprite2D"]
script = ExtResource("1_jk1u0")
[node name="Sfx" parent="." instance=ExtResource("2_8s5wk")]
unique_name_in_owner = true
file = "令牌道具获取.wav"
[node name="Sign" type="Sprite2D" parent="."]
unique_name_in_owner = true
modulate = Color(1, 1, 1, 0)
position = Vector2(0, -3.8147e-06)
scale = Vector2(0.2, 0.2)
texture = ExtResource("2_bggcm")
script = ExtResource("3_hpbqf")
[node name="PointLight2D" type="PointLight2D" parent="."]
unique_name_in_owner = true
scale = Vector2(0.2, 0.2)
energy = 0.0
texture = ExtResource("5_yhysn")
texture_scale = 0.5
[node name="Area2D" type="Area2D" parent="."]
unique_name_in_owner = true
collision_layer = 0
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
shape = SubResource("RectangleShape2D_k6och")

View File

@ -10,14 +10,11 @@ extends Sprite2D
@export var target_scene := "c02_s00" @export var target_scene := "c02_s00"
@export_enum("none", "left", "right", "1", "2", "3", "4", "5", "6", "7", "8", "9") @export_enum("none", "left", "right", "1", "2", "3", "4", "5", "6", "7", "8", "9")
var target_portal := "none" var target_portal := "none"
@export_enum("door", "channel") var sound_effect := "door"
@onready var sign_mark = %Sign as Sprite2D @onready var sign_mark = %Sign as Sprite2D
@onready var area2d = %Area2D as Area2D @onready var area2d = %Area2D as Area2D
var sfx_door := preload("res://config/audio/action/action_door_open.tres")
var sfx_channel := preload("res://config/audio/action/action_book_open.tres")
var activated := false var activated := false
var action_times := 0 var action_times := 0
@ -29,15 +26,8 @@ func _ready() -> void:
area2d.body_exited.connect(_on_cancel) area2d.body_exited.connect(_on_cancel)
sign_mark.interacted.connect(_on_interacted) sign_mark.interacted.connect(_on_interacted)
sign_mark.cancel.connect(_on_cancel) sign_mark.cancel.connect(_on_cancel)
# sound effect
if sound_effect == "door":
sign_mark.audio_collection = sfx_door
elif sound_effect == "channel":
sign_mark.audio_collection = sfx_channel
# show or hide sign
if target_portal == "none": if target_portal == "none":
sign_mark.show_sign = false sign_mark.show_sign = false
# if GlobalConfig.DEBUG: # if GlobalConfig.DEBUG:
# var label = Label.new() # var label = Label.new()
# label.text = portal_name # label.text = portal_name
@ -49,6 +39,7 @@ func _on_interacted() -> void:
if target_portal == "none": if target_portal == "none":
return return
# 传送 # 传送
%Sfx.play()
if GlobalConfig.DEBUG: if GlobalConfig.DEBUG:
print("传送前往", target_scene, target_portal) print("传送前往", target_scene, target_portal)
var ground_loader = SceneManager.get_ground_loader() as GroundLoader var ground_loader = SceneManager.get_ground_loader() as GroundLoader
@ -75,8 +66,7 @@ func _input(event: InputEvent) -> void:
if action_times >= 7: if action_times >= 7:
activated = false activated = false
action_times = 0 action_times = 0
if sign_mark.random_audio_player: %Sfx.play()
sign_mark.random_audio_player.play_random()
_on_interacted() _on_interacted()
if portal_name == "right" and target_portal == "left": if portal_name == "right" and target_portal == "left":
if event.is_action("right"): if event.is_action("right"):
@ -86,6 +76,5 @@ func _input(event: InputEvent) -> void:
if action_times >= 7: if action_times >= 7:
activated = false activated = false
action_times = 0 action_times = 0
if sign_mark.random_audio_player: %Sfx.play()
sign_mark.random_audio_player.play_random()
_on_interacted() _on_interacted()

View File

@ -3,8 +3,8 @@
[ext_resource type="Script" path="res://scene/entity/portal.gd" id="1_jyh6v"] [ext_resource type="Script" path="res://scene/entity/portal.gd" id="1_jyh6v"]
[ext_resource type="Texture2D" uid="uid://dcafeofupga6j" path="res://asset/art/scene/c02/s06_院子回忆版/e_1014 开门.png" id="1_ynrqg"] [ext_resource type="Texture2D" uid="uid://dcafeofupga6j" path="res://asset/art/scene/c02/s06_院子回忆版/e_1014 开门.png" id="1_ynrqg"]
[ext_resource type="Texture2D" uid="uid://dbi1whlvfrt5k" path="res://asset/art/ui/action_mark/传送.png" id="2_ay30q"] [ext_resource type="Texture2D" uid="uid://dbi1whlvfrt5k" path="res://asset/art/ui/action_mark/传送.png" id="2_ay30q"]
[ext_resource type="PackedScene" uid="uid://c85t6stvytvjn" path="res://scene/entity/ux/sfx.tscn" id="3_6khux"]
[ext_resource type="Script" path="res://scene/entity/ux/sign.gd" id="4_lu5q5"] [ext_resource type="Script" path="res://scene/entity/ux/sign.gd" id="4_lu5q5"]
[ext_resource type="Resource" uid="uid://bbvtfv3xl1d6" path="res://config/audio/action/action_door_open.tres" id="5_7e0co"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_munml"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_munml"]
resource_local_to_scene = true resource_local_to_scene = true
@ -14,14 +14,17 @@ size = Vector2(45, 130)
texture = ExtResource("1_ynrqg") texture = ExtResource("1_ynrqg")
script = ExtResource("1_jyh6v") script = ExtResource("1_jyh6v")
[node name="Sfx" parent="." instance=ExtResource("3_6khux")]
unique_name_in_owner = true
file = "开门.mp3"
[node name="Sign" type="Sprite2D" parent="."] [node name="Sign" type="Sprite2D" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
modulate = Color(1, 1, 1, 0)
position = Vector2(0, -73) position = Vector2(0, -73)
scale = Vector2(0.05, 0.05) scale = Vector2(0.05, 0.05)
texture = ExtResource("2_ay30q") texture = ExtResource("2_ay30q")
script = ExtResource("4_lu5q5") script = ExtResource("4_lu5q5")
volume_db = -15.0
audio_collection = ExtResource("5_7e0co")
[node name="PointLight2D" type="PointLight2D" parent="."] [node name="PointLight2D" type="PointLight2D" parent="."]
unique_name_in_owner = true unique_name_in_owner = true

View File

@ -4,3 +4,4 @@ class_name AnimatedSoundSprite2D extends AnimatedSprite2D
func play_with_sound(animation_name: String) -> void: func play_with_sound(animation_name: String) -> void:
super.play(animation_name) super.play(animation_name)
AudioManager.play_animation_sound(animation_name) AudioManager.play_animation_sound(animation_name)

View File

@ -0,0 +1,2 @@
extends AnimationPlayer

View File

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://bpouwlfacjjdb"]
[ext_resource type="Script" path="res://scene/entity/ux/cg_event.gd" id="1_cugx1"]
[node name="CGEvent" type="AnimationPlayer"]
script = ExtResource("1_cugx1")

View File

@ -0,0 +1,2 @@
extends Node

View File

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://dyelo1dwkvlf"]
[ext_resource type="Script" path="res://scene/entity/ux/journal_event.gd" id="1_5w7ov"]
[node name="JournalEvent" type="Node"]
script = ExtResource("1_5w7ov")

89
scene/entity/ux/sfx.gd Normal file
View File

@ -0,0 +1,89 @@
@tool
extends Node
@export var volume_db := 0.0
@export_enum("child", "game/八音盒", "game/旋转锁", "ghost", "lvping", "ui", "c01", "c02") var dir := "ui":
set(value):
dir = value
_update_files()
#@export var file: String = "":
#set(val):
#if val and current_files.has(val):
#file = val
var file: String
var sfx_root_path = "res://asset/audio/sfx/"
var current_files := PackedStringArray()
var sfx: AudioStream
func _ready() -> void:
_update_files()
func _reload_sfx():
if file and dir:
sfx = load(sfx_root_path + dir + "/" + file) as AudioStream
else:
sfx = null
func _update_files():
current_files.clear()
if not dir:
return
var dir_access := DirAccess.open(sfx_root_path + dir) as DirAccess
for f in dir_access.get_files():
if f.ends_with(".wav") or f.ends_with(".ogg") or f.ends_with(".mp3"):
current_files.push_back(f)
#for d in dir_access.get_directories():
#var sub_dir_access := DirAccess.open(sfx_root_path + dir + "/" + d) as DirAccess
#for f in sub_dir_access.get_files():
#if f.ends_with(".wav") or f.ends_with(".ogg") or f.ends_with(".mp3"):
#current_files.push_back(d + "/" + f)
if current_files.is_empty():
file = ""
elif not file or not current_files.has(file):
file = current_files[0]
_reload_sfx()
notify_property_list_changed()
#func _property_can_revert(property: StringName) -> bool:
#if property == &"file":
#return true
#return false
#
#func _property_get_revert(property: StringName) -> Variant:
#if property == &"file":
#return ""
#return null
func _get_property_list():
return [
{
"name": &"file",
"type": TYPE_STRING,
"hint": PROPERTY_HINT_ENUM_SUGGESTION,
"hint_string": ",".join(current_files),
}
]
func _get(property: StringName) -> Variant:
if property == &"file":
return file
return null
func _set(property: StringName, value: Variant) -> bool:
if property == &"file":
file = value
_reload_sfx()
notify_property_list_changed()
return true
return false
func play() -> void:
if sfx:
AudioManager.play_sfx(sfx, volume_db)

7
scene/entity/ux/sfx.tscn Normal file
View File

@ -0,0 +1,7 @@
[gd_scene load_steps=2 format=3 uid="uid://c85t6stvytvjn"]
[ext_resource type="Script" path="res://scene/entity/ux/sfx.gd" id="1_ng32y"]
[node name="Sfx" type="Node"]
script = ExtResource("1_ng32y")
file = "click.wav"

View File

@ -1,4 +1,4 @@
# @tool @tool
extends Node2D extends Node2D
# @export var texture: Texture: # @export var texture: Texture:
@ -10,17 +10,6 @@ extends Node2D
# # base_scale = val # # base_scale = val
# # sprite2d.scale = base_scale # # sprite2d.scale = base_scale
@export var show_sign := true @export var show_sign := true
@export var volume_db := -5.0:
set(val):
volume_db = val
if random_audio_player:
random_audio_player.volume_db = volume_db
@export var audio_collection: AudioStreamCollection:
set(val):
audio_collection = val
if random_audio_player:
random_audio_player.audio_collections.clear()
random_audio_player.audio_collections.append(audio_collection)
signal interacted signal interacted
signal cancel signal cancel
@ -33,7 +22,6 @@ static var _pending_callables: Array[Callable]
var own_callable var own_callable
var activated = false var activated = false
var random_audio_player: RandomAudioStreamPlayer
# var sprite2d = Sprite2D.new() # var sprite2d = Sprite2D.new()
var base_scale = Vector2.ONE var base_scale = Vector2.ONE
@ -49,19 +37,8 @@ func _ready() -> void:
if area2d: if area2d:
area2d.body_entered.connect(activate) area2d.body_entered.connect(activate)
area2d.body_exited.connect(disactivate) area2d.body_exited.connect(disactivate)
# # add child if not Engine.is_editor_hint():
# add_child(sprite2d)
# sprite2d.modulate.a = 0
# if Engine.is_editor_hint():
# sprite2d.modulate.a = 1
# _load_sprite()
modulate.a = 0 modulate.a = 0
if audio_collection:
random_audio_player = RandomAudioStreamPlayer.new()
random_audio_player.audio_collections.append(audio_collection)
random_audio_player.bus = GlobalConfig.AUDIO_BUS_SFX
random_audio_player.volume_db = volume_db
add_child(random_audio_player)
# func _load_sprite() -> void: # func _load_sprite() -> void:
@ -104,8 +81,6 @@ func _input(event: InputEvent) -> void:
if activated: if activated:
if event.is_action_pressed("interact"): if event.is_action_pressed("interact"):
interacted.emit() interacted.emit()
if show_sign and random_audio_player:
random_audio_player.play_random()
elif event.is_action_pressed("cancel"): elif event.is_action_pressed("cancel"):
cancel.emit() cancel.emit()

View File

@ -1,6 +1,7 @@
@tool @tool
class_name GroundLoader extends Node2D class_name GroundLoader extends Node2D
@export var ignore_archive := false
@export var current_scene := "c02_s01" @export var current_scene := "c02_s01"
@export var entrance_portal := "left" @export var entrance_portal := "left"
@ -12,11 +13,13 @@ var ground_dict = {}
func _ready() -> void: func _ready() -> void:
if not ignore_archive:
_load_save() _load_save()
_read_grounds() _read_grounds()
if current_scene and entrance_portal: if current_scene and entrance_portal and not Engine.is_editor_hint():
transition_to_scene(current_scene, entrance_portal, true) transition_to_scene(current_scene, entrance_portal, true)
func _load_save(): func _load_save():
if ArchiveManager.archive: if ArchiveManager.archive:
if ArchiveManager.archive.current_scene: if ArchiveManager.archive.current_scene:
@ -24,6 +27,7 @@ func _load_save():
if ArchiveManager.archive.entrance_portal: if ArchiveManager.archive.entrance_portal:
entrance_portal = ArchiveManager.archive.entrance_portal entrance_portal = ArchiveManager.archive.entrance_portal
func _read_grounds(): func _read_grounds():
var dir = DirAccess.open(scenes_dir) var dir = DirAccess.open(scenes_dir)
for c_dir in dir.get_directories(): for c_dir in dir.get_directories():
@ -50,7 +54,7 @@ func transition_to_scene(key: String, portal: String, load_save := false) -> voi
# 更新玩家位置 # 更新玩家位置
_update_player_position() _update_player_position()
else: else:
var tween = create_tween() var tween = create_tween() as Tween
var player = SceneManager.get_player() as MainPlayer var player = SceneManager.get_player() as MainPlayer
if player: if player:
player.action_locked = true player.action_locked = true
@ -62,7 +66,10 @@ func transition_to_scene(key: String, portal: String, load_save := false) -> voi
else: else:
print("Scene not found: " + key) print("Scene not found: " + key)
func _update_player_position(): func _update_player_position():
if ignore_archive:
return
var player = SceneManager.get_player() as MainPlayer var player = SceneManager.get_player() as MainPlayer
if player and ArchiveManager.archive: if player and ArchiveManager.archive:
# if GlobalConfig.DEBUG: # if GlobalConfig.DEBUG:
@ -70,6 +77,7 @@ func _update_player_position():
player.global_position = ArchiveManager.archive.player_global_position player.global_position = ArchiveManager.archive.player_global_position
player.set_facing_direction(ArchiveManager.archive.player_direction) player.set_facing_direction(ArchiveManager.archive.player_direction)
func _do_transition(scene: Node2D): func _do_transition(scene: Node2D):
if ground: if ground:
ground.queue_free() ground.queue_free()
@ -78,16 +86,23 @@ func _do_transition(scene: Node2D):
ground = scene.get_child(0) ground = scene.get_child(0)
scene.remove_child(ground) scene.remove_child(ground)
scene.queue_free() scene.queue_free()
ground.owner = null
add_child(ground) add_child(ground)
ground.owner = self
ground.name = "Ground" ground.name = "Ground"
_set_camera_and_player_boundary() _set_camera_and_player_boundary()
_update_archive() _update_archive()
var portal_node = get_node_or_null("./Ground/DeployLayer/portal_" + entrance_portal) as Node2D var portal_node = get_node_or_null("./Ground/DeployLayer/portal_" + entrance_portal) as Node2D
if portal_node: if portal_node:
print("set player to portal:", entrance_portal) print("set player and camera to portal:", entrance_portal, portal_node.global_position)
var player = SceneManager.get_player() var player = SceneManager.get_player()
if player: if player:
player.global_position.x = portal_node.global_position.x player.global_position.x = portal_node.global_position.x
var camera = SceneManager.get_camera()
if camera:
camera.global_position.x = portal_node.global_position.x
if GlobalConfig.DEBUG:
_watch_scene_update()
func _set_camera_and_player_boundary(): func _set_camera_and_player_boundary():
@ -98,5 +113,40 @@ func _set_camera_and_player_boundary():
func _update_archive(): func _update_archive():
if ArchiveManager.archive:
ArchiveManager.archive.current_scene = current_scene ArchiveManager.archive.current_scene = current_scene
ArchiveManager.archive.entrance_portal = entrance_portal ArchiveManager.archive.entrance_portal = entrance_portal
var update_watcher: Timer
var last_modify = 0
func _watch_scene_update():
var scene_path = ground_dict[current_scene]
if scene_path:
last_modify = FileAccess.get_modified_time(scene_path)
if not update_watcher:
update_watcher = Timer.new()
update_watcher.wait_time = 1
update_watcher.one_shot = false
add_child(update_watcher)
update_watcher.start()
else:
# remove all connections
for c in update_watcher.timeout.get_connections():
update_watcher.timeout.disconnect(c.callable)
update_watcher.timeout.connect(_check_scene_update.bind(scene_path))
func _check_scene_update(scene_path):
var modify = FileAccess.get_modified_time(scene_path)
if modify != last_modify:
last_modify = modify
_on_resources_reload(scene_path)
func _on_resources_reload(res):
print("resources_reload processing:", res)
if res.ends_with(".tscn"):
ArchiveManager.save_all()
transition_to_scene(current_scene, entrance_portal, true)

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=7 format=3 uid="uid://bbs7yy5aofw1v"] [gd_scene load_steps=8 format=3 uid="uid://bbs7yy5aofw1v"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_gdcov"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_gdcov"]
[ext_resource type="Texture2D" uid="uid://kc4726andgy2" path="res://asset/art/scene/c02/s01_街道/bg_公寓入口.png" id="2_ni1a4"] [ext_resource type="Texture2D" uid="uid://kc4726andgy2" path="res://asset/art/scene/c02/s01_街道/bg_公寓入口.png" id="2_ni1a4"]
@ -7,6 +7,10 @@
[ext_resource type="PackedScene" uid="uid://wyj4qdjyn4ql" path="res://scene/entity/inspectable.tscn" id="5_g5fsn"] [ext_resource type="PackedScene" uid="uid://wyj4qdjyn4ql" path="res://scene/entity/inspectable.tscn" id="5_g5fsn"]
[ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="6_vgxa0"] [ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="6_vgxa0"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_dmp2c"]
resource_local_to_scene = true
size = Vector2(45, 130)
[node name="S01" type="Node2D"] [node name="S01" type="Node2D"]
[node name="Ground" parent="." instance=ExtResource("1_gdcov")] [node name="Ground" parent="." instance=ExtResource("1_gdcov")]
@ -16,7 +20,7 @@ texture = ExtResource("2_ni1a4")
[node name="Note" parent="Ground/DeployLayer" index="0" instance=ExtResource("3_6lnxd")] [node name="Note" parent="Ground/DeployLayer" index="0" instance=ExtResource("3_6lnxd")]
position = Vector2(250, -22) position = Vector2(250, -22)
notes = Array[String](["(门牌号: 1012)", "(似乎是用血来写的)"]) notes = Array[String](["(似乎是一张寻人启示)", "(脸的部分被撕掉了,打不开)"])
[node name="PortalL" parent="Ground/DeployLayer" index="1" instance=ExtResource("4_i5pa0")] [node name="PortalL" parent="Ground/DeployLayer" index="1" instance=ExtResource("4_i5pa0")]
position = Vector2(68, 23) position = Vector2(68, 23)
@ -30,7 +34,12 @@ texture = null
portal_name = "1" portal_name = "1"
target_scene = "c02_s02" target_scene = "c02_s02"
target_portal = "left" target_portal = "left"
sound_effect = "channel"
[node name="Sfx" parent="Ground/DeployLayer/Portal" index="0"]
file = "页面转换声.wav"
[node name="CollisionShape2D" parent="Ground/DeployLayer/Portal/Area2D" index="0"]
shape = SubResource("RectangleShape2D_dmp2c")
[node name="Inspectable" parent="Ground/DeployLayer" index="3" instance=ExtResource("5_g5fsn")] [node name="Inspectable" parent="Ground/DeployLayer" index="3" instance=ExtResource("5_g5fsn")]
position = Vector2(311, -7) position = Vector2(311, -7)
@ -42,3 +51,4 @@ position = Vector2(135, 56)
texture = null texture = null
[editable path="Ground"] [editable path="Ground"]
[editable path="Ground/DeployLayer/Portal"]

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=9 format=3 uid="uid://brck77w81fhvc"] [gd_scene load_steps=10 format=3 uid="uid://brck77w81fhvc"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_wrr6r"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_wrr6r"]
[ext_resource type="Texture2D" uid="uid://c4647gof464ws" path="res://asset/art/scene/c02/s02_走道/bg_过道.png" id="2_cn1s8"] [ext_resource type="Texture2D" uid="uid://c4647gof464ws" path="res://asset/art/scene/c02/s02_走道/bg_过道.png" id="2_cn1s8"]
@ -8,6 +8,10 @@
[ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="6_70vqn"] [ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="6_70vqn"]
[ext_resource type="Texture2D" uid="uid://dd0sn5e4hwq5m" path="res://asset/art/scene/c02/s02_走道/e_纸人.png" id="7_xsghn"] [ext_resource type="Texture2D" uid="uid://dd0sn5e4hwq5m" path="res://asset/art/scene/c02/s02_走道/e_纸人.png" id="7_xsghn"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_vj0ag"]
resource_local_to_scene = true
size = Vector2(45, 130)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_0xrg2"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_0xrg2"]
size = Vector2(40, 150) size = Vector2(40, 150)
@ -18,9 +22,9 @@ size = Vector2(40, 150)
[node name="BGSprite2D" parent="Ground" index="0"] [node name="BGSprite2D" parent="Ground" index="0"]
texture = ExtResource("2_cn1s8") texture = ExtResource("2_cn1s8")
[node name="Note" parent="Ground/DeployLayer" index="0" instance=ExtResource("3_fy0o1")] [node name="几张卫生宣传画" parent="Ground/DeployLayer" index="0" instance=ExtResource("3_fy0o1")]
position = Vector2(506, 74) position = Vector2(275, -30)
notes = Array[String](["(门牌号: 1012)", "(似乎是用血来写的)"]) notes = Array[String](["(几张卫生宣传画)"])
[node name="Portal" parent="Ground/DeployLayer" index="1" instance=ExtResource("4_vwh5u")] [node name="Portal" parent="Ground/DeployLayer" index="1" instance=ExtResource("4_vwh5u")]
position = Vector2(18, 54) position = Vector2(18, 54)
@ -34,11 +38,22 @@ texture = null
portal_name = "right" portal_name = "right"
target_scene = "c02_s03" target_scene = "c02_s03"
target_portal = "left" target_portal = "left"
sound_effect = "channel"
[node name="Sfx" parent="Ground/DeployLayer/Portal2" index="0"]
file = "页面转换声.wav"
[node name="CollisionShape2D" parent="Ground/DeployLayer/Portal2/Area2D" index="0"]
shape = SubResource("RectangleShape2D_vj0ag")
[node name="鼠疫海报" parent="Ground/DeployLayer" index="3" instance=ExtResource("5_nhtbp")] [node name="鼠疫海报" parent="Ground/DeployLayer" index="3" instance=ExtResource("5_nhtbp")]
position = Vector2(277, -6) position = Vector2(441, -20)
flip_h = true flip_h = true
entity_title = "(鼠疫海报)"
inspection_note = "据闻奉贤县分水墩又有七人染受鼠疫,病状可怖,闻医官药治无用,免职。
有地方人称鼠疫为妖邪作祟,甚为惊骇,一时人心惶惶,竟有聚众滋闹之事,政府以防疫事宜关系紧要,拟赴分水墩一带调查防疫事宜云。
《申报》
民国五年一月十三日"
[node name="纸人" parent="Ground/DeployLayer" index="4" instance=ExtResource("5_nhtbp")] [node name="纸人" parent="Ground/DeployLayer" index="4" instance=ExtResource("5_nhtbp")]
position = Vector2(601, 44) position = Vector2(601, 44)
@ -60,3 +75,4 @@ hook_cg = "c02_胖子说话"
texture = null texture = null
[editable path="Ground"] [editable path="Ground"]
[editable path="Ground/DeployLayer/Portal2"]

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=7 format=3 uid="uid://djc2uaefhmu7"] [gd_scene load_steps=9 format=3 uid="uid://djc2uaefhmu7"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_lheeb"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_lheeb"]
[ext_resource type="PackedScene" uid="uid://0sofmhrl358m" path="res://scene/entity/npc.tscn" id="2_r5smg"] [ext_resource type="PackedScene" uid="uid://0sofmhrl358m" path="res://scene/entity/npc.tscn" id="2_r5smg"]
@ -6,6 +6,11 @@
[ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="4_gvtrn"] [ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="4_gvtrn"]
[ext_resource type="PackedScene" uid="uid://wyj4qdjyn4ql" path="res://scene/entity/inspectable.tscn" id="5_0xh53"] [ext_resource type="PackedScene" uid="uid://wyj4qdjyn4ql" path="res://scene/entity/inspectable.tscn" id="5_0xh53"]
[ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="6_gg4jv"] [ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="6_gg4jv"]
[ext_resource type="Texture2D" uid="uid://0yip10ue5r4x" path="res://asset/art/scene/c02/s04_院子现实版/fg_楼梯.png" id="7_icddm"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_ik5u6"]
resource_local_to_scene = true
size = Vector2(45, 130)
[node name="S03" type="Node2D"] [node name="S03" type="Node2D"]
@ -24,7 +29,12 @@ scale = Vector2(1.02941, 1.06667)
texture = null texture = null
target_scene = "c02_s02" target_scene = "c02_s02"
target_portal = "right" target_portal = "right"
sound_effect = "channel"
[node name="Sfx" parent="Ground/DeployLayer/Portal" index="0"]
file = "页面转换声.wav"
[node name="CollisionShape2D" parent="Ground/DeployLayer/Portal/Area2D" index="0"]
shape = SubResource("RectangleShape2D_ik5u6")
[node name="Portal2" parent="Ground/DeployLayer" index="3" instance=ExtResource("4_gvtrn")] [node name="Portal2" parent="Ground/DeployLayer" index="3" instance=ExtResource("4_gvtrn")]
position = Vector2(192, 8) position = Vector2(192, 8)
@ -40,4 +50,14 @@ position = Vector2(376, 36)
position = Vector2(567, 28) position = Vector2(567, 28)
hook_cg = "c02_胖子说话" hook_cg = "c02_胖子说话"
[node name="楼梯" type="Sprite2D" parent="Ground/ParallaxForeground/BGParallaxLayer" index="0"]
position = Vector2(1250, 2)
scale = Vector2(1.05, 1.05)
texture = ExtResource("7_icddm")
[node name="FGSprite2D" parent="Ground/ParallaxForeground/FGParallaxLayer" index="0"]
position = Vector2(-12, -143)
scale = Vector2(1.08, 1.08)
[editable path="Ground"] [editable path="Ground"]
[editable path="Ground/DeployLayer/Portal"]

View File

@ -5,7 +5,7 @@
[ext_resource type="PackedScene" uid="uid://dmkt1roqc4he7" path="res://scene/dialog/dialog.tscn" id="3_prpss"] [ext_resource type="PackedScene" uid="uid://dmkt1roqc4he7" path="res://scene/dialog/dialog.tscn" id="3_prpss"]
[ext_resource type="PackedScene" uid="uid://dc778gsjfr3ky" path="res://scene/hud/prop_hud.tscn" id="4_t7gb2"] [ext_resource type="PackedScene" uid="uid://dc778gsjfr3ky" path="res://scene/hud/prop_hud.tscn" id="4_t7gb2"]
[ext_resource type="PackedScene" uid="uid://5g07x6q7wwr1" path="res://scene/notification/notification.tscn" id="5_3gg5t"] [ext_resource type="PackedScene" uid="uid://5g07x6q7wwr1" path="res://scene/notification/notification.tscn" id="5_3gg5t"]
[ext_resource type="PackedScene" uid="uid://cekhj65axie0p" path="res://scene/popup/prop_inspector_2d.tscn" id="5_ux0rw"] [ext_resource type="PackedScene" uid="uid://cekhj65axie0p" path="res://scene/popup/prop_inspector.tscn" id="5_ux0rw"]
[ext_resource type="PackedScene" uid="uid://cjhw5ecygrqty" path="res://scene/player/main_player.tscn" id="6_6geb0"] [ext_resource type="PackedScene" uid="uid://cjhw5ecygrqty" path="res://scene/player/main_player.tscn" id="6_6geb0"]
[ext_resource type="PackedScene" uid="uid://cqkeegrcdjyg4" path="res://scene/camera/camera_focus_marker.tscn" id="7_n7qcv"] [ext_resource type="PackedScene" uid="uid://cqkeegrcdjyg4" path="res://scene/camera/camera_focus_marker.tscn" id="7_n7qcv"]
[ext_resource type="PackedScene" uid="uid://ogyvstscr0kx" path="res://scene/camera/main_camera.tscn" id="8_nj084"] [ext_resource type="PackedScene" uid="uid://ogyvstscr0kx" path="res://scene/camera/main_camera.tscn" id="8_nj084"]
@ -33,9 +33,11 @@ metadata/_edit_use_anchors_ = true
[node name="Notification" parent="UILayer" instance=ExtResource("5_3gg5t")] [node name="Notification" parent="UILayer" instance=ExtResource("5_3gg5t")]
metadata/_edit_use_anchors_ = true metadata/_edit_use_anchors_ = true
[node name="VignetteShading" parent="." instance=ExtResource("2_d1re1")] [node name="PropInspector" parent="." instance=ExtResource("5_ux0rw")]
unique_name_in_owner = true
layer = 98
[node name="PropInspector2D" parent="." instance=ExtResource("5_ux0rw")] [node name="VignetteShading" parent="." instance=ExtResource("2_d1re1")]
[node name="MainPlayer" parent="." instance=ExtResource("6_6geb0")] [node name="MainPlayer" parent="." instance=ExtResource("6_6geb0")]
unique_name_in_owner = true unique_name_in_owner = true

Some files were not shown because too many files have changed in this diff Show More