优化场景内部数据存储过程

This commit is contained in:
cakipaul 2025-01-14 08:56:51 +08:00
parent adab1e536d
commit b3d398af1a
34 changed files with 749 additions and 642 deletions

Binary file not shown.

BIN
asset/art/ui/对话框.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1000 B

View File

@ -7,8 +7,8 @@
=> END
~ PropItems
# texture 路径从 "res://asset/art/prop/" 之后算起
空手 [ID:prop_空手]
# texture 路径从 "res://asset/art/prop/" 之后算起
# c01
令牌 [#texture=c01/令牌物品.png][#inspect=c01/令牌.png] [ID:prop_令牌]
装有灵魂的令牌 [#texture=c01/装有灵魂的令牌物品.png][#inspect=c01/装有灵魂的令牌.png] [ID:prop_装有灵魂的令牌]

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
[gd_scene load_steps=3 format=3 uid="uid://5d6o5k30wsnc"]
[ext_resource type="Script" path="res://config/animation/frames_display_card.gd" id="1_8ollf"]
[ext_resource type="SpriteFrames" uid="uid://c3s8u4ifaucpj" path="res://config/animation/entity_sprite_frames.tres" id="2_4hiuy"]
[ext_resource type="SpriteFrames" path="res://config/animation/entity_sprite_frames.tres" id="2_4hiuy"]
[node name="FramesDisplayCard" type="VBoxContainer"]
offset_right = 103.0

View File

@ -1,30 +0,0 @@
class_name AssembledArchive extends Resource
@export var archive_id := 0
@export var current_scene := ""
@export var entrance_portal := ""
@export var player_global_position := Vector2(0, 0)
@export var player_direction := Vector2(0, 0)
@export var current_chapter := 0
@export var current_section := 0
@export var game_seconds_all := 0
@export var game_seconds_current := 0
@export var created_time := "2024-12-24 00:00:00"
@export var ambush_data := {}
# true 为匿名false 非匿名
@export var npc_anonymous_states := {
}
@export var prop_inventory: PropInventory
@export_group("八音盒", "bayinhe")
@export var bayinhe_current_answer := [0, 0, 0, 0, 0, 0, 0, 0, 0]
@export_enum("closed", "opened", "playing", "finished") var bayinhe_mode := "closed"
func _init() -> void:
if not prop_inventory:
prop_inventory = PropInventory.new()

View File

@ -97,6 +97,7 @@ func _check_dirs_and_archives() -> bool:
_handle_load_error("存档目录", "读取")
# TODO pop up a dialog to inform the user
return false
archives.clear()
var files = archive_dir_access.get_files()
# get archive number
for file in files:

View File

@ -0,0 +1,52 @@
class_name AssembledArchive extends Resource
@export var archive_id := 0
@export var entrance_portal := ""
@export var current_scene := "":
set(val):
current_scene = val
if val and val.length() == 7:
current_chapter = int(val.substr(1, 2))
current_section = int(val.substr(5))
# current_chapter and current_section are derived from current_scene
@export var current_chapter := 0
@export var current_section := 0
# player's info
@export var player_global_position := Vector2(0, 0)
@export var player_direction := Vector2(0, 0)
# game total seconds
@export var game_seconds_all := 0
@export var game_seconds_current := 0
# created time
@export var created_time := "2024-12-24 00:00:00"
# 不同场景的地面物品状态存档
@export var ground_archives = {}
# true 为匿名false 非匿名
@export var npc_anonymous_states = {}
# prop hud 显示道具
@export var prop_inventory: PropInventory
@export_group("八音盒", "bayinhe")
@export var bayinhe_current_answer := [0, 0, 0, 0, 0, 0, 0, 0, 0]
@export_enum("closed", "opened", "playing", "finished") var bayinhe_mode := "closed"
func _init() -> void:
if not prop_inventory:
prop_inventory = PropInventory.new()
func ground_archive(scene_name := current_scene) -> GroundArchive:
if not scene_name:
printerr("getting GroundArchive: scene_name is null")
return null
if not ground_archives.has(scene_name):
var g = GroundArchive.new()
g.scene_name = scene_name
ground_archives[scene_name] = g
# # 保存新建的 GroundArchive
# ArchiveManager.save_all()
return ground_archives[scene_name]

View File

@ -0,0 +1,31 @@
class_name GroundArchive extends Resource
@export var scene_name := ""
# node_name -> dictionary
@export var _data := {}
func set_data(name: String, data: Dictionary) -> void:
_data[name] = data
func set_pair(name: String, key: String, val: Variant) -> void:
if _data.has(name):
_data[name][key] = val
else:
_data[name] = {key: val}
func get_data(name: String) -> Dictionary:
if _data.has(name):
return _data[name]
_data[name] = {}
return {}
func get_value(name: String, key: String, default = null) -> Variant:
if _data.has(name):
var data = _data[name]
if data.has(key):
return data[key]
return default

View File

@ -13,7 +13,7 @@ func get_camera_marker():
func get_player() -> MainPlayer:
return get_node_or_null("/root/Main/MainPlayer") as MainPlayer
return get_node_or_null("/root/Main/GroundLoader/Ground/MainPlayer") as MainPlayer
func get_prop_hud() -> PropHud:
@ -118,10 +118,12 @@ func focus_nodepath(node_path: NodePath) -> void:
var camera_remote_transformer: RemoteTransform2D
var focus_mutex := Mutex.new()
func focus_node(node: CanvasItem) -> void:
var rt := node.get_node_or_null("./camera_remote_transformer") as RemoteTransform2D
focus_mutex.lock()
if rt:
if camera_remote_transformer and rt != camera_remote_transformer:
camera_remote_transformer.queue_free()
@ -132,6 +134,7 @@ func focus_node(node: CanvasItem) -> void:
camera_remote_transformer = RemoteTransform2D.new()
node.add_child(camera_remote_transformer)
_setup_camera_remote_transformer()
focus_mutex.unlock()
func _setup_camera_remote_transformer():
@ -144,8 +147,9 @@ func _setup_camera_remote_transformer():
camera_remote_transformer.name = "camera_remote_transformer"
func focus_player() -> void:
var player = get_player()
func focus_player(player: MainPlayer = null) -> void:
if not player:
player = get_player()
if player:
focus_node(player)
else:

View File

@ -24,58 +24,43 @@ var dialogue_c02 = preload("res://asset/dialogue/c02.dialogue")
var dialogue_res = dialogue_c01
var played_time := 0.0
var played := false:
set(val):
played = val
_save_archive()
# var played := false:
# set(val):
# if played != val and ground_archive:
# ground_archive.set_pair(name, "played", played)
# played = val
@onready var area2d = %Area2D as Area2D
@onready var ground_archive := ArchiveManager.archive.ground_archive()
@onready var played = ground_archive.get_value(name, "played", false):
set(val):
played = val
ground_archive.set_pair(name, "played", played)
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
if Engine.is_editor_hint():
return
_load_archive()
if one_shot and played:
if GlobalConfig.DEBUG:
print("Ambush already played, key=", _get_key())
print("Ambush already played, name=", name)
return
area2d.body_entered.connect(_entered)
func _get_key() -> String:
var ground_loader = get_node_or_null("../../..") as GroundLoader
if ground_loader:
return ground_loader.current_scene + "_" + name
return name
func _save_archive():
if Engine.is_editor_hint():
return
ArchiveManager.archive.ambush_data[_get_key()] = {"played": played}
func _load_archive():
if Engine.is_editor_hint():
return
var key = _get_key()
if ArchiveManager.archive.ambush_data.has(key):
var data = ArchiveManager.archive.ambush_data[key]
if data.has("played"):
played = data.played
func _entered(_body):
if not one_shot:
var time = Time.get_ticks_msec()
if not one_shot:
var time_left = freeze_time - (time - played_time) * 0.001
if time_left > 0:
if GlobalConfig.DEBUG:
print("Ambush freeze time not reached, time left=", time_left)
return
elif played:
return
played_time = time
played = true
# hook_animation
if hook_animation:
$AnimationPlayer.play(hook_animation)
@ -85,9 +70,8 @@ func _entered(_body):
SceneManager.freeze_player(0.0, "")
DialogueManager.show_dialogue_balloon(dialogue_res, hook_dialogue_title)
DialogueManager.dialogue_ended.connect(_on_dialogue_ended, CONNECT_ONE_SHOT)
if one_shot:
played = true
player_entered.emit()
if GlobalConfig.DEBUG:
print("ambush body_entered!")

View File

@ -5,7 +5,7 @@
[ext_resource type="AudioStream" uid="uid://csdwhc83jshd3" path="res://asset/audio/sfx/ui/纸条.mp3" id="3_3ldx7"]
[ext_resource type="Texture2D" uid="uid://t526pexw4ng4" path="res://asset/art/tool/neutral_point_light.webp" id="3_o562w"]
[ext_resource type="PackedScene" uid="uid://c4tipnj1cr1j3" path="res://scene/entity/ux/sign.tscn" id="4_do8tr"]
[ext_resource type="SpriteFrames" uid="uid://c3s8u4ifaucpj" path="res://config/animation/entity_sprite_frames.tres" id="6_e77p4"]
[ext_resource type="SpriteFrames" uid="uid://bvypjkvdwysx8" path="res://config/animation/entity_sprite_frames.tres" id="6_e77p4"]
[ext_resource type="Script" path="res://scene/entity/ux/animated_sound_sprite_2d.gd" id="7_bhwlx"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_4fuic"]

View File

@ -1,7 +1,7 @@
[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="SpriteFrames" uid="uid://c3s8u4ifaucpj" path="res://config/animation/entity_sprite_frames.tres" id="3_1e8sl"]
[ext_resource type="SpriteFrames" 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="Texture2D" uid="uid://t526pexw4ng4" path="res://asset/art/tool/neutral_point_light.webp" id="4_jrmg5"]
[ext_resource type="PackedScene" uid="uid://c4tipnj1cr1j3" path="res://scene/entity/ux/sign.tscn" id="4_nokx4"]

View File

@ -5,7 +5,7 @@
[ext_resource type="AudioStream" uid="uid://b1fu8x6yonjgx" path="res://asset/audio/sfx/ui/物品查看.mp3" id="3_kilnm"]
[ext_resource type="Texture2D" uid="uid://t526pexw4ng4" path="res://asset/art/tool/neutral_point_light.webp" id="3_vbivp"]
[ext_resource type="PackedScene" uid="uid://c4tipnj1cr1j3" path="res://scene/entity/ux/sign.tscn" id="4_1yty8"]
[ext_resource type="SpriteFrames" uid="uid://c3s8u4ifaucpj" path="res://config/animation/entity_sprite_frames.tres" id="7_njjhh"]
[ext_resource type="SpriteFrames" uid="uid://bvypjkvdwysx8" path="res://config/animation/entity_sprite_frames.tres" id="7_njjhh"]
[ext_resource type="Script" path="res://scene/entity/ux/animated_sound_sprite_2d.gd" id="8_wntgt"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_4fuic"]

View File

@ -20,6 +20,7 @@ var target_portal := "none"
if is_node_ready():
_checkout_texture()
@onready var sfx = %Sfx as Sfx
@onready var sign_mark = %Sign as Sign
@onready var area2d = %Area2D as Area2D
@ -54,8 +55,8 @@ func _checkout_texture():
func _on_interacted() -> void:
if target_portal == "none":
return
# 传送
%Sfx.play()
# 传送queue free 导致 sfx 无法播放,使用全局声源
sfx.global_play()
if GlobalConfig.DEBUG:
print("传送前往", target_scene, target_portal)
var ground_loader = SceneManager.get_ground_loader() as GroundLoader

View File

@ -20,9 +20,9 @@ file = "页面转换声.wav"
[node name="Sign" parent="." instance=ExtResource("4_ty1ds")]
unique_name_in_owner = true
offset_top = -67.5
offset_top = -47.0
offset_right = 347.0
offset_bottom = 266.5
offset_bottom = 287.0
scale = Vector2(0.05, 0.05)
[node name="Sprite2D" parent="Sign/TextureContainer" index="0"]

View File

@ -21,6 +21,7 @@ func _ready() -> void:
_update_files()
bus = &"game_sfx"
func _reload_sfx():
if file and dir:
# print("reload sfx", sfx_root_path + dir + "/" + file)
@ -90,3 +91,8 @@ func _set(property: StringName, value: Variant) -> bool:
# func play() -> void:
# if sfx:
# AudioManager.play_sfx(sfx, volume_db)
# queue free 导致 sfx 无法播放,使用全局声源
func global_play() -> void:
if sfx:
AudioManager.play_sfx(sfx)

View File

@ -3,7 +3,11 @@ class_name Ground2D extends Node2D
@export_group("Player", "player_")
@export var player_y_fixed := true
@export var player_y := 45
@export var player_y := 45:
set(val):
player_y = val
if is_node_ready():
player.position.y = player_y
@export_group("Sound")
@export_enum("none", "ghost", "walking", "running", "crawling", "concrete")
var footstep_type: String = "concrete":
@ -12,11 +16,11 @@ var footstep_type: String = "concrete":
if is_node_ready():
_load_footstep_audio()
@onready var player = %MainPlayer as MainPlayer
@onready var directional_light := %DirectionalLight2D as DirectionalLight2D
@onready var foreground = %ParallaxForeground as ParallaxBackground
var footstep_audio = RandomAudioStreamPlayer.new()
@onready var footstep_audio = %FootstepAudioPlayer as RandomAudioStreamPlayer
const FOOTSTEP_AUDIO = {
#"wood": preload("res://config/audio/footstep/footstep_wood.tres"),
@ -33,10 +37,12 @@ const FOOTSTEP_AUDIO = {
func _ready() -> void:
foreground.layer = GlobalConfig.CANVAS_LAYER_FG
player.position.y = player_y
if Engine.is_editor_hint():
return
_load_footstep_audio()
# %ColorRectTop.visible = true
# %ColorRectBottom.visible = true
add_child(footstep_audio)
_load_footstep_audio()
func _load_footstep_audio():

View File

@ -1,7 +1,9 @@
[gd_scene load_steps=5 format=3 uid="uid://dayyx4jerj7io"]
[gd_scene load_steps=7 format=3 uid="uid://dayyx4jerj7io"]
[ext_resource type="Script" path="res://scene/ground/ground.gd" id="1_0vrlo"]
[ext_resource type="PackedScene" uid="uid://cjhw5ecygrqty" path="res://scene/player/main_player.tscn" id="3_atha7"]
[ext_resource type="PackedScene" uid="uid://61pis75a8fdq" path="res://scene/entity/portal.tscn" id="3_t73yw"]
[ext_resource type="Script" path="res://config/audio/random_audio_stream_player.gd" id="5_7mb2q"]
[ext_resource type="Texture2D" uid="uid://by8h2yuqve7fw" path="res://asset/art/scene/c02/s06_院子回忆版/fg_有人.png" id="5_i5hii"]
[sub_resource type="GDScript" id="GDScript_qxugl"]
@ -46,6 +48,10 @@ portal_name = "right"
[node name="AmbientLayer" type="Node2D" parent="."]
[node name="MainPlayer" parent="." instance=ExtResource("3_atha7")]
unique_name_in_owner = true
position = Vector2(2, 45)
[node name="ParallaxForeground" type="ParallaxBackground" parent="."]
unique_name_in_owner = true
layer = 2
@ -84,3 +90,7 @@ range_layer_max = 2
shadow_enabled = true
shadow_color = Color(0.333333, 0.333333, 0.333333, 0.34902)
height = 0.5
[node name="FootstepAudioPlayer" type="AudioStreamPlayer" parent="."]
unique_name_in_owner = true
script = ExtResource("5_7mb2q")

View File

@ -37,15 +37,8 @@ func _ready() -> void:
ground = null
func _load_save():
if not Engine.is_editor_hint() and ArchiveManager.archive:
if ArchiveManager.archive.current_scene:
archive_scene = ArchiveManager.archive.current_scene
if ArchiveManager.archive.entrance_portal:
archive_portal = ArchiveManager.archive.entrance_portal
func _read_grounds():
func _read_grounds() -> void:
# read grounds
var dir = DirAccess.open(scenes_dir)
for c_dir in dir.get_directories():
var c_path = scenes_dir + c_dir + "/"
@ -53,6 +46,19 @@ func _read_grounds():
if s_file.ends_with(".tscn"):
var s_path = c_path + s_file
ground_dict[c_dir.substr(0, 3) + "_" + s_file.substr(0, 3)] = s_path
# # 确保每个 ground 都初始化 archive
# for key in ground_dict.keys():
# if GlobalConfig.DEBUG:
# print("check ground_archive:", key)
# ArchiveManager.archive.ground_archive(key)
func _load_save():
if not Engine.is_editor_hint() and ArchiveManager.archive:
if ArchiveManager.archive.current_scene:
archive_scene = ArchiveManager.archive.current_scene
if ArchiveManager.archive.entrance_portal:
archive_portal = ArchiveManager.archive.entrance_portal
func play_footstep_sound() -> void:
@ -66,6 +72,8 @@ func transition_to_scene(key: String, portal: String, immediately := false) -> v
var scene = load(scene_path).instantiate()
current_scene = key
entrance_portal = portal
# 优先更新 archive使 ground 可以访问自己的 current_scene 键值
_update_archive()
if immediately:
_do_transition(scene)
# 更新玩家位置
@ -80,6 +88,7 @@ func transition_to_scene(key: String, portal: String, immediately := false) -> v
#
tween.tween_interval(0.2)
tween.tween_callback(_do_transition.bind(scene))
if player:
tween.tween_callback(func(): player.action_locked = false)
first_entered = false
else:
@ -112,9 +121,9 @@ func _do_transition(scene: Node2D):
add_child(ground)
ground.name = "Ground"
_set_camera_and_player_boundary()
_update_archive()
if not Engine.is_editor_hint():
var portal_node = ground.get_node_or_null("DeployLayer/portal_" + entrance_portal) as Node2D
if portal_node and not Engine.is_editor_hint():
if portal_node:
var player = SceneManager.get_player()
if player:
# player.global_position.x = -20.0
@ -156,13 +165,14 @@ func _update_archive():
var update_watcher: Timer
var last_modify = 0
var last_modify_time = 0
# DEBUG 时重新加载资源
func _watch_scene_update():
var scene_path = ground_dict[current_scene]
if scene_path:
last_modify = FileAccess.get_modified_time(scene_path)
last_modify_time = FileAccess.get_modified_time(scene_path)
if not update_watcher:
update_watcher = Timer.new()
update_watcher.wait_time = 1
@ -178,8 +188,8 @@ func _watch_scene_update():
func _check_scene_update(scene_path):
var modify = FileAccess.get_modified_time(scene_path)
if modify != last_modify:
last_modify = modify
if modify != last_modify_time:
last_modify_time = modify
_on_resources_reload(scene_path)

View File

@ -0,0 +1 @@
class_name AnimationRoot extends AnimationPlayer

View File

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

View File

@ -1,6 +1,7 @@
[gd_scene load_steps=22 format=3 uid="uid://dlx5xxbg53rb8"]
[gd_scene load_steps=24 format=3 uid="uid://dlx5xxbg53rb8"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_ff4yb"]
[ext_resource type="Script" path="res://scene/ground/scene/c01/s05_animations.gd" id="2_j5oim"]
[ext_resource type="Texture2D" uid="uid://bx5we5pgnlhl5" path="res://asset/art/scene/c01/s05_院长房间/bg_房间背景.png" id="3_3r1q2"]
[ext_resource type="Texture2D" uid="uid://dkufmwg07maun" path="res://asset/art/scene/c01/s05_院长房间/全局参考.png" id="3_7u4bh"]
[ext_resource type="Texture2D" uid="uid://bp2r4s6v6ag2f" path="res://asset/art/scene/c01/s05_院长房间/fg_前景.png" id="3_vmr0f"]
@ -15,6 +16,7 @@
[ext_resource type="Texture2D" uid="uid://diw7l2qdwbyoc" path="res://asset/art/scene/c01/s05_院长房间/e_画框.png" id="11_6gq1s"]
[ext_resource type="Texture2D" uid="uid://dx3ym8inpuj5b" path="res://asset/art/scene/c01/s05_院长房间/e_鸡毛掸子.png" id="12_jtglg"]
[ext_resource type="PackedScene" uid="uid://cw3q5pvciumil" path="res://scene/entity/interactable.tscn" id="14_lq1ou"]
[ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="15_1uixh"]
[ext_resource type="Texture2D" uid="uid://ox0ctin85kbl" path="res://asset/art/scene/c01/s05_院长房间/l_墙.png" id="16_qh7fg"]
[ext_resource type="Texture2D" uid="uid://bojbuuxwvlkkg" path="res://asset/art/scene/c01/s05_院长房间/l_窗户光源.png" id="17_qqw2v"]
@ -38,6 +40,9 @@ size = Vector2(35, 70)
[node name="Ground" parent="." instance=ExtResource("1_ff4yb")]
[node name="AnimationPlayer" parent="Ground" index="0"]
script = ExtResource("2_j5oim")
[node name="BGSprite2D" parent="Ground" index="2"]
position = Vector2(23, -118)
scale = Vector2(0.333, 0.333)
@ -115,6 +120,9 @@ prop_key = "prop_1012钥匙"
[node name="CollisionShape2D" parent="Ground/DeployLayer/Interactable/Area2D" index="0"]
shape = SubResource("RectangleShape2D_40ng7")
[node name="Ambush" parent="Ground/DeployLayer" index="9" instance=ExtResource("15_1uixh")]
position = Vector2(113, 46)
[node name="PointLight墙" type="PointLight2D" parent="Ground/AmbientLayer" index="0"]
visible = false
position = Vector2(283, 0)
@ -134,7 +142,7 @@ texture = ExtResource("3_vmr0f")
[node name="HdLayer" parent="Ground/SubViewportContainer/SubViewport" index="0"]
layer = -1
[node name="DirectionalLight2D" parent="Ground" index="7"]
[node name="DirectionalLight2D" parent="Ground" index="8"]
rotation = -0.000622023
energy = 0.3
blend_mode = 1

View File

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

View File

@ -1,7 +1,8 @@
[gd_scene load_steps=5 format=3 uid="uid://bbs7yy5aofw1v"]
[gd_scene load_steps=6 format=3 uid="uid://bbs7yy5aofw1v"]
[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="Script" path="res://scene/ground/scene/c02/s01_animations.gd" id="2_uuwn3"]
[ext_resource type="PackedScene" uid="uid://jr1yd46wm5je" path="res://scene/entity/note.tscn" id="3_6lnxd"]
[ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="6_vgxa0"]
@ -9,6 +10,9 @@
[node name="Ground" parent="." instance=ExtResource("1_gdcov")]
[node name="AnimationPlayer" parent="Ground" index="0"]
script = ExtResource("2_uuwn3")
[node name="BGSprite2D" parent="Ground" index="2"]
texture = ExtResource("2_ni1a4")

View File

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

View File

@ -1,6 +1,7 @@
[gd_scene load_steps=13 format=3 uid="uid://brck77w81fhvc"]
[gd_scene load_steps=14 format=3 uid="uid://brck77w81fhvc"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_wrr6r"]
[ext_resource type="Script" path="res://scene/ground/scene/c02/s02_animations.gd" id="2_5p8ev"]
[ext_resource type="Texture2D" uid="uid://c4647gof464ws" path="res://asset/art/scene/c02/s02_走道/bg_过道.png" id="2_cn1s8"]
[ext_resource type="PackedScene" uid="uid://jr1yd46wm5je" path="res://scene/entity/note.tscn" id="3_fy0o1"]
[ext_resource type="PackedScene" uid="uid://wyj4qdjyn4ql" path="res://scene/entity/old/inspectable.tscn" id="5_nhtbp"]
@ -23,6 +24,9 @@ size = Vector2(35, 70)
[node name="Ground" parent="." instance=ExtResource("1_wrr6r")]
[node name="AnimationPlayer" parent="Ground" index="0"]
script = ExtResource("2_5p8ev")
[node name="BGSprite2D" parent="Ground" index="2"]
texture = ExtResource("2_cn1s8")
@ -46,19 +50,16 @@ texture = ExtResource("7_xsghn")
flip_h = true
[node name="Sign" parent="Ground/DeployLayer/纸人" index="1"]
offset_left = -63.5
offset_top = -114.0
offset_right = -63.5
offset_bottom = -34.0
offset_left = 0.0
offset_top = -44.0
offset_right = 0.0
offset_bottom = 36.0
[node name="CollisionShape2D" parent="Ground/DeployLayer/纸人/Area2D" index="0"]
shape = SubResource("RectangleShape2D_vc6i4")
[node name="Ambush" parent="Ground/DeployLayer" index="5" instance=ExtResource("6_70vqn")]
position = Vector2(502, 54)
hook_animation = null
lock_player_on_playing_dialogue = null
hook_dialogue_res = null
[node name="HdEntity" parent="Ground/DeployLayer" index="6" node_paths=PackedStringArray("sprite_ref") instance=ExtResource("10_3c313")]
position = Vector2(147, 75)

View File

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

View File

@ -1,6 +1,7 @@
[gd_scene load_steps=13 format=3 uid="uid://djc2uaefhmu7"]
[gd_scene load_steps=14 format=3 uid="uid://djc2uaefhmu7"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_lheeb"]
[ext_resource type="Script" path="res://scene/ground/scene/c02/s03_animations.gd" id="2_l2oec"]
[ext_resource type="PackedScene" uid="uid://0sofmhrl358m" path="res://scene/entity/npc.tscn" id="2_r5smg"]
[ext_resource type="PackedScene" uid="uid://jr1yd46wm5je" path="res://scene/entity/note.tscn" id="3_6x7xl"]
[ext_resource type="Texture2D" uid="uid://bb3f72fla7mvs" path="res://asset/art/scene/c02/s03_院子切换/bg_院子1楼(黄昏无人).png" id="3_78bcp"]
@ -23,6 +24,9 @@ size = Vector2(40, 70)
[node name="Ground" parent="." instance=ExtResource("1_lheeb")]
[node name="AnimationPlayer" parent="Ground" index="0"]
script = ExtResource("2_l2oec")
[node name="BGSprite2D" parent="Ground" index="2"]
texture = SubResource("CanvasTexture_41q0k")
@ -36,7 +40,7 @@ position = Vector2(629, 2)
[node name="Npc" parent="Ground/DeployLayer" index="2" instance=ExtResource("2_r5smg")]
position = Vector2(465, 23)
frame_progress = 0.663565
frame_progress = 0.54706
character_name = "张胖子"
dialogue_title = "张胖子_01"
@ -78,7 +82,7 @@ texture = ExtResource("7_icddm")
position = Vector2(-12, -143)
scale = Vector2(1.08, 1.08)
[node name="DirectionalLight2D" parent="Ground" index="7"]
[node name="DirectionalLight2D" parent="Ground" index="8"]
color = Color(0.368627, 0.447059, 0.882353, 1)
[editable path="Ground"]

View File

@ -2,7 +2,8 @@ class_name PropInventory extends Resource
signal current_item_changed(prop_key: String)
@export var enabled_items := [] as Array[String]
# prop_空手 默认就存在,并且不可删除
@export var enabled_items := ["prop_空手"]
@export var current_index := 0:
set(val):
if current_index != val:
@ -25,7 +26,10 @@ func enable_item(prop_key: String) -> void:
func disable_item(prop_key: String) -> void:
if enabled_items.has(prop_key):
if prop_key == "prop_空手":
printerr("Cannot disable prop_空手")
return
# if enabled_items.has(prop_key):
enabled_items.erase(prop_key)
# wrap index
current_index = wrapi(current_index, 0, enabled_items.size())

View File

@ -1,11 +1,10 @@
[gd_scene load_steps=10 format=3 uid="uid://dygvcmykn02n8"]
[gd_scene load_steps=9 format=3 uid="uid://dygvcmykn02n8"]
[ext_resource type="Script" path="res://scene/main.gd" id="1_pks84"]
[ext_resource type="PackedScene" uid="uid://3gk1gxwanw24" path="res://scene/shading/shading_layer.tscn" id="2_d1re1"]
[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://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="Environment" uid="uid://c6ri8tn5qt6fe" path="res://scene/ground/environment.tres" id="9_jsof5"]
[ext_resource type="PackedScene" uid="uid://clxgkj80yin2" path="res://scene/ground/ground_loader.tscn" id="10_8rc5n"]
[ext_resource type="PackedScene" uid="uid://cvbt5qm70cg7t" path="res://scene/journal/journal.tscn" id="10_durpa"]
@ -19,12 +18,9 @@ environment = ExtResource("9_jsof5")
[node name="GroundLoader" parent="." instance=ExtResource("10_8rc5n")]
position = Vector2(1, 0)
ignore_archive = true
current_scene = "c01_s05"
[node name="MainPlayer" parent="." instance=ExtResource("6_6geb0")]
unique_name_in_owner = true
position = Vector2(80, 42)
scale = Vector2(0.6, 0.6)
entrance_portal = "right"
[node name="ShadingLayer" parent="." instance=ExtResource("2_d1re1")]

View File

@ -57,7 +57,7 @@ func _ready() -> void:
# _reset_face_direction()
footstep_timer.timeout.connect(_on_footstep_timer_timeout)
footstep_timer.stop()
SceneManager.focus_player()
SceneManager.focus_player(self)
os_contaner.modulate.a = 0.0
sprite.frame_changed.connect(queue_redraw)
@ -299,7 +299,7 @@ func _reset_os_and_shadow_position():
var texture = sprite.sprite_frames.get_frame_texture(sprite.animation, 0) as Texture2D
var size = texture.get_size()
# reset the os label position
os_pivot.position.y = -size.y * 0.5 - 4.0
os_pivot.position.y = -size.y * 0.5 * sprite.scale.x
# reset the shadow position
shadow_y = size.y * 0.5

View File

@ -1,25 +1,29 @@
[gd_scene load_steps=8 format=3 uid="uid://cjhw5ecygrqty"]
[gd_scene load_steps=9 format=3 uid="uid://cjhw5ecygrqty"]
[ext_resource type="Script" path="res://scene/player/main_player.gd" id="1_3a78y"]
[ext_resource type="SpriteFrames" uid="uid://c3s8u4ifaucpj" path="res://config/animation/entity_sprite_frames.tres" id="2_3w63u"]
[ext_resource type="SpriteFrames" uid="uid://bvypjkvdwysx8" path="res://config/animation/entity_sprite_frames.tres" id="2_3w63u"]
[ext_resource type="Texture2D" uid="uid://may55b2uerbw" path="res://asset/art/neutral_point_light.png" id="3_h4uja"]
[ext_resource type="Texture2D" uid="uid://bucpmiscjaem0" path="res://asset/art/ui/对话框.png" id="4_0qo0c"]
[ext_resource type="FontFile" uid="uid://coy0c115cjmv5" path="res://asset/font/MPLUS中文像素.TTF" id="4_4jk1c"]
[ext_resource type="Script" path="res://addons/dialogue_manager/dialogue_label.gd" id="5_tclgd"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_fno82"]
size = Vector2(78.25, 205.062)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_lq4rc"]
bg_color = Color(0.0313726, 0.0313726, 0.0313726, 0.729412)
border_color = Color(0.8, 0.8, 0.8, 0.160784)
corner_radius_top_left = 6
corner_radius_top_right = 6
corner_radius_bottom_right = 6
corner_radius_bottom_left = 6
expand_margin_left = 6.0
expand_margin_top = 6.0
expand_margin_right = 6.0
expand_margin_bottom = 6.0
[sub_resource type="StyleBoxTexture" id="StyleBoxTexture_j5yhp"]
texture = ExtResource("4_0qo0c")
texture_margin_left = 6.0
texture_margin_top = 6.0
texture_margin_right = 6.0
texture_margin_bottom = 6.0
expand_margin_left = 2.0
expand_margin_top = 2.0
expand_margin_right = 2.0
expand_margin_bottom = 2.0
axis_stretch_horizontal = 2
axis_stretch_vertical = 2
region_rect = Rect2(24, 76, 38, 24)
modulate_color = Color(0.996078, 0.92549, 0.85098, 0.733333)
[node name="MainPlayer" type="CharacterBody2D"]
collision_mask = 2
@ -30,6 +34,7 @@ unique_name_in_owner = true
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."]
unique_name_in_owner = true
scale = Vector2(0.6, 0.6)
sprite_frames = ExtResource("2_3w63u")
animation = &"idle_r"
@ -53,7 +58,6 @@ offset_bottom = -20.0
mouse_filter = 2
[node name="MarginContainer" type="MarginContainer" parent="OSPivot"]
custom_minimum_size = Vector2(120, 0)
layout_mode = 1
anchors_preset = 7
anchor_left = 0.5
@ -61,7 +65,7 @@ anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
offset_left = -60.0
offset_top = -12.0
offset_top = -21.0
offset_right = 60.0
grow_horizontal = 2
grow_vertical = 0
@ -71,23 +75,25 @@ mouse_filter = 2
[node name="PanelContainer" type="PanelContainer" parent="OSPivot/MarginContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(100, 0)
custom_minimum_size = Vector2(70, 0)
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
mouse_filter = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_lq4rc")
theme_override_styles/panel = SubResource("StyleBoxTexture_j5yhp")
[node name="OSLabel" type="RichTextLabel" parent="OSPivot/MarginContainer/PanelContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(120, 0)
clip_contents = false
custom_minimum_size = Vector2(70, 0)
layout_mode = 2
size_flags_vertical = 8
mouse_filter = 2
theme_override_fonts/normal_font = ExtResource("4_4jk1c")
theme_override_font_sizes/normal_font_size = 8
bbcode_enabled = true
text = "os:..."
fit_content = true
scroll_following = true
script = ExtResource("5_tclgd")
skip_action = &""
seconds_per_step = 0.05