diff --git a/asset/art/little_game/拼凑信件/信件碎片.png b/asset/art/little_game/拼凑信件/信件碎片.png new file mode 100644 index 00000000..69ae0711 Binary files /dev/null and b/asset/art/little_game/拼凑信件/信件碎片.png differ diff --git a/asset/art/little_game/拼凑信件/信件碎片.png.import b/asset/art/little_game/拼凑信件/信件碎片.png.import new file mode 100644 index 00000000..e0f50057 --- /dev/null +++ b/asset/art/little_game/拼凑信件/信件碎片.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cuyejl2kbp7y4" +path="res://.godot/imported/信件碎片.png-c35bdb7240fb280003e7b3bca88b316c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://asset/art/little_game/拼凑信件/信件碎片.png" +dest_files=["res://.godot/imported/信件碎片.png-c35bdb7240fb280003e7b3bca88b316c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/asset/art/little_game/拼凑信件/完整信件.png b/asset/art/little_game/拼凑信件/完整信件.png new file mode 100644 index 00000000..de8d4b5d Binary files /dev/null and b/asset/art/little_game/拼凑信件/完整信件.png differ diff --git a/asset/art/little_game/拼凑信件/完整信件.png.import b/asset/art/little_game/拼凑信件/完整信件.png.import new file mode 100644 index 00000000..120d0dc5 --- /dev/null +++ b/asset/art/little_game/拼凑信件/完整信件.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dnjrdh1qnpony" +path="res://.godot/imported/完整信件.png-cfd076a390551cbdbbaeee723f1d98cc.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://asset/art/little_game/拼凑信件/完整信件.png" +dest_files=["res://.godot/imported/完整信件.png-cfd076a390551cbdbbaeee723f1d98cc.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/asset/art/little_game/自动枯萎的花/花.png b/asset/art/little_game/自动枯萎的花/花.png new file mode 100644 index 00000000..fe3db9a2 Binary files /dev/null and b/asset/art/little_game/自动枯萎的花/花.png differ diff --git a/asset/art/little_game/自动枯萎的花/花.png.import b/asset/art/little_game/自动枯萎的花/花.png.import new file mode 100644 index 00000000..860f21ac --- /dev/null +++ b/asset/art/little_game/自动枯萎的花/花.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://crdphnglw5tv8" +path="res://.godot/imported/花.png-253551d934c1db4768dd5bcf7b145c5b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://asset/art/little_game/自动枯萎的花/花.png" +dest_files=["res://.godot/imported/花.png-253551d934c1db4768dd5bcf7b145c5b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/asset/dialogue/c03.dialogue b/asset/dialogue/c03.dialogue new file mode 100644 index 00000000..626a4593 --- /dev/null +++ b/asset/dialogue/c03.dialogue @@ -0,0 +1,11 @@ +~ this_is_a_node_title +Nathan: [[Hi|Hello|Howdy]], this is some dialogue. +Nathan: Here are some choices. +- First one + Nathan: You picked the first one. +- Second one + Nathan: You picked the second one. +- Start again => this_is_a_node_title +- End the conversation => END +Nathan: For more information see the online documentation. +=> END \ No newline at end of file diff --git a/asset/dialogue/c03.dialogue.import b/asset/dialogue/c03.dialogue.import new file mode 100644 index 00000000..ac5fa85b --- /dev/null +++ b/asset/dialogue/c03.dialogue.import @@ -0,0 +1,15 @@ +[remap] + +importer="dialogue_manager_compiler_13" +type="Resource" +uid="uid://b66v5hsf3tdox" +path="res://.godot/imported/c03.dialogue-c0384ecbb52edd7836345e985eb72b38.tres" + +[deps] + +source_file="res://asset/dialogue/c03.dialogue" +dest_files=["res://.godot/imported/c03.dialogue-c0384ecbb52edd7836345e985eb72b38.tres"] + +[params] + +defaults=true diff --git a/asset/dialogue/c04.dialogue b/asset/dialogue/c04.dialogue new file mode 100644 index 00000000..626a4593 --- /dev/null +++ b/asset/dialogue/c04.dialogue @@ -0,0 +1,11 @@ +~ this_is_a_node_title +Nathan: [[Hi|Hello|Howdy]], this is some dialogue. +Nathan: Here are some choices. +- First one + Nathan: You picked the first one. +- Second one + Nathan: You picked the second one. +- Start again => this_is_a_node_title +- End the conversation => END +Nathan: For more information see the online documentation. +=> END \ No newline at end of file diff --git a/asset/dialogue/c04.dialogue.import b/asset/dialogue/c04.dialogue.import new file mode 100644 index 00000000..dee334f7 --- /dev/null +++ b/asset/dialogue/c04.dialogue.import @@ -0,0 +1,15 @@ +[remap] + +importer="dialogue_manager_compiler_13" +type="Resource" +uid="uid://cthsrdkrseijb" +path="res://.godot/imported/c04.dialogue-c094c22b3c3a3667c042516fadd04a57.tres" + +[deps] + +source_file="res://asset/dialogue/c04.dialogue" +dest_files=["res://.godot/imported/c04.dialogue-c094c22b3c3a3667c042516fadd04a57.tres"] + +[params] + +defaults=true diff --git a/asset/dialogue/c05.dialogue b/asset/dialogue/c05.dialogue new file mode 100644 index 00000000..626a4593 --- /dev/null +++ b/asset/dialogue/c05.dialogue @@ -0,0 +1,11 @@ +~ this_is_a_node_title +Nathan: [[Hi|Hello|Howdy]], this is some dialogue. +Nathan: Here are some choices. +- First one + Nathan: You picked the first one. +- Second one + Nathan: You picked the second one. +- Start again => this_is_a_node_title +- End the conversation => END +Nathan: For more information see the online documentation. +=> END \ No newline at end of file diff --git a/asset/dialogue/c05.dialogue.import b/asset/dialogue/c05.dialogue.import new file mode 100644 index 00000000..83fad850 --- /dev/null +++ b/asset/dialogue/c05.dialogue.import @@ -0,0 +1,15 @@ +[remap] + +importer="dialogue_manager_compiler_13" +type="Resource" +uid="uid://c2em7wb623pd7" +path="res://.godot/imported/c05.dialogue-de8e66d65fcfff540deb26ce3c92b0a4.tres" + +[deps] + +source_file="res://asset/dialogue/c05.dialogue" +dest_files=["res://.godot/imported/c05.dialogue-de8e66d65fcfff540deb26ce3c92b0a4.tres"] + +[params] + +defaults=true diff --git a/asset/shader/cloud.gdshader b/asset/shader/cloud.gdshader index f749f0ab..b245a8d4 100644 --- a/asset/shader/cloud.gdshader +++ b/asset/shader/cloud.gdshader @@ -5,39 +5,44 @@ shader_type canvas_item; uniform sampler2D perlin_noise: repeat_enable; uniform sampler2D cell_noise: repeat_enable; -#define pow2(x) (x * x) -//#define iResolution 1.0/SCREEN_PIXEL_SIZE +//#define pow2(x) (x * x) +////#define iResolution 1.0/SCREEN_PIXEL_SIZE -const int samples = 35; -const float sigma = float(samples) * 0.25; +//const int samples = 16; +//const int half_samples = 8; +//const float sigma = float(samples) * 0.25; -float gaussian(vec2 i) { - return 1.0 / (2.0 * PI * pow2(sigma)) * exp(-((pow2(i.x) + pow2(i.y)) / (2.0 * pow2(sigma)))); -} - -vec3 blur(sampler2D sp, vec2 uv, vec2 scale) { - vec3 col = vec3(0.0); - float accum = 0.0; - float weight; - vec2 offset; - for (int x = - samples >> 1 ; x < samples >> 1; ++x) { - for (int y = -samples >> 1; y < samples >> 1; ++y) { - offset = vec2(float(x), float(y)); - weight = gaussian(offset); - col += texture(sp, uv + scale * offset).rgb * weight; - accum += weight; - } - } - return col / accum; -} +//float gaussian(vec2 i) { + //return 1.0 / (2.0 * PI * pow2(sigma)) * exp(-((pow2(i.x) + pow2(i.y)) / (2.0 * pow2(sigma)))); +//} +// +//float blur(sampler2D sp, vec2 uv, vec2 scale) { + //float col = 0.0; + //float accum = 0.0; + //float weight = 1.0; + //vec2 offset; + //for (int x = - half_samples ; x < half_samples; ++x) { + //for (int y = - half_samples; y < half_samples; ++y) { + //offset = vec2(float(x), float(y)); + ////weight = gaussian(offset); + //col += texture(sp, uv + scale * offset).r * weight; + //accum += weight; + //} + //} + //return col / accum; +//} void fragment() { vec2 uv1 = vec2(UV.x + TIME * .02, UV.y + TIME * .005); vec2 uv2 = vec2(UV.x + TIME * .03, UV.y + TIME * .005); - float noise1 = blur(perlin_noise, uv1, SCREEN_PIXEL_SIZE).r; - float noise2 = blur(cell_noise, uv2, SCREEN_PIXEL_SIZE).r; - float noise = smoothstep(noise1 * noise2 * 1.0, .0, .15); + //float noise1 = blur(perlin_noise, uv1, SCREEN_PIXEL_SIZE); + //float noise2 = blur(cell_noise, uv2, SCREEN_PIXEL_SIZE); + float noise1 = texture(perlin_noise, uv1).r; + float noise2 = texture(cell_noise, uv2).r; + //noise1 = 1.0; + //noise2 = 1.0; + float noise = smoothstep(noise1 * noise2, .0, .15); COLOR.a *= noise; } diff --git a/asset/shader/cloud.tres b/asset/shader/cloud.tres index e506fabe..497da99a 100644 --- a/asset/shader/cloud.tres +++ b/asset/shader/cloud.tres @@ -1,6 +1,28 @@ -[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://7wllwmfkfvsb"] +[gd_resource type="ShaderMaterial" load_steps=6 format=3 uid="uid://7wllwmfkfvsb"] -[ext_resource type="Shader" path="res://asset/shader/fog.gdshader" id="1_0axjk"] +[ext_resource type="Shader" path="res://asset/shader/cloud.gdshader" id="1_53tbo"] + +[sub_resource type="FastNoiseLite" id="FastNoiseLite_b87im"] +noise_type = 2 +fractal_type = 2 +fractal_octaves = 3 + +[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_phjgp"] +invert = true +seamless = true +seamless_blend_skirt = 0.45 +noise = SubResource("FastNoiseLite_b87im") + +[sub_resource type="FastNoiseLite" id="FastNoiseLite_wt8y1"] +noise_type = 3 +frequency = 0.005 + +[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_km1py"] +seamless = true +seamless_blend_skirt = 0.3 +noise = SubResource("FastNoiseLite_wt8y1") [resource] -shader = ExtResource("1_0axjk") +shader = ExtResource("1_53tbo") +shader_parameter/perlin_noise = SubResource("NoiseTexture2D_km1py") +shader_parameter/cell_noise = SubResource("NoiseTexture2D_phjgp") diff --git a/manager/config_manager/global_config.gd b/manager/config_manager/global_config.gd index 6b6b5851..3804bd14 100644 --- a/manager/config_manager/global_config.gd +++ b/manager/config_manager/global_config.gd @@ -14,6 +14,7 @@ const CANVAS_LAYER_SETTINGS = 20 const CANVAS_LAYER_BAG = 12 const CANVAS_LAYER_GROUND_MASK = 11 const CANVAS_LAYER_SHADING = 10 +const LAYER_LITTLE_GAME = 5 const CANVAS_LAYER_FG = 2 const CANVAS_LAYER_HD_ENTITY = 1 diff --git a/manager/scene/scene_manager.gd b/manager/scene/scene_manager.gd index 9879a28a..a917c1bc 100644 --- a/manager/scene/scene_manager.gd +++ b/manager/scene/scene_manager.gd @@ -50,7 +50,7 @@ func focus_player_and_reset_zoom(duration := 1.2) -> void: var marker = get_camera_marker() if marker: # marker.force_offset = Vector2.ZERO - marker.tween_zoom(1.0, duration, true) + marker.tween_zoom(1.0, duration) marker.focus_node(get_player()) diff --git a/project.godot b/project.godot index b2ca0096..bef2fc38 100644 --- a/project.godot +++ b/project.godot @@ -169,7 +169,7 @@ bag={ [internationalization] locale/translations=PackedStringArray("res://asset/dialogue/c01.en.translation", "res://asset/dialogue/c02.en.translation", "res://asset/dialogue/item_description.en.translation", "res://asset/dialogue/names.en.translation", "res://asset/dialogue/inspect_content.en.translation", "res://asset/dialogue/npc.en.translation", "res://asset/dialogue/c01.zh_CN.translation", "res://asset/dialogue/c02.zh_CN.translation", "res://asset/dialogue/inspect_content.zh_CN.translation", "res://asset/dialogue/item_description.zh_CN.translation", "res://asset/dialogue/names.zh_CN.translation", "res://asset/dialogue/npc.zh_CN.translation") -locale/translations_pot_files=PackedStringArray("res://asset/dialogue/item_description.dialogue", "res://asset/dialogue/c01.dialogue", "res://asset/dialogue/c02.dialogue", "res://asset/dialogue/inspect_content.dialogue", "res://asset/dialogue/npc.dialogue") +locale/translations_pot_files=PackedStringArray("res://asset/dialogue/item_description.dialogue", "res://asset/dialogue/c01.dialogue", "res://asset/dialogue/c02.dialogue", "res://asset/dialogue/inspect_content.dialogue", "res://asset/dialogue/npc.dialogue", "res://asset/dialogue/c03.dialogue", "res://asset/dialogue/c04.dialogue", "res://asset/dialogue/c05.dialogue") locale/test="zh-Hans" locale/fallback="zh" diff --git a/scene/entity/ambush.gd b/scene/entity/ambush.gd index ce564c17..6f2028bb 100644 --- a/scene/entity/ambush.gd +++ b/scene/entity/ambush.gd @@ -20,7 +20,7 @@ signal triggered @export var freeze_time := 5.0 var hook_animation = "" @export var lock_player_on_playing_dialogue = true -@export_enum("c01", "c02") var hook_dialogue_res = "c01": +@export_enum("c01", "c02", "c03", "c04", "c05") var hook_dialogue_res = "c01": set(val): hook_dialogue_res = val match val: @@ -28,13 +28,22 @@ var hook_animation = "" dialogue_res = dialogue_c01 "c02": dialogue_res = dialogue_c02 + "c03": + dialogue_res = dialogue_c03 + "c04": + dialogue_res = dialogue_c04 + "c05": + dialogue_res = dialogue_c05 if is_node_ready() and Engine.is_editor_hint(): notify_property_list_changed() -var hook_dialogue_title = "" -var hook_method = "" +var hook_dialogue_title := "" +var hook_method := "" var dialogue_c01 = preload("res://asset/dialogue/c01.dialogue") var dialogue_c02 = preload("res://asset/dialogue/c02.dialogue") +var dialogue_c03 = preload("res://asset/dialogue/c03.dialogue") +var dialogue_c04 = preload("res://asset/dialogue/c04.dialogue") +var dialogue_c05 = preload("res://asset/dialogue/c05.dialogue") var dialogue_res = dialogue_c01 var played_time := 0.0 @@ -128,6 +137,7 @@ func _do_trigger(): return played_time = time played = true + trigger_mutex.unlock() # hook_animation if hook_animation: var animation_player = _get_animation_player() @@ -146,7 +156,6 @@ func _do_trigger(): triggered.emit() if GlobalConfig.DEBUG: print("ambush triggered! name=", name) - trigger_mutex.unlock() _check_sign_display() diff --git a/scene/entity/general/sfx.gd b/scene/entity/general/sfx.gd index 969b04b0..b4d867e0 100644 --- a/scene/entity/general/sfx.gd +++ b/scene/entity/general/sfx.gd @@ -24,6 +24,7 @@ func _reload_sfx(): if not Engine.is_editor_hint(): return var path = sfx_root_path + dir + "/" + file + print("path=", path) if file and dir and FileAccess.file_exists(path): sfx = load(sfx_root_path + dir + "/" + file) as AudioStream else: diff --git a/scene/entity/local_inspectable.gd b/scene/entity/local_inspectable.gd index 48305775..36d02023 100644 --- a/scene/entity/local_inspectable.gd +++ b/scene/entity/local_inspectable.gd @@ -12,7 +12,7 @@ enum { STATUS_NORAML, STATUS_TRANSITIONING, STATUS_INSPECTING_COVER, STATUS_INSP @export var entity_name: String = "" @export var texture_cover: Texture2D -@export_enum("none", "c01", "c02", "c03", "c04", "c05", "c06") var editor_filter := "none": +@export_enum("none", "c01", "c02", "c03", "c04", "c05") var editor_filter := "none": set(val): editor_filter = val if is_node_ready() and Engine.is_editor_hint(): diff --git a/scene/entity/note.gd b/scene/entity/note.gd index c5066cf3..ac28a917 100644 --- a/scene/entity/note.gd +++ b/scene/entity/note.gd @@ -9,7 +9,7 @@ signal read_note if is_node_ready(): sign_mark.enabled = val @export_enum("os", "ballon") var mode = "os" -@export_enum("items", "c01", "c02", "c03", "c04", "c05", "c06") var dialogue := "items": +@export_enum("items", "c01", "c02", "c03", "c04", "c05") var dialogue := "items": set(val): dialogue = val match dialogue: @@ -19,10 +19,16 @@ signal read_note dialogue_res = dialogue_c01 "c02": dialogue_res = dialogue_c02 + "c03": + dialogue_res = dialogue_c03 + "c04": + dialogue_res = dialogue_c04 + "c05": + dialogue_res = dialogue_c05 if is_node_ready() and Engine.is_editor_hint(): notify_property_list_changed() var note_key := "" -@export_enum("none", "notes", "c01", "c02", "c03", "c04", "c05", "c06") var title_filter := "none": +@export_enum("none", "notes", "c01", "c02", "c03", "c04", "c05") var title_filter := "none": set(val): title_filter = val if is_node_ready() and Engine.is_editor_hint(): @@ -34,7 +40,9 @@ var note_key := "" var dialogue_items = preload("res://asset/dialogue/item_description.dialogue") var dialogue_c01 = preload("res://asset/dialogue/c01.dialogue") var dialogue_c02 = preload("res://asset/dialogue/c02.dialogue") - +var dialogue_c03 = preload("res://asset/dialogue/c03.dialogue") +var dialogue_c04 = preload("res://asset/dialogue/c04.dialogue") +var dialogue_c05 = preload("res://asset/dialogue/c05.dialogue") var dialogue_res = dialogue_items var interacting = false diff --git a/scene/ground/camera/camera_focus_marker.gd b/scene/ground/camera/camera_focus_marker.gd index 14f8af0e..18fbdf6a 100644 --- a/scene/ground/camera/camera_focus_marker.gd +++ b/scene/ground/camera/camera_focus_marker.gd @@ -5,7 +5,6 @@ class_name CameraFocusMarker extends Camera2D @export_group("Status") @export var lock_horizontal = true @export_group("Config") -@export var speed := 5.0 @export var half_screen_size := Vector2(564, 240) / 2.0 @export var shaded_height := 38 @export_group("Shake", "shake_") @@ -18,13 +17,14 @@ class_name CameraFocusMarker extends Camera2D # @export var limit_top := 0 # @export var limit_bottom := 316.0 @export var zoom_ratio := 1.0 +var speed := 5.0 var _tweeked_position := Vector2.ZERO var zoom_tween: Tween -var zooming_and_focus_start_position: Vector2 -# 0 to 1 -var zooming_and_focus_progress := 1.0 +# var zooming_and_focus_start_position: Vector2 +# # 0 to 1 +# var zooming_and_focus_progress := 1.0 func _ready() -> void: @@ -60,18 +60,19 @@ func _physics_process(delta: float) -> void: # set camera's position var target_position = focusing_node.global_position + _tweeked_position + force_offset if focusing_node is MainPlayer: - # player 的焦点在脚底,所以需要加上 player 的高度 + # player 的焦点在脚底,所以需要偏移 player 的高度。注意 y 轴是向下的,所以是减去 player 的高度 target_position.y -= focusing_node.current_animation_config.os_height * 0.7 - # 如果有 zooming_and_focus_progress, 将其位置加入计算 - if zooming_and_focus_progress < 1.0: - target_position.x = lerpf( - zooming_and_focus_start_position.x, target_position.x, zooming_and_focus_progress - ) - target_position.y = lerpf( - zooming_and_focus_start_position.y, target_position.y, zooming_and_focus_progress - ) + # # 如果有 zooming_and_focus_progress, 将其位置加入计算 + # if zooming_and_focus_progress < 1.0: + # target_position.x = lerpf( + # zooming_and_focus_start_position.x, target_position.x, zooming_and_focus_progress + # ) + # target_position.y = lerpf( + # zooming_and_focus_start_position.y, target_position.y, zooming_and_focus_progress + # ) # easing with speed - var new_position = global_position + (target_position - global_position) * speed * delta + var new_position = lerp(global_position, target_position, speed * delta) + # var new_position = global_position + (target_position - global_position) * speed * delta # clamp the position var margin = half_screen_size / zoom_ratio margin.y += shaded_height @@ -81,30 +82,31 @@ func _physics_process(delta: float) -> void: zoom = Vector2(zoom_ratio, zoom_ratio) -func tween_zoom(ratio: float, duration := 1.5, refocus := false): +func tween_zoom(ratio: float, duration := 1.5): if zoom_tween and zoom_tween.is_running(): zoom_tween.kill() zoom_tween = create_tween() ( zoom_tween . tween_property(self, "zoom_ratio", ratio, duration) - . set_trans(Tween.TRANS_CUBIC) + . set_trans(Tween.TRANS_SINE) . set_ease(Tween.EASE_IN_OUT) ) - if refocus: - zooming_and_focus_start_position = global_position - ( - zoom_tween - . parallel() - . tween_property(self, "zooming_and_focus_progress", 1.0, duration) - . from(0.0) - . set_trans(Tween.TRANS_LINEAR) - . set_ease(Tween.EASE_IN_OUT) - ) + # if refocus: + # zooming_and_focus_start_position = global_position + # ( + # zoom_tween + # . parallel() + # . tween_property(self, "zooming_and_focus_progress", 1.0, duration) + # . from(0.0) + # . set_trans(Tween.TRANS_SINE) + # . set_ease(Tween.EASE_IN_OUT) + # ) func focus_node(node: Node2D) -> void: focusing_node = node + # zooming_and_focus_start_position = global_position # var exited := false # var exit_position: Vector2 diff --git a/scene/ground/ground.gd b/scene/ground/ground.gd index 9bd2d0df..1cf6f404 100644 --- a/scene/ground/ground.gd +++ b/scene/ground/ground.gd @@ -16,10 +16,11 @@ var default_portal := "left" player_y = val if is_node_ready(): _reset_player_y() -@export var reset_player_y := false: +@export var replace_player_to_portal := false: set(val): - reset_player_y = false + replace_player_to_portal = false if is_node_ready(): + move_player_to_portal(default_portal) _reset_player_y() @export_group("Sound") @export_enum("none", "ghost", "walking", "running", "crawling", "concrete") diff --git a/scene/ground/scene/animation_root.gd b/scene/ground/scene/animation_root.gd index 971b43a2..b571e7d4 100644 --- a/scene/ground/scene/animation_root.gd +++ b/scene/ground/scene/animation_root.gd @@ -5,6 +5,9 @@ signal oneshot_animation_finished # 在继承 AnimationRoot 的各场景内的脚本中,可以直接调用 DialogueResource var dialogue_c01 := preload("res://asset/dialogue/c01.dialogue") as DialogueResource var dialogue_c02 := preload("res://asset/dialogue/c02.dialogue") as DialogueResource +var dialogue_c03 := preload("res://asset/dialogue/c03.dialogue") as DialogueResource +var dialogue_c04 := preload("res://asset/dialogue/c04.dialogue") as DialogueResource +var dialogue_c05 := preload("res://asset/dialogue/c05.dialogue") as DialogueResource @export var data = { # 首次进入场景时触发 @@ -22,13 +25,13 @@ func _default_data() -> Dictionary: func _ready() -> void: + data.merge(_default_data(), true) if Engine.is_editor_hint(): # notify_property_list_changed() # 更新 oneshot_animation 的可选项 animation_libraries_updated.connect(notify_property_list_changed) return ground_archive = ArchiveManager.archive.ground_archive() as GroundArchive - data.merge(_default_data(), true) var archive_data = ground_archive.get_data(name) # merge data for key in archive_data.keys(): @@ -41,24 +44,24 @@ func _ready() -> void: ground.ready.connect(_on_ground_ready) else: _on_ground_ready() + ready.connect(_on_ready) func _on_ground_ready() -> void: pass -func _notification(what: int) -> void: +func _on_ready() -> void: if Engine.is_editor_hint(): return # 仅在首次进入场景时触发 - if what == NOTIFICATION_READY: - if oneshot_animation: - if not data["oneshot_animation_played"]: - play(oneshot_animation) - animation_finished.connect(_oneshot_animation_finished, CONNECT_ONE_SHOT) - else: - if GlobalConfig.DEBUG: - print("oneshot_animation_played:", oneshot_animation) + if oneshot_animation: + if not data["oneshot_animation_played"]: + play(oneshot_animation) + animation_finished.connect(_oneshot_animation_finished, CONNECT_ONE_SHOT) + else: + if GlobalConfig.DEBUG: + print("oneshot_animation_played:", oneshot_animation) func _oneshot_animation_finished(animation_name) -> void: diff --git a/scene/ground/scene/c01/s05_animation.gd b/scene/ground/scene/c01/s05_animation.gd index 4216861c..15f3c48f 100644 --- a/scene/ground/scene/c01/s05_animation.gd +++ b/scene/ground/scene/c01/s05_animation.gd @@ -1,7 +1,6 @@ @tool extends AnimationRoot -var frame_relocated = false var ambush: Ambush2D var frame: Note2D var paper: Interactable2D @@ -11,7 +10,9 @@ var piano: Interactable2D # 覆盖该方法 func _default_data() -> Dictionary: - return {} + return { + "frame_relocated": false + } func _ready() -> void: @@ -31,11 +32,11 @@ func _on_ground_ready() -> void: right_door = $"../DeployLayer/portal_right" piano = $"../DeployLayer/钢琴" # 画框是否已经正位 - frame_relocated = ambush.played and ambush.one_shot + data.frame_relocated = ambush.played and ambush.one_shot # 禁用鸡毛掸子 ambush.enabled = false # 画框已经正位时,重制画框状态 - if frame_relocated: + if data.frame_relocated: frame.rotation_degrees = 0.0 frame.note_key = "c01_摆正的洋相片" if GlobalConfig.DEBUG: @@ -46,7 +47,7 @@ func _on_ground_ready() -> void: ambush.triggered.connect(_on_ambush_triggered) # 纸片状态 - if frame_relocated: + if data.frame_relocated: # 画框已经正位,纸片已经被拾取 if paper.interacted_times > 0: paper.visible = false diff --git a/scene/ground/scene/c01/s05_院长房间.tscn b/scene/ground/scene/c01/s05_院长房间.tscn index abd4b9f3..e4ba457b 100644 --- a/scene/ground/scene/c01/s05_院长房间.tscn +++ b/scene/ground/scene/c01/s05_院长房间.tscn @@ -578,6 +578,10 @@ libraries = { "": SubResource("AnimationLibrary_ifimj") } script = ExtResource("2_j5oim") +data = { +"frame_relocated": false, +"oneshot_animation_played": false +} oneshot_animation = "intro" [node name="BGSprite2D" parent="Ground" index="2"] diff --git a/scene/ground/scene/c01/s06_animation.gd b/scene/ground/scene/c01/s06_animation.gd index 441b791a..bd7174ce 100644 --- a/scene/ground/scene/c01/s06_animation.gd +++ b/scene/ground/scene/c01/s06_animation.gd @@ -58,6 +58,7 @@ func _on_ground_ready() -> void: game_kid_limp = $"../DeployLayer/【胖小孩背着残疾小孩】/【单残疾小孩】" cat_shadow = $"../DeployLayer/【胖小孩背着残疾小孩】/【单残疾小孩】/【墙上小孩猫影子】" cat = $"../DeployLayer/【墙上黑猫】" + cat.visible = false game_kid_limp.modulate.a = 0.0 # 院长翻书 @@ -91,7 +92,7 @@ func _game_counting_down(_res = null): # 重置镜头 SceneManager.focus_player_and_reset_zoom() DialogueManager.show_dialogue_balloon( - preload("res://asset/dialogue/c01.dialogue"), + dialogue_c01, "c01_s06_猫鼠游戏", [GlobalConfig.DIALOG_IGNORE_INPUT] ) diff --git a/scene/ground/scene/c01/s06_孤儿院长廊围墙.tscn b/scene/ground/scene/c01/s06_孤儿院长廊围墙.tscn index 1568afce..76627c72 100644 --- a/scene/ground/scene/c01/s06_孤儿院长廊围墙.tscn +++ b/scene/ground/scene/c01/s06_孤儿院长廊围墙.tscn @@ -121,7 +121,6 @@ position = Vector2(299, 42) one_shot = false freeze_time = 3.0 hook_animation = "门口_观望" -hook_method = null [node name="踢球男孩" parent="Ground/DeployLayer" index="5" instance=ExtResource("5_erliv")] position = Vector2(535, -3) @@ -278,10 +277,11 @@ move_configs = Array[Dictionary]([{ position = Vector2(123, 43) [node name="【墙上黑猫】" parent="Ground/DeployLayer" index="15" instance=ExtResource("8_ouldg")] -position = Vector2(1394, -1) +position = Vector2(1453, -14) +scale = Vector2(0.8, 0.8) sprite_frames = ExtResource("7_dsj2r") animation = &"【墙上黑猫】跑步" -frame_progress = 0.142437 +frame = 3 autostart = false move_configs = Array[Dictionary]([{ "animation": &"【墙上黑猫】跑步", diff --git a/scene/ground/scene/c01/s08_书店.tscn b/scene/ground/scene/c01/s08_书店.tscn new file mode 100644 index 00000000..0ad8f026 --- /dev/null +++ b/scene/ground/scene/c01/s08_书店.tscn @@ -0,0 +1,28 @@ +[gd_scene load_steps=3 format=3 uid="uid://cwu4dhayra8pg"] + +[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_b3cca"] + +[sub_resource type="LabelSettings" id="LabelSettings_7adaf"] +font_size = 20 + +[node name="S08" type="Node2D"] + +[node name="Ground" parent="." instance=ExtResource("1_b3cca")] +scene_name = "c01_s08" + +[node name="portal_right" parent="Ground/DeployLayer" index="1"] +immediately = false +target_scene = "c02_s08" + +[node name="Label" type="Label" parent="Ground/DeployLayer" index="2"] +offset_left = 132.0 +offset_top = -9.0 +offset_right = 212.0 +offset_bottom = 16.0 +text = "书店" +label_settings = SubResource("LabelSettings_7adaf") + +[node name="MainPlayer" parent="Ground" index="5"] +character = "小小蝶" + +[editable path="Ground"] diff --git a/scene/ground/scene/c01/s09_公寓楼外.tscn b/scene/ground/scene/c01/s09_公寓楼外.tscn new file mode 100644 index 00000000..b058a6fe --- /dev/null +++ b/scene/ground/scene/c01/s09_公寓楼外.tscn @@ -0,0 +1,36 @@ +[gd_scene load_steps=4 format=3 uid="uid://c777lv8mjojcw"] + +[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_mrwu5"] +[ext_resource type="PackedScene" uid="uid://ci34db7xool2n" path="res://scene/ground/script/c01/s01_自动枯萎的花朵.tscn" id="2_shnte"] + +[sub_resource type="LabelSettings" id="LabelSettings_7adaf"] +font_size = 20 + +[node name="S09" type="Node2D"] + +[node name="Ground" parent="." instance=ExtResource("1_mrwu5")] +scene_name = "c01_s09" + +[node name="portal_right" parent="Ground/DeployLayer" index="1"] +immediately = false +target_scene = "c02_s08" + +[node name="Label" type="Label" parent="Ground/DeployLayer" index="2"] +offset_left = 132.0 +offset_top = -9.0 +offset_right = 212.0 +offset_bottom = 16.0 +text = "公寓楼外" +label_settings = SubResource("LabelSettings_7adaf") + +[node name="S01自动枯萎的花朵" parent="Ground/DeployLayer" index="3" node_paths=PackedStringArray("focus_node") instance=ExtResource("2_shnte")] +position = Vector2(42, 70) +focus_node = NodePath("../../MainPlayer") + +[node name="MainPlayer" parent="Ground" index="5"] +character = "小小蝶" + +[node name="FGSprite2D" parent="Ground/ParallaxForeground/FGParallaxLayer" index="0"] +texture = null + +[editable path="Ground"] diff --git a/scene/ground/scene/c01/s10_公寓楼道.tscn b/scene/ground/scene/c01/s10_公寓楼道.tscn new file mode 100644 index 00000000..de4ea87b --- /dev/null +++ b/scene/ground/scene/c01/s10_公寓楼道.tscn @@ -0,0 +1,28 @@ +[gd_scene load_steps=3 format=3 uid="uid://be57l2o3vxxtm"] + +[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_hhs2q"] + +[sub_resource type="LabelSettings" id="LabelSettings_7adaf"] +font_size = 20 + +[node name="S10" type="Node2D"] + +[node name="Ground" parent="." instance=ExtResource("1_hhs2q")] +scene_name = "c01_s10" + +[node name="portal_right" parent="Ground/DeployLayer" index="1"] +immediately = false +target_scene = "c02_s08" + +[node name="Label" type="Label" parent="Ground/DeployLayer" index="2"] +offset_left = 132.0 +offset_top = -9.0 +offset_right = 212.0 +offset_bottom = 16.0 +text = "公寓楼道" +label_settings = SubResource("LabelSettings_7adaf") + +[node name="MainPlayer" parent="Ground" index="5"] +character = "小小蝶" + +[editable path="Ground"] diff --git a/scene/ground/scene/c02/s01_街道.tscn b/scene/ground/scene/c02/s01_街道.tscn index 67a7721d..cca337c2 100644 --- a/scene/ground/scene/c02/s01_街道.tscn +++ b/scene/ground/scene/c02/s01_街道.tscn @@ -13,6 +13,10 @@ scene_name = "c02_s01" [node name="AnimationPlayer" parent="Ground" index="0"] script = ExtResource("2_uuwn3") +data = { +"oneshot_animation_played": false, +"received_letter": false +} oneshot_animation = "" [node name="BGSprite2D" parent="Ground" index="2"] diff --git a/scene/ground/scene/c02/s02_animation.gd b/scene/ground/scene/c02/s02_animation.gd index f37a48a6..cfe0d749 100644 --- a/scene/ground/scene/c02/s02_animation.gd +++ b/scene/ground/scene/c02/s02_animation.gd @@ -1,12 +1,13 @@ @tool extends AnimationRoot -@onready var wind_blows = $"../DeployLayer/WindBlows" as AnimatedSprite2D +var wind_blows: AnimatedSprite2D +var paper_man: Ambush2D # 覆盖该方法 func _default_data() -> Dictionary: - return {} + return {"display_paper_man": false} func _ready() -> void: @@ -16,8 +17,13 @@ func _ready() -> void: func _on_ground_ready() -> void: - pass - + wind_blows = $"../DeployLayer/WindBlows" + wind_blows.visible = false + paper_man = $"../DeployLayer/Ambush纸人" + paper_man.enabled = data.display_paper_man + paper_man.visible = data.display_paper_man + + func _oneshot_wind(): SceneManager.freeze_player(0) %MainPlayer.visible = false @@ -29,12 +35,25 @@ func _oneshot_wind(): func _on_wind_finished(): %MainPlayer.visible = true wind_blows.visible = false - - -func _oneshot_dialog(): DialogueManager.show_dialogue_balloon(dialogue_c02, "c02_s02_天冷") DialogueManager.dialogue_ended.connect(_on_dialogue_ended, CONNECT_ONE_SHOT) func _on_dialogue_ended(_res): SceneManager.release_player() + + +func _display_paper_man(): + data.display_paper_man = true + paper_man.enabled = true + paper_man.visible = true + paper_man.get_node("Sfx").play() + + +func paper_man_interacted(): + SceneManager.enable_prop_item("prop_1012钥匙") + + +func lumber_interacted(): + SceneManager.pop_debug_dialog_info("美术", "杂物堆⾥有眼睛瞟向玩家/眨动,然后消失(动画)") + _display_paper_man() diff --git a/scene/ground/scene/c02/s02_走道.tscn b/scene/ground/scene/c02/s02_走道.tscn index f559736a..235bc39d 100644 --- a/scene/ground/scene/c02/s02_走道.tscn +++ b/scene/ground/scene/c02/s02_走道.tscn @@ -1,13 +1,16 @@ -[gd_scene load_steps=13 format=3 uid="uid://brck77w81fhvc"] +[gd_scene load_steps=17 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_animation.gd" id="2_5p8ev"] [ext_resource type="Texture2D" uid="uid://tqkhrogci71d" 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="SpriteFrames" uid="uid://b7fhheih1hbvf" path="res://config/animation/entity_sprite_frames.tres" id="4_wbif8"] -[ext_resource type="PackedScene" uid="uid://wyj4qdjyn4ql" path="res://scene/entity/old/inspectable.tscn" id="5_nhtbp"] [ext_resource type="Texture2D" uid="uid://cvgw2mxrlr6io" path="res://asset/art/scene/c02/s02_走道/ux_进门鼠疫海报yz.png" id="7_wdwbi"] [ext_resource type="Texture2D" uid="uid://5pl1b7cor715" path="res://asset/art/scene/c02/s02_走道/e_纸人.png" id="7_xsghn"] +[ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="8_52as8"] +[ext_resource type="PackedScene" uid="uid://beleib3mmu0af" path="res://scene/little_game/八音盒.tscn" id="10_ifae7"] +[ext_resource type="PackedScene" uid="uid://c85t6stvytvjn" path="res://scene/entity/general/sfx.tscn" id="10_pelha"] +[ext_resource type="AudioStream" uid="uid://dq2ndg5yd3rps" path="res://asset/audio/sfx/c02/出现.mp3" id="11_u68d7"] [ext_resource type="PackedScene" uid="uid://ci5anaxsa1apl" path="res://scene/entity/local_inspectable.tscn" id="12_0fckv"] [sub_resource type="Animation" id="Animation_abofy"] @@ -20,14 +23,11 @@ tracks/0/path = NodePath("AnimationPlayer") tracks/0/interp = 1 tracks/0/loop_wrap = true tracks/0/keys = { -"times": PackedFloat32Array(0, 1.6), -"transitions": PackedFloat32Array(1, 1), +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), "values": [{ "args": [], "method": &"_oneshot_wind" -}, { -"args": [], -"method": &"_oneshot_dialog" }] } @@ -36,11 +36,15 @@ _data = { "oneshot_天冷": SubResource("Animation_abofy") } -[sub_resource type="RectangleShape2D" id="RectangleShape2D_vc6i4"] +[sub_resource type="RectangleShape2D" id="RectangleShape2D_dwg0o"] resource_local_to_scene = true -size = Vector2(35, 70) +size = Vector2(10, 70) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_mjnwv"] +size = Vector2(17, 91) [node name="S02" type="Node2D"] +metadata/_edit_horizontal_guides_ = [98.0] [node name="Ground" parent="." instance=ExtResource("1_wrr6r")] scene_name = "c02_s02" @@ -51,11 +55,18 @@ libraries = { "": SubResource("AnimationLibrary_fjkfm") } script = ExtResource("2_5p8ev") +data = { +"display_paper_man": false, +"oneshot_animation_played": false +} oneshot_animation = "oneshot_天冷" [node name="BGSprite2D" parent="Ground" index="2"] texture = ExtResource("2_cn1s8") +[node name="portal_left" parent="Ground/DeployLayer" index="0"] +position = Vector2(53, 15) + [node name="portal_right" parent="Ground/DeployLayer" index="1"] position = Vector2(678, 6) target_scene = "c02_s03" @@ -63,8 +74,7 @@ target_portal = "left" [node name="WindBlows" type="AnimatedSprite2D" parent="Ground/DeployLayer" index="2"] unique_name_in_owner = true -visible = false -position = Vector2(435, 9) +position = Vector2(462, 9) scale = Vector2(1.2, 1.2) sprite_frames = ExtResource("4_wbif8") animation = &"c02_吕萍_风吹过" @@ -79,36 +89,60 @@ position = Vector2(439, -18) texture_cover = ExtResource("7_wdwbi") content_key = "c02_鼠疫海报" -[node name="纸人" parent="Ground/DeployLayer" index="5" instance=ExtResource("5_nhtbp")] -position = Vector2(599, 44) +[node name="Ambush纸人" parent="Ground/DeployLayer" index="5" instance=ExtResource("8_52as8")] +position = Vector2(198, 48) texture = ExtResource("7_xsghn") flip_h = true +trigger_mode = "interact" +freeze_time = 1.0 +hook_method = "paper_man_interacted" -[node name="Sign" parent="Ground/DeployLayer/纸人" index="1"] -offset_left = 0.0 -offset_top = -44.0 -offset_right = 0.0 -offset_bottom = 36.0 +[node name="Sign" parent="Ground/DeployLayer/Ambush纸人" index="0"] +offset_left = -1.0 +offset_top = -2.0 +offset_right = -1.0 +offset_bottom = -2.0 +display_sign = true -[node name="CollisionShape2D" parent="Ground/DeployLayer/纸人/Area2D" index="0"] -shape = SubResource("RectangleShape2D_vc6i4") +[node name="CollisionShape2D" parent="Ground/DeployLayer/Ambush纸人/Area2D" index="0"] +shape = SubResource("RectangleShape2D_dwg0o") + +[node name="wall" type="StaticBody2D" parent="Ground/DeployLayer/Ambush纸人"] +position = Vector2(-11, 6) +collision_layer = 2 +collision_mask = 0 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Ground/DeployLayer/Ambush纸人/wall"] +position = Vector2(-14, -1) +shape = SubResource("RectangleShape2D_mjnwv") + +[node name="Sfx" parent="Ground/DeployLayer/Ambush纸人" instance=ExtResource("10_pelha")] +stream = ExtResource("11_u68d7") +dir = "c02" +file = "出现.mp3" + +[node name="八音盒" parent="Ground/DeployLayer" index="6" instance=ExtResource("10_ifae7")] +visible = false + +[node name="Ambush杂物堆" parent="Ground/DeployLayer" index="7" instance=ExtResource("8_52as8")] +position = Vector2(387, 66) +trigger_mode = "interact" +freeze_time = 1.0 +hook_method = "lumber_interacted" + +[node name="Label" type="Label" parent="Ground/DeployLayer/Ambush杂物堆"] +offset_left = -16.0 +offset_top = 7.0 +offset_right = 24.0 +offset_bottom = 22.0 +text = "杂物堆 +" [node name="MainPlayer" parent="Ground" index="5"] -position = Vector2(26, 98) - -[node name="CameraFocusMarker" parent="Ground" index="6"] -force_offset = Vector2(0, 0) -lock_horizontal = true -speed = 5.0 -half_screen_size = Vector2(282, 120) -shaded_height = 38 -shake_enabled = false -shake_strength = 2.0 -shake_recovery_speed = 8.0 -zoom_ratio = 1.0 +position = Vector2(53, 98) [node name="FGSprite2D" parent="Ground/ParallaxForeground/FGParallaxLayer" index="0"] texture = null [editable path="Ground"] -[editable path="Ground/DeployLayer/纸人"] +[editable path="Ground/DeployLayer/Ambush纸人"] diff --git a/scene/ground/script/c01/s01_自动枯萎的花朵.gd b/scene/ground/script/c01/s01_自动枯萎的花朵.gd new file mode 100644 index 00000000..26421dde --- /dev/null +++ b/scene/ground/script/c01/s01_自动枯萎的花朵.gd @@ -0,0 +1,94 @@ +@tool +extends Node2D + +@export var flower_area := Vector2(400, 50): + set(val): + flower_area = val + queue_redraw() +@export var gizmo_outline_color := Color(0.4, 0.4, 0.2, 0.8): + set(val): + gizmo_outline_color = val + queue_redraw() +@export var scatter_on_start := false +@export var debug_scatter := false: + set(val): + debug_scatter = false + if Engine.is_editor_hint(): + _init_flowers(true) +@export var auto_fade_distance := 50.0 +@export var focus_node: Node2D + +var flowers = [] as Array[AnimatedSprite2D] +var faded_flowers = [] as Array[String] + +var fade_animation_dict = { + "flower1_开放": "flower1_枯萎", + "flower2_开放": "flower2_枯萎", +} + + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + _init_flowers() + if Engine.is_editor_hint(): + queue_redraw() + + +func _enter_tree() -> void: + if is_node_ready(): + _init_flowers() + + +func _init_flowers(scatter := scatter_on_start) -> void: + flowers.clear() + for f in get_children(): + if f is AnimatedSprite2D: + flowers.append(f) + for i in range(flowers.size()): + var f = flowers[i] + # clamp to action area + if scatter: + var pos = Vector2(randf() * flower_area.x, randf() * flower_area.y) + f.position = pos + if ( + not Engine.is_editor_hint() + and ArchiveManager.archive.global_data_dict.has("faded_flowers") + ): + faded_flowers = ArchiveManager.archive.global_data_dict["faded_flowers"] + for f in flowers: + if faded_flowers.has(f.name): + var animation_name = fade_animation_dict.get(f.animation, "") + if animation_name: + f.play(animation_name) + + +func _draw() -> void: + if Engine.is_editor_hint(): + # draw gizmo + var area_rect = Rect2(Vector2.ZERO, flower_area) + # fill + var fill_color = gizmo_outline_color + fill_color.a = 0.4 + draw_rect(area_rect, fill_color) + # outline + draw_rect(area_rect, gizmo_outline_color, false, 1.0) + + +func _physics_process(_delta: float) -> void: + if Engine.is_editor_hint(): + return + if not focus_node or not focus_node.is_visible_in_tree(): + return + var focus_pos_x = focus_node.global_position.x + var faded := false + for f in flowers: + var f_pos_x = f.global_position.x + var distance = abs(focus_pos_x - f_pos_x) + if distance < auto_fade_distance: + var animation_name = fade_animation_dict.get(f.animation, "") + if animation_name: + f.play(animation_name) + faded_flowers.append(f.name) + faded = true + if faded and not Engine.is_editor_hint(): + ArchiveManager.archive.global_data_dict["faded_flowers"] = faded_flowers diff --git a/scene/ground/script/c01/s01_自动枯萎的花朵.tscn b/scene/ground/script/c01/s01_自动枯萎的花朵.tscn new file mode 100644 index 00000000..b983e887 --- /dev/null +++ b/scene/ground/script/c01/s01_自动枯萎的花朵.tscn @@ -0,0 +1,130 @@ +[gd_scene load_steps=8 format=3 uid="uid://ci34db7xool2n"] + +[ext_resource type="Script" path="res://scene/ground/script/c01/s01_自动枯萎的花朵.gd" id="1_l00w7"] +[ext_resource type="Texture2D" uid="uid://crdphnglw5tv8" path="res://asset/art/little_game/自动枯萎的花/花.png" id="2_h4yj5"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_p73pf"] +atlas = ExtResource("2_h4yj5") +region = Rect2(0, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_2mqji"] +atlas = ExtResource("2_h4yj5") +region = Rect2(0, 32, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_hm6ef"] +atlas = ExtResource("2_h4yj5") +region = Rect2(32, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_tkwcu"] +atlas = ExtResource("2_h4yj5") +region = Rect2(32, 32, 32, 32) + +[sub_resource type="SpriteFrames" id="SpriteFrames_hq611"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_p73pf") +}], +"loop": true, +"name": &"flower1_开放", +"speed": 5.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_2mqji") +}], +"loop": true, +"name": &"flower1_枯萎", +"speed": 5.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_hm6ef") +}], +"loop": true, +"name": &"flower2_开放", +"speed": 5.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_tkwcu") +}], +"loop": true, +"name": &"flower2_枯萎", +"speed": 5.0 +}] + +[node name="S01自动枯萎的花朵" type="Node2D"] +script = ExtResource("1_l00w7") + +[node name="flower1" type="AnimatedSprite2D" parent="."] +position = Vector2(361.267, 37.2719) +sprite_frames = SubResource("SpriteFrames_hq611") +animation = &"flower1_开放" +autoplay = "flower1_开放" + +[node name="flower2" type="AnimatedSprite2D" parent="."] +position = Vector2(130.105, 48.4146) +sprite_frames = SubResource("SpriteFrames_hq611") +animation = &"flower2_开放" +autoplay = "flower2_开放" + +[node name="flower3" type="AnimatedSprite2D" parent="."] +position = Vector2(90.0357, 29.8311) +sprite_frames = SubResource("SpriteFrames_hq611") +animation = &"flower1_开放" +autoplay = "flower1_开放" + +[node name="flower4" type="AnimatedSprite2D" parent="."] +position = Vector2(61.5162, 18.0411) +sprite_frames = SubResource("SpriteFrames_hq611") +animation = &"flower2_开放" +autoplay = "flower2_开放" + +[node name="flower5" type="AnimatedSprite2D" parent="."] +position = Vector2(146.966, 14.3762) +sprite_frames = SubResource("SpriteFrames_hq611") +animation = &"flower1_开放" +autoplay = "flower1_开放" + +[node name="flower6" type="AnimatedSprite2D" parent="."] +position = Vector2(320.474, 10.6263) +sprite_frames = SubResource("SpriteFrames_hq611") +animation = &"flower2_开放" +autoplay = "flower2_开放" + +[node name="flower7" type="AnimatedSprite2D" parent="."] +position = Vector2(341.667, 41.5392) +sprite_frames = SubResource("SpriteFrames_hq611") +animation = &"flower2_枯萎" +autoplay = "flower1_开放" + +[node name="flower8" type="AnimatedSprite2D" parent="."] +position = Vector2(287.04, 47.0337) +sprite_frames = SubResource("SpriteFrames_hq611") +animation = &"flower2_开放" +autoplay = "flower2_开放" + +[node name="flower9" type="AnimatedSprite2D" parent="."] +position = Vector2(190.428, 2.00511) +sprite_frames = SubResource("SpriteFrames_hq611") +animation = &"flower1_开放" +autoplay = "flower1_开放" + +[node name="flower10" type="AnimatedSprite2D" parent="."] +position = Vector2(128.674, 24.4653) +sprite_frames = SubResource("SpriteFrames_hq611") +animation = &"flower2_开放" +autoplay = "flower2_开放" + +[node name="flower11" type="AnimatedSprite2D" parent="."] +position = Vector2(73.9961, 8.11343) +sprite_frames = SubResource("SpriteFrames_hq611") +animation = &"flower1_开放" +autoplay = "flower1_开放" + +[node name="flower12" type="AnimatedSprite2D" parent="."] +position = Vector2(309.109, 21.3757) +sprite_frames = SubResource("SpriteFrames_hq611") +animation = &"flower2_开放" +autoplay = "flower2_开放" diff --git a/scene/little_game/八音盒.gd b/scene/little_game/八音盒.gd index 3bd7fc10..d6ca9386 100644 --- a/scene/little_game/八音盒.gd +++ b/scene/little_game/八音盒.gd @@ -1,4 +1,4 @@ -extends Control +extends CanvasLayer signal exit(passed: bool) @@ -51,14 +51,17 @@ var playing_step_sec := 0.5 func _ready() -> void: + layer = GlobalConfig.LAYER_LITTLE_GAME # debug mode: reset if GlobalConfig.DEBUG: ArchiveManager.archive.bayinhe_mode = "closed" ArchiveManager.archive.bayinhe_current_answer = [0, 0, 0, 0, 0, 0, 0, 0, 0] playing_step_sec = audio_manual.get_length() / playing_steps - _chechout_mode() + if visible: + _chechout_mode() inside_handle.pressed.connect(_on_handle_pressed) handle_wheel.rotated.connect(_on_wheel_rotated) + visibility_changed.connect(_on_visibility_changed) # # test close shaking effect # ArchiveManager.archive.bayinhe_mode = "playing" @@ -66,6 +69,13 @@ func _ready() -> void: # get_tree().create_timer(1.0).timeout.connect(_on_auto_play_finished) +func _on_visibility_changed() -> void: + if visible: + _chechout_mode() + else: + audio_player.stop() + + func _chechout_mode(play_sfx := false) -> void: var mode = ArchiveManager.archive.bayinhe_mode inside_handle.visible = mode == "opened" @@ -249,7 +259,7 @@ func _on_auto_play_finished(): var count = int(duration * fps) var delta_t = 1.0 / fps for i in range(count): - var offset = Vector2(randf_range(-delta, delta), randf_range(-delta, delta)) * exp(-i) - tween.tween_property(box, "position", origin_pos + offset, delta_t).set_trans( + var _offset = Vector2(randf_range(-delta, delta), randf_range(-delta, delta)) * exp(-i) + tween.tween_property(box, "position", origin_pos + _offset, delta_t).set_trans( Tween.TRANS_CUBIC ) diff --git a/scene/little_game/八音盒.tscn b/scene/little_game/八音盒.tscn index 74aa9710..7d0efcd0 100644 --- a/scene/little_game/八音盒.tscn +++ b/scene/little_game/八音盒.tscn @@ -119,14 +119,8 @@ animations = [{ atlas = ExtResource("4_a11wt") region = Rect2(272, 127, 110, 41) -[node name="八音盒" type="Control"] -layout_mode = 3 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -mouse_filter = 1 +[node name="八音盒" type="CanvasLayer"] +layer = 5 script = ExtResource("2_opptd") [node name="AnimationPlayer" type="AnimationPlayer" parent="."] @@ -135,7 +129,6 @@ libraries = { } [node name="BG" type="TextureRect" parent="."] -layout_mode = 1 anchors_preset = 8 anchor_left = 0.5 anchor_top = 0.5 @@ -156,7 +149,6 @@ stream = ExtResource("19_7mlnq") bus = &"game_sfx" [node name="Box" type="TextureRect" parent="."] -layout_mode = 1 anchors_preset = 8 anchor_left = 0.5 anchor_top = 0.5 @@ -177,7 +169,6 @@ sprite_frames = SubResource("SpriteFrames_t7gu7") centered = false [node name="InsideHandle" type="TextureButton" parent="."] -layout_mode = 0 offset_left = 244.0 offset_top = 157.0 offset_right = 354.0 @@ -198,7 +189,7 @@ offset_right = 426.0 offset_bottom = 188.0 [node name="LidHint" type="Control" parent="."] -layout_mode = 1 +layout_mode = 3 anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 diff --git a/scene/little_game/拼凑信件.gd b/scene/little_game/拼凑信件.gd new file mode 100644 index 00000000..dd01f024 --- /dev/null +++ b/scene/little_game/拼凑信件.gd @@ -0,0 +1,109 @@ +extends CanvasLayer + +@onready var container = %PartsContainer as GridContainer +@onready var whole = %Whole as Sprite2D +# from part 0 to 3, rotated by 0, 90, 180, 270 degrees +var rotations = [0, 0, 0, 0] + +var selected := 0: + set(value): + selected = value + _display_selected() + + +func _ready() -> void: + layer = GlobalConfig.LAYER_LITTLE_GAME + for i in range(4): + var part = container.get_child(i) + part.pressed.connect(_select_part.bind(part)) + _shuffle() + _display_selected() + whole.visible = false + + +func _select_part(part) -> void: + selected = part.get_index() + _display_selected() + + +func _exchange_parts(a: int, b: int) -> void: + var part_a = container.get_child(a) + var part_b = container.get_child(b) + container.move_child(part_a, b) + container.move_child(part_b, a) + # reassign answer + container.move_child(part_a, b) + + +func _rotate_part(direction := 1) -> void: + var part = container.get_child(selected) as TextureButton + var id = int(str(part.name)) + rotations[id] = wrapi(rotations[id] + direction, 0, 4) + var image = part.texture_normal.get_image() + image.rotate_90(direction) + part.texture_normal = ImageTexture.create_from_image(image) + + +func _shuffle() -> void: + # shuffle answer + for i in range(30): + var a = randi() % 4 + var b = randi() % 4 + _exchange_parts(a, b) + # shuffle rotations + for i in range(4): + selected = i + for j in range(randi() % 4): + _rotate_part(1) + selected = 0 + + +func _display_selected() -> void: + for i in range(4): + if i == selected: + container.get_child(i).modulate = Color(1, 1, 1) + else: + container.get_child(i).modulate = Color(0.7, 0.7, 0.7) + + +func _check_answer() -> void: + var success = true + for i in range(4): + var part = container.get_child(i) + var id = int(str(part.name)) + if rotations[id] != 0 or id != i: + success = false + if success: + whole.visible = true + container.visible = false + + +func _unhandled_input(event: InputEvent) -> void: + var handled = false + if event.is_action_pressed("up"): + if selected > 1: + _exchange_parts(selected, selected - 2) + selected -= 2 + handled = true + elif event.is_action_pressed("down"): + if selected < 2: + _exchange_parts(selected, selected + 2) + selected += 2 + handled = true + elif event.is_action_pressed("left"): + if selected % 2 == 1: + _exchange_parts(selected, selected - 1) + selected -= 1 + handled = true + elif event.is_action_pressed("right"): + if selected % 2 == 0: + _exchange_parts(selected, selected + 1) + selected += 1 + handled = true + elif event.is_action_pressed("interact"): + _rotate_part() + handled = true + if handled: + _display_selected() + _check_answer() + get_viewport().set_input_as_handled() diff --git a/scene/little_game/拼凑信件.tscn b/scene/little_game/拼凑信件.tscn new file mode 100644 index 00000000..b084ddf8 --- /dev/null +++ b/scene/little_game/拼凑信件.tscn @@ -0,0 +1,75 @@ +[gd_scene load_steps=8 format=3 uid="uid://bp3tkos1ufjcl"] + +[ext_resource type="Script" path="res://scene/little_game/拼凑信件.gd" id="1_cifku"] +[ext_resource type="Texture2D" uid="uid://dnjrdh1qnpony" path="res://asset/art/little_game/拼凑信件/完整信件.png" id="3_uenrm"] + +[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_5u07c"] +load_path = "res://.godot/imported/信件碎片.png-c35bdb7240fb280003e7b3bca88b316c.ctex" + +[sub_resource type="AtlasTexture" id="AtlasTexture_4e0jv"] +atlas = SubResource("CompressedTexture2D_5u07c") +region = Rect2(29, 16, 75, 80) + +[sub_resource type="AtlasTexture" id="AtlasTexture_qxu7b"] +atlas = SubResource("CompressedTexture2D_5u07c") +region = Rect2(104, 16, 72, 80) + +[sub_resource type="AtlasTexture" id="AtlasTexture_mbck6"] +atlas = SubResource("CompressedTexture2D_5u07c") +region = Rect2(24, 120, 72, 72) + +[sub_resource type="AtlasTexture" id="AtlasTexture_5dpsb"] +atlas = SubResource("CompressedTexture2D_5u07c") +region = Rect2(104, 104, 80, 88) + +[node name="拼凑信件" type="CanvasLayer"] +layer = 5 +script = ExtResource("1_cifku") + +[node name="Control" type="Control" parent="."] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="BGTexture" type="TextureRect" parent="Control"] +layout_mode = 1 +anchors_preset = 14 +anchor_top = 0.5 +anchor_right = 1.0 +anchor_bottom = 0.5 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Whole" type="Sprite2D" parent="Control"] +unique_name_in_owner = true +visible = false +position = Vector2(263, 161) +texture = ExtResource("3_uenrm") + +[node name="PartsContainer" type="GridContainer" parent="Control"] +unique_name_in_owner = true +layout_mode = 0 +offset_left = 206.0 +offset_top = 72.0 +offset_right = 365.0 +offset_bottom = 244.0 +columns = 2 + +[node name="0" type="TextureButton" parent="Control/PartsContainer"] +layout_mode = 2 +texture_normal = SubResource("AtlasTexture_4e0jv") + +[node name="1" type="TextureButton" parent="Control/PartsContainer"] +layout_mode = 2 +texture_normal = SubResource("AtlasTexture_qxu7b") + +[node name="2" type="TextureButton" parent="Control/PartsContainer"] +layout_mode = 2 +texture_normal = SubResource("AtlasTexture_mbck6") + +[node name="3" type="TextureButton" parent="Control/PartsContainer"] +layout_mode = 2 +texture_normal = SubResource("AtlasTexture_5dpsb")