animation pro 增加 mov x 范围移动与预览功能

This commit is contained in:
cakipaul 2025-06-17 17:10:48 +08:00
parent e2ca7f48c4
commit 09a5c40994
11 changed files with 207 additions and 220 deletions

View File

@ -14,12 +14,20 @@ class_name ProAnimatedSprite2D extends AnimatedSprite2D
else: else:
light2d.blend_mode = Light2D.BLEND_MODE_SUB light2d.blend_mode = Light2D.BLEND_MODE_SUB
light_energy = val * modulate.a light_energy = val * modulate.a
@export var debug_mov_animation := ""
@export_tool_button("debug 刷新 mov 目标") var debug_mov_projection := _debug_mov_projection
const ACTION_CONFIG = { const ACTION_CONFIG = {
"animation_intro": "", "intro_loop": 1, "animation_wait_time": 0.0, "animation_next": "" "animation_intro": "", "intro_loop": 1, "animation_wait_time": 0.0, "animation_next": ""
} }
# 参数 {duration} 目前无需求,暂且保留 # 参数 {duration} 目前无需求,暂且保留
const MOVE_CONFIG = {"animation": "", "velocity": Vector2.ZERO, "duration": 10000000.0} const MOVE_CONFIG = {
"animation": "",
"velocity": Vector2.ZERO,
"duration": 10000000.0,
"movement_x": 0.0,
"animation_next": ""
}
static func new_move_config() -> Dictionary: static func new_move_config() -> Dictionary:
@ -30,13 +38,15 @@ static func new_action_config() -> Dictionary:
return ACTION_CONFIG.duplicate() return ACTION_CONFIG.duplicate()
@onready var debug_mov_onion_sprite2d = $DebugMovOnionSkinSprite2D as Sprite2D
# 从 intro 到 next 的配置信息 # 从 intro 到 next 的配置信息
var auto_checkout_dict = { var auto_checkout_dict = {
# intro -> {state_config instance} # intro -> {state_config instance}
} }
# 播放 animation 的同时,进行移动 # 播放 animation 的同时,进行移动
var animation_velocity = { var animation_mov_dict = {
# animation -> velocity # animation -> {velocity, ...}
} }
var light2d := PointLight2D.new() var light2d := PointLight2D.new()
@ -47,16 +57,29 @@ func _ready() -> void:
add_child(light2d) add_child(light2d)
frame_changed.connect(_on_frame_changed) frame_changed.connect(_on_frame_changed)
if Engine.is_editor_hint(): if Engine.is_editor_hint():
_debug_mov_projection()
return return
_load_config() _load_config()
debug_mov_onion_sprite2d.queue_free()
if autostart and animation: if autostart and animation:
# 制造一点错差 # 制造一点错差
frame = randi() % sprite_frames.get_frame_count(animation) frame = randi() % sprite_frames.get_frame_count(animation)
play() play()
animation_finished.connect(_on_animation_finished)
animation_looped.connect(_on_animation_finished)
animation_changed.connect(_on_animation_start) animation_changed.connect(_on_animation_start)
animation_looped.connect(_on_animation_start) animation_looped.connect(_on_animation_start)
animation_finished.connect(_on_animation_finished)
animation_looped.connect(_on_animation_finished)
func _debug_mov_projection():
_load_config()
if debug_mov_animation and animation_mov_dict.has(debug_mov_animation):
var mov_config = animation_mov_dict[debug_mov_animation]
# 展示 accumulated animation 的目标位置
debug_mov_onion_sprite2d.position.x = mov_config.movement_x
debug_mov_onion_sprite2d.texture = sprite_frames.get_frame_texture(debug_mov_animation, 0)
elif debug_mov_animation:
printerr("Debug move config not found:", debug_mov_animation)
func _load_config(): func _load_config():
@ -74,7 +97,7 @@ func _load_config():
move_configs[i].merge(MOVE_CONFIG) move_configs[i].merge(MOVE_CONFIG)
var move_config = move_configs[i] var move_config = move_configs[i]
if sprite_frames and sprite_frames.has_animation(move_config.animation): if sprite_frames and sprite_frames.has_animation(move_config.animation):
animation_velocity[move_config.animation] = move_config.velocity animation_mov_dict[move_config.animation] = move_config
func _on_frame_changed(): func _on_frame_changed():
@ -110,24 +133,46 @@ func _on_animation_finished() -> void:
var velocity := Vector2.ZERO var velocity := Vector2.ZERO
var mov_x := 0.0
var mov_x_next_animation := ""
var accumulated_mov_x := 0.0
var prev_animation := ""
func _on_animation_start(): func _on_animation_start():
if not animation or not animation_velocity.has(animation): if prev_animation != animation:
velocity = Vector2.ZERO accumulated_mov_x = 0.0
prev_animation = animation
velocity = Vector2.ZERO
mov_x = 0.0
mov_x_next_animation = ""
if not animation or not animation_mov_dict.has(animation):
return return
velocity = animation_velocity[animation] * speed_scale # velocity = animation_mov_dict[animation] * speed_scale
# if GlobalConfig.DEBUG: velocity = animation_mov_dict[animation].velocity
# print("animation ", animation, " velocity=", velocity) mov_x_next_animation = animation_mov_dict[animation].animation_next
if mov_x_next_animation:
# 只有在 next animation 存在时mov_x 才有意义
mov_x = animation_mov_dict[animation].movement_x
func _physics_process(delta: float) -> void: func _physics_process(delta: float) -> void:
if Engine.is_editor_hint() or not velocity or not is_playing(): if Engine.is_editor_hint() or not velocity or not is_playing():
return return
var diff_x = velocity.x * delta
if flip_h: if flip_h:
position.x -= velocity.x * delta position.x -= diff_x
else: else:
position.x += velocity.x * delta position.x += diff_x
# 检查是否切换 animation
if mov_x != 0.0 and mov_x_next_animation:
accumulated_mov_x += diff_x
if absf(accumulated_mov_x) >= absf(mov_x):
if GlobalConfig.DEBUG:
print(
"切换 animation:", mov_x_next_animation, " accumulated_mov_x=", accumulated_mov_x
)
play(mov_x_next_animation)
if not velocity.y: if not velocity.y:
return return
if flip_v: if flip_v:
@ -138,7 +183,9 @@ func _physics_process(delta: float) -> void:
# temporary set velocity # temporary set velocity
func set_animation_velocity(anim: String, v: Vector2) -> void: func set_animation_velocity(anim: String, v: Vector2) -> void:
animation_velocity[anim] = v if not animation_mov_dict.has(anim):
animation_mov_dict[anim] = new_move_config()
animation_mov_dict[anim].velocity = v
if GlobalConfig.DEBUG: if GlobalConfig.DEBUG:
print("set_animation_velocity:", anim, v) print("set_animation_velocity:", anim, v)

View File

@ -3,5 +3,7 @@
[ext_resource type="Script" uid="uid://cphfob11f7atx" path="res://addons/property-inspector/pro_animation_sprite2d/pro_animated_sprite.gd" id="1_21eda"] [ext_resource type="Script" uid="uid://cphfob11f7atx" path="res://addons/property-inspector/pro_animation_sprite2d/pro_animated_sprite.gd" id="1_21eda"]
[node name="AutoplayAnimatedSprite" type="AnimatedSprite2D"] [node name="AutoplayAnimatedSprite" type="AnimatedSprite2D"]
position = Vector2(-1, -1)
script = ExtResource("1_21eda") script = ExtResource("1_21eda")
[node name="DebugMovOnionSkinSprite2D" type="Sprite2D" parent="."]
modulate = Color(1, 1, 1, 0.501961)

View File

@ -72,11 +72,41 @@ func _add_line(check_updating := false):
h_box.add_child(line_edit) h_box.add_child(line_edit)
line_edit.focus_exited.connect(_on_line_edit_text_submitted.bind(line_edit, id, "velocity:y")) line_edit.focus_exited.connect(_on_line_edit_text_submitted.bind(line_edit, id, "velocity:y"))
line_edit.text_submitted.connect(_on_line_edit_text_submitted.bind(id, "velocity:y")) line_edit.text_submitted.connect(_on_line_edit_text_submitted.bind(id, "velocity:y"))
# next row
line_box.add_child(h_box)
h_box = HBoxContainer.new()
# add label
label = Label.new()
label.text = "mov_x:"
h_box.add_child(label)
# add movement_x edit
line_edit = LineEdit.new()
line_edit.text = str(prop.movement_x)
h_box.add_child(line_edit)
line_edit.expand_to_text_length = true
line_edit.focus_exited.connect(
_on_line_edit_text_submitted.bind(line_edit, id, "movement_x")
)
line_edit.text_submitted.connect(_on_line_edit_text_submitted.bind(id, "movement_x"))
# add label
label = Label.new()
label.text = "next:"
h_box.add_child(label)
# add animation next edit
line_edit = LineEdit.new()
line_edit.text = str(prop.animation_next)
h_box.add_child(line_edit)
line_edit.expand_to_text_length = true
line_edit.focus_exited.connect(
_on_line_edit_text_submitted.bind(line_edit, id, "animation_next")
)
line_edit.text_submitted.connect(_on_line_edit_text_submitted.bind(id, "animation_next"))
# add delete button # add delete button
var button = Button.new() var button = Button.new()
button.icon = EditorInterface.get_editor_theme().get_icon("Remove", "EditorIcons") button.icon = EditorInterface.get_editor_theme().get_icon("Remove", "EditorIcons")
button.pressed.connect(_on_delete_button_pressed.bind(id)) button.pressed.connect(_on_delete_button_pressed.bind(id))
h_box.add_child(button) h_box.add_child(button)
# finish
line_box.add_child(h_box) line_box.add_child(h_box)
v_box.add_child(line_box) v_box.add_child(line_box)
line_nodes.append(line_box) line_nodes.append(line_box)
@ -126,6 +156,10 @@ func _on_line_edit_text_submitted(text, id, property):
_get_property()[id]["velocity"].y = float(text) _get_property()[id]["velocity"].y = float(text)
elif property == "duration": elif property == "duration":
_get_property()[id]["duration"] = float(text) _get_property()[id]["duration"] = float(text)
elif property == "movement_x":
_get_property()[id]["movement_x"] = float(text)
elif property == "animation_next":
_get_property()[id]["animation_next"] = text
_update_change() _update_change()

View File

@ -1,4 +1,7 @@
class_name StateMoveConfigResource extends Resource class_name StateMoveConfigResource extends Resource
@export var animation := "" @export var animation := ""
@export var velocity := Vector2(0, 0) @export var velocity := Vector2(0, 0)
# 如果 movement_x != 0 (可正可负), 移动 movement_x 后播放 animation_next
@export var movement_x := 0.0
@export var animation_next := ""

View File

@ -3,80 +3,16 @@ class_name Sfx2D extends AudioStreamPlayer2D
@export var loop := false @export var loop := false
const sfx_root_path = "res://asset/audio/sfx/"
@export_enum("child", "ghost", "lvping", "ui", "c01", "c02") var dir := "ui":
set(value):
dir = value
if Engine.is_editor_hint():
_update_files()
var file: String
var current_files := PackedStringArray()
func _ready() -> void: func _ready() -> void:
bus = &"game_sfx" bus = &"game_sfx"
finished.connect(_on_finished) finished.connect(_on_finished)
# TODO 暂时停用其额外效果
# # 仅在编辑器模式下加载音频 stream
# if Engine.is_editor_hint():
# _update_files()
# _reload_sfx()
# notify_property_list_changed()
func _on_finished() -> void: func _on_finished() -> void:
if loop: if loop:
play() play()
func _reload_sfx():
var path = sfx_root_path + dir + "/" + file
if file and dir and FileAccess.file_exists(path):
stream = load(sfx_root_path + dir + "/" + file) as AudioStream
if stream:
print("sfx2d [", name, "] stream=", stream.resource_path)
else:
print("sfx2d [", name, "] stream is null")
func _update_files():
current_files.clear()
if not dir:
return
var dir_access := DirAccess.open(sfx_root_path + dir) as DirAccess
if not dir_access:
push_warning("sfx2d dir_access is null for ", sfx_root_path + dir)
return
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)
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
# queue free 导致 sfx 无法播放,使用全局声源 # queue free 导致 sfx 无法播放,使用全局声源
func global_play() -> void: func global_play() -> void:
if stream: if stream:

View File

@ -189,7 +189,8 @@ func _unhandled_input(event: InputEvent) -> void:
return return
# if lock_on_player_freezed and SceneManager.is_palyer_freezed_or_locked(): # if lock_on_player_freezed and SceneManager.is_palyer_freezed_or_locked():
# return # return
if SceneManager.get_player().action_locked: var player = SceneManager.get_player()
if not player or player.action_locked:
return return
if activated: if activated:
if event.is_action_pressed("interact"): if event.is_action_pressed("interact"):

View File

@ -638,6 +638,7 @@ animation = &"小婵_被霸凌"
autoplay = "小婵_被霸凌" autoplay = "小婵_被霸凌"
frame = 5 frame = 5
frame_progress = 0.248369 frame_progress = 0.248369
debug_mov_animation = null
[node name="f1" parent="Ground/DeployLayer/霸凌" instance=ExtResource("33_ycojw")] [node name="f1" parent="Ground/DeployLayer/霸凌" instance=ExtResource("33_ycojw")]
z_index = 10 z_index = 10
@ -645,6 +646,7 @@ position = Vector2(-11, 1)
sprite_frames = ExtResource("34_1tart") sprite_frames = ExtResource("34_1tart")
animation = &"霸凌1" animation = &"霸凌1"
autoplay = "霸凌1" autoplay = "霸凌1"
debug_mov_animation = null
[node name="f2" parent="Ground/DeployLayer/霸凌" instance=ExtResource("33_ycojw")] [node name="f2" parent="Ground/DeployLayer/霸凌" instance=ExtResource("33_ycojw")]
z_index = 10 z_index = 10
@ -652,6 +654,7 @@ position = Vector2(23, 11)
sprite_frames = ExtResource("34_1tart") sprite_frames = ExtResource("34_1tart")
animation = &"霸凌2" animation = &"霸凌2"
autoplay = "霸凌2" autoplay = "霸凌2"
debug_mov_animation = null
[node name="f3" parent="Ground/DeployLayer/霸凌" instance=ExtResource("33_ycojw")] [node name="f3" parent="Ground/DeployLayer/霸凌" instance=ExtResource("33_ycojw")]
z_index = 10 z_index = 10
@ -659,6 +662,7 @@ position = Vector2(57, 7)
sprite_frames = ExtResource("34_1tart") sprite_frames = ExtResource("34_1tart")
animation = &"霸凌3" animation = &"霸凌3"
autoplay = "霸凌3" autoplay = "霸凌3"
debug_mov_animation = null
[node name="Ambush点火游戏阻挡右移" parent="Ground/DeployLayer/霸凌" instance=ExtResource("25_iyaiw")] [node name="Ambush点火游戏阻挡右移" parent="Ground/DeployLayer/霸凌" instance=ExtResource("25_iyaiw")]
position = Vector2(-116, -13) position = Vector2(-116, -13)

View File

@ -118,7 +118,8 @@ func _c02_final_show():
var player = SceneManager.get_player() var player = SceneManager.get_player()
player.set_facing_direction(Vector2(-1, 0)) player.set_facing_direction(Vector2(-1, 0))
SceneManager.freeze_player(0) SceneManager.freeze_player(0)
play("c02_final_show") play("c02_final_show_join")
play("c02_final_show_quit")
# WARN: 如果不延时,开场直接显示 dialog 可能会显示失败(无报错提示) # WARN: 如果不延时,开场直接显示 dialog 可能会显示失败(无报错提示)
await get_tree().create_timer(0.1).timeout await get_tree().create_timer(0.1).timeout
player.global_position.x = 650 player.global_position.x = 650
@ -127,8 +128,9 @@ func _c02_final_show():
await DialogueManager.dialogue_ended await DialogueManager.dialogue_ended
# 瞎子打断 # 瞎子打断
DialogueManager.show_dialogue_balloon(dialogue_c02, "c02_s11_谢幕交谈2") DialogueManager.show_dialogue_balloon(dialogue_c02, "c02_s11_谢幕交谈2")
_final_show_end()
func _c02_final_show_end(): func _final_show_end():
SceneManager.release_player() SceneManager.release_player()
ArchiveManager.set_global_entry("c02_burning_end", true) ArchiveManager.set_global_entry("c02_burning_end", true)

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=30 format=3 uid="uid://cootarwb44vvh"] [gd_scene load_steps=31 format=3 uid="uid://cootarwb44vvh"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_qkymk"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_qkymk"]
[ext_resource type="Script" uid="uid://cbt0ubygchxvv" path="res://scene/ground/scene/c02/s06_animation.gd" id="2_4dg6u"] [ext_resource type="Script" uid="uid://cbt0ubygchxvv" path="res://scene/ground/scene/c02/s06_animation.gd" id="2_4dg6u"]
@ -41,31 +41,31 @@ tracks/0/keys = {
tracks/1/type = "value" tracks/1/type = "value"
tracks/1/imported = false tracks/1/imported = false
tracks/1/enabled = true tracks/1/enabled = true
tracks/1/path = NodePath("DeployLayer/c02_final/瞎子:position") tracks/1/path = NodePath("DeployLayer/煤油灯:gaslight_energy")
tracks/1/interp = 1 tracks/1/interp = 1
tracks/1/loop_wrap = true tracks/1/loop_wrap = true
tracks/1/keys = { tracks/1/keys = {
"times": PackedFloat32Array(0), "times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1), "transitions": PackedFloat32Array(1),
"update": 0, "update": 0,
"values": [Vector2(475, 41.5)] "values": [2.0]
} }
tracks/2/type = "value" tracks/2/type = "value"
tracks/2/imported = false tracks/2/imported = false
tracks/2/enabled = true tracks/2/enabled = true
tracks/2/path = NodePath("DeployLayer/c02_final/胖子:position") tracks/2/path = NodePath("DeployLayer/煤油灯:gaslight_ground_energy")
tracks/2/interp = 1 tracks/2/interp = 1
tracks/2/loop_wrap = true tracks/2/loop_wrap = true
tracks/2/keys = { tracks/2/keys = {
"times": PackedFloat32Array(0), "times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1), "transitions": PackedFloat32Array(1),
"update": 0, "update": 0,
"values": [Vector2(501, 33.5)] "values": [2.0]
} }
tracks/3/type = "value" tracks/3/type = "value"
tracks/3/imported = false tracks/3/imported = false
tracks/3/enabled = true tracks/3/enabled = true
tracks/3/path = NodePath("DeployLayer/c02_final:visible") tracks/3/path = NodePath("DeployLayer/疯子撞墙:visible")
tracks/3/interp = 1 tracks/3/interp = 1
tracks/3/loop_wrap = true tracks/3/loop_wrap = true
tracks/3/keys = { tracks/3/keys = {
@ -77,31 +77,31 @@ tracks/3/keys = {
tracks/4/type = "value" tracks/4/type = "value"
tracks/4/imported = false tracks/4/imported = false
tracks/4/enabled = true tracks/4/enabled = true
tracks/4/path = NodePath("DeployLayer/煤油灯:gaslight_energy") tracks/4/path = NodePath("DeployLayer/疯子撞墙:position")
tracks/4/interp = 1 tracks/4/interp = 1
tracks/4/loop_wrap = true tracks/4/loop_wrap = true
tracks/4/keys = { tracks/4/keys = {
"times": PackedFloat32Array(0), "times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1), "transitions": PackedFloat32Array(1),
"update": 0, "update": 0,
"values": [2.0] "values": [Vector2(221, 4)]
} }
tracks/5/type = "value" tracks/5/type = "value"
tracks/5/imported = false tracks/5/imported = false
tracks/5/enabled = true tracks/5/enabled = true
tracks/5/path = NodePath("DeployLayer/煤油灯:gaslight_ground_energy") tracks/5/path = NodePath("DeployLayer/疯子撞墙:animation")
tracks/5/interp = 1 tracks/5/interp = 1
tracks/5/loop_wrap = true tracks/5/loop_wrap = true
tracks/5/keys = { tracks/5/keys = {
"times": PackedFloat32Array(0), "times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1), "transitions": PackedFloat32Array(1),
"update": 0, "update": 1,
"values": [2.0] "values": [&"疯子跑动"]
} }
tracks/6/type = "value" tracks/6/type = "value"
tracks/6/imported = false tracks/6/imported = false
tracks/6/enabled = true tracks/6/enabled = true
tracks/6/path = NodePath("DeployLayer/疯子撞墙:visible") tracks/6/path = NodePath("DeployLayer/疯子撞墙/疯子撞墙Sfx2D:playing")
tracks/6/interp = 1 tracks/6/interp = 1
tracks/6/loop_wrap = true tracks/6/loop_wrap = true
tracks/6/keys = { tracks/6/keys = {
@ -110,133 +110,62 @@ tracks/6/keys = {
"update": 1, "update": 1,
"values": [false] "values": [false]
} }
tracks/7/type = "value"
tracks/7/imported = false
tracks/7/enabled = true
tracks/7/path = NodePath("DeployLayer/疯子撞墙:position")
tracks/7/interp = 1
tracks/7/loop_wrap = true
tracks/7/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(221, 4)]
}
tracks/8/type = "value"
tracks/8/imported = false
tracks/8/enabled = true
tracks/8/path = NodePath("DeployLayer/疯子撞墙:animation")
tracks/8/interp = 1
tracks/8/loop_wrap = true
tracks/8/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [&"疯子跑动"]
}
tracks/9/type = "value"
tracks/9/imported = false
tracks/9/enabled = true
tracks/9/path = NodePath("DeployLayer/疯子撞墙/疯子撞墙Sfx2D:playing")
tracks/9/interp = 1
tracks/9/loop_wrap = true
tracks/9/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
[sub_resource type="Animation" id="Animation_ciatp"] [sub_resource type="Animation" id="Animation_ciatp"]
resource_name = "c02_final_show" resource_name = "c02_final_show_join"
length = 22.0 length = 22.0
tracks/0/type = "method" tracks/0/type = "value"
tracks/0/imported = false tracks/0/imported = false
tracks/0/enabled = true tracks/0/enabled = true
tracks/0/path = NodePath("AnimationPlayer") tracks/0/path = NodePath("DeployLayer/c02_final/PointLight2D:energy")
tracks/0/interp = 1 tracks/0/interp = 1
tracks/0/loop_wrap = true tracks/0/loop_wrap = true
tracks/0/keys = { tracks/0/keys = {
"times": PackedFloat32Array(20.8333),
"transitions": PackedFloat32Array(1),
"values": [{
"args": [],
"method": &"_c02_final_show_end"
}]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("DeployLayer/c02_final/PointLight2D:energy")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(1.13333, 2.53333, 14.8333, 16.6333), "times": PackedFloat32Array(1.13333, 2.53333, 14.8333, 16.6333),
"transitions": PackedFloat32Array(1, 1, 1, 1), "transitions": PackedFloat32Array(1, 1, 1, 1),
"update": 0, "update": 0,
"values": [0.0, 2.0, 2.0, 0.0] "values": [0.0, 2.0, 2.0, 0.0]
} }
tracks/2/type = "value" tracks/1/type = "value"
tracks/2/imported = false tracks/1/imported = false
tracks/2/enabled = true tracks/1/enabled = true
tracks/2/path = NodePath("DeployLayer/c02_final/瞎子:position") tracks/1/path = NodePath("DeployLayer/c02_final:visible")
tracks/2/interp = 1 tracks/1/interp = 1
tracks/2/loop_wrap = true tracks/1/loop_wrap = true
tracks/2/keys = { tracks/1/keys = {
"times": PackedFloat32Array(0, 2.7, 9.1),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Vector2(0, 41.5), Vector2(0, 41.5), Vector2(557, 34)]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("DeployLayer/c02_final/胖子:position")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0, 2.7, 9.1),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Vector2(0, 41.5), Vector2(0, 41.5), Vector2(580, 25)]
}
tracks/4/type = "value"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("DeployLayer/c02_final:visible")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(0.0333333, 18.8), "times": PackedFloat32Array(0.0333333, 18.8),
"transitions": PackedFloat32Array(1, 1), "transitions": PackedFloat32Array(1, 1),
"update": 1, "update": 1,
"values": [true, false] "values": [true, false]
} }
tracks/5/type = "value" tracks/2/type = "value"
tracks/5/imported = false tracks/2/imported = false
tracks/5/enabled = true tracks/2/enabled = true
tracks/5/path = NodePath("DeployLayer/煤油灯:gaslight_energy") tracks/2/path = NodePath("DeployLayer/煤油灯:gaslight_energy")
tracks/5/interp = 1 tracks/2/interp = 1
tracks/5/loop_wrap = true tracks/2/loop_wrap = true
tracks/5/keys = { tracks/2/keys = {
"times": PackedFloat32Array(0, 1.33333), "times": PackedFloat32Array(0, 1.33333),
"transitions": PackedFloat32Array(1, 1), "transitions": PackedFloat32Array(1, 1),
"update": 0, "update": 0,
"values": [0.0, 2.0] "values": [0.0, 2.0]
} }
tracks/6/type = "value" tracks/3/type = "value"
tracks/6/imported = false tracks/3/imported = false
tracks/6/enabled = true tracks/3/enabled = true
tracks/6/path = NodePath("DeployLayer/煤油灯:gaslight_ground_energy") tracks/3/path = NodePath("DeployLayer/煤油灯:gaslight_ground_energy")
tracks/6/interp = 1 tracks/3/interp = 1
tracks/6/loop_wrap = true tracks/3/loop_wrap = true
tracks/6/keys = { tracks/3/keys = {
"times": PackedFloat32Array(0, 1.33333), "times": PackedFloat32Array(0, 1.33333),
"transitions": PackedFloat32Array(1, 1), "transitions": PackedFloat32Array(1, 1),
"update": 0, "update": 0,
"values": [0.0, 2.0] "values": [0.0, 2.0]
} }
[sub_resource type="Animation" id="Animation_yolsv"]
resource_name = "c02_final_show_quit"
[sub_resource type="Animation" id="Animation_p6da7"] [sub_resource type="Animation" id="Animation_p6da7"]
resource_name = "疯子撞墙" resource_name = "疯子撞墙"
length = 6.0 length = 6.0
@ -292,7 +221,8 @@ tracks/3/keys = {
[sub_resource type="AnimationLibrary" id="AnimationLibrary_k01ve"] [sub_resource type="AnimationLibrary" id="AnimationLibrary_k01ve"]
_data = { _data = {
&"RESET": SubResource("Animation_k01ve"), &"RESET": SubResource("Animation_k01ve"),
&"c02_final_show": SubResource("Animation_ciatp"), &"c02_final_show_join": SubResource("Animation_ciatp"),
&"c02_final_show_quit": SubResource("Animation_yolsv"),
&"疯子撞墙": SubResource("Animation_p6da7") &"疯子撞墙": SubResource("Animation_p6da7")
} }
@ -313,7 +243,6 @@ fill_to = Vector2(1, 1)
[node name="Ground" parent="." instance=ExtResource("1_qkymk")] [node name="Ground" parent="." instance=ExtResource("1_qkymk")]
scene_name = "c02_s06" scene_name = "c02_s06"
player_y = 60 player_y = 60
main_scene = null
[node name="AnimationPlayer" parent="Ground" index="0"] [node name="AnimationPlayer" parent="Ground" index="0"]
libraries = { libraries = {
@ -337,6 +266,16 @@ mode = "场景背景音"
"感应玩家操作" = false "感应玩家操作" = false
metadata/_custom_type_script = "uid://rq6w1vuhuq1m" metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="Sfx翻找东西" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="1"]
bus = &"game_sfx"
script = ExtResource("4_2e08x")
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="Sfx擦亮火柴" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="2"]
bus = &"game_sfx"
script = ExtResource("4_2e08x")
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="BGSprite2D" parent="Ground" index="1"] [node name="BGSprite2D" parent="Ground" index="1"]
light_mask = 5 light_mask = 5
position = Vector2(0, -2) position = Vector2(0, -2)
@ -413,7 +352,7 @@ max_distance = 600.0
attenuation = 3.0 attenuation = 3.0
bus = &"game_sfx" bus = &"game_sfx"
script = ExtResource("14_7x2h6") script = ExtResource("14_7x2h6")
file = "" loop = true
metadata/_custom_type_script = "uid://wapo47a1oddf" metadata/_custom_type_script = "uid://wapo47a1oddf"
[node name="Ambush三男孩" parent="Ground/DeployLayer" index="9" instance=ExtResource("14_k01ve")] [node name="Ambush三男孩" parent="Ground/DeployLayer" index="9" instance=ExtResource("14_k01ve")]
@ -442,19 +381,33 @@ position = Vector2(289, 16)
packed_scene = ExtResource("16_p6da7") packed_scene = ExtResource("16_p6da7")
[node name="c02_final" type="Node2D" parent="Ground/DeployLayer" index="12"] [node name="c02_final" type="Node2D" parent="Ground/DeployLayer" index="12"]
visible = false
[node name="胖子" type="AnimatedSprite2D" parent="Ground/DeployLayer/c02_final"] [node name="瞎子" parent="Ground/DeployLayer/c02_final" instance=ExtResource("10_p6da7")]
position = Vector2(501, 33.5) position = Vector2(277, 29)
sprite_frames = ExtResource("15_k01ve") sprite_frames = ExtResource("15_k01ve")
animation = &"小婵走路" animation = &"方瞎子走路-右"
autoplay = "胖子" move_configs = Array[Dictionary]([{
"animation": "方瞎子走路-右",
"animation_next": "方瞎子呼吸-右",
"duration": 1e+07,
"movement_x": 300.0,
"velocity": Vector2(50, 0)
}])
debug_mov_animation = "方瞎子走路-右"
[node name="瞎子" type="AnimatedSprite2D" parent="Ground/DeployLayer/c02_final"] [node name="胖子" parent="Ground/DeployLayer/c02_final" instance=ExtResource("10_p6da7")]
position = Vector2(475, 41.5) position = Vector2(233, 33)
sprite_frames = ExtResource("15_k01ve") sprite_frames = ExtResource("15_k01ve")
animation = &"瞎子" animation = &"胖子走路"
autoplay = "瞎子" autostart = false
move_configs = Array[Dictionary]([{
"animation": "胖子走路",
"animation_next": "胖子呼吸",
"duration": 1e+07,
"movement_x": 300.0,
"velocity": Vector2(60, 0)
}])
debug_mov_animation = "胖子走路"
[node name="小蝉" type="AnimatedSprite2D" parent="Ground/DeployLayer/c02_final"] [node name="小蝉" type="AnimatedSprite2D" parent="Ground/DeployLayer/c02_final"]
position = Vector2(585, 82) position = Vector2(585, 82)
@ -485,6 +438,4 @@ visible = false
energy = 0.9 energy = 0.9
blend_mode = 1 blend_mode = 1
[connection signal="finished" from="Ground/DeployLayer/疯子撞墙/疯子撞墙Sfx2D" to="Ground/DeployLayer/疯子撞墙/疯子撞墙Sfx2D" method="play"]
[editable path="Ground"] [editable path="Ground"]

View File

@ -54,12 +54,11 @@ func _ready() -> void:
point_light_ground.position.y = ground_height_offset point_light_ground.position.y = ground_height_offset
place_sprite2d.visible = not hide_texture place_sprite2d.visible = not hide_texture
point_light.texture = gaslight_texture
point_light.energy = gaslight_energy
point_light_ground.texture = ground_light_texture
point_light_ground.energy = gaslight_ground_energy
if Engine.is_editor_hint(): if Engine.is_editor_hint():
point_light.texture = gaslight_texture
point_light.energy = gaslight_energy
point_light_ground.texture = ground_light_texture
point_light_ground.energy = gaslight_ground_energy
_switch_gaslight(debug_light_switch) _switch_gaslight(debug_light_switch)
return return

View File

@ -11,17 +11,23 @@ signal exit(success: bool)
var image: Image var image: Image
var show_childhood := false
func _ready() -> void: func _ready() -> void:
# 第三章设置为启用 c03_meta_enabled
show_childhood = ArchiveManager.get_global_value("c03_meta_enabled", false)
layer = GlobalConfig.CANVAS_LAYER_LITTLE_GAME layer = GlobalConfig.CANVAS_LAYER_LITTLE_GAME
image = ripple.texture.get_image() image = ripple.texture.get_image()
shader.gui_input.connect(_shader_input) shader.gui_input.connect(_shader_input)
timer.timeout.connect(_try_ripple) timer.timeout.connect(_try_ripple)
shader.material.set("shader_parameter/amplitude", 0.0) shader.material.set("shader_parameter/amplitude", 0.0)
# 幼年 -> 成年 # 幼年 -> 成年
var tween = create_tween() as Tween if show_childhood:
tween.tween_interval(1.5) var tween = create_tween() as Tween
tween.tween_property(child_sprite, "modulate:a", 0.0, 0.5) tween.tween_interval(1.5)
tween.tween_property(child_sprite, "modulate:a", 0.0, 0.5)
else:
child_sprite.modulate.a = 0
await get_tree().create_timer(1.5).timeout
_try_ripple() _try_ripple()
func _try_ripple(): func _try_ripple():
@ -59,10 +65,12 @@ func _make_ripple(pos:Vector2) -> bool:
ripple_tween.kill() ripple_tween.kill()
ripple_tween = create_tween() ripple_tween = create_tween()
ripple_tween.tween_property(shader.material, "shader_parameter/amplitude", 2.0, 0.3) ripple_tween.tween_property(shader.material, "shader_parameter/amplitude", 2.0, 0.3)
ripple_tween.parallel().tween_property(child_sprite, "modulate:a", 1.0, 0.2) if show_childhood:
ripple_tween.parallel().tween_property(grownup_sprite, "modulate:a", 0.5, 0.2) ripple_tween.parallel().tween_property(child_sprite, "modulate:a", 1.0, 0.2)
ripple_tween.parallel().tween_property(grownup_sprite, "modulate:a", 0.5, 0.2)
ripple_tween.tween_property(shader.material, "shader_parameter/amplitude", 0.0, 2.0) ripple_tween.tween_property(shader.material, "shader_parameter/amplitude", 0.0, 2.0)
ripple_tween.parallel().tween_property(child_sprite, "modulate:a", 0.0, 1.0) if show_childhood:
ripple_tween.parallel().tween_property(grownup_sprite, "modulate:a", 1.0, 1.5) ripple_tween.parallel().tween_property(child_sprite, "modulate:a", 0.0, 1.0)
ripple_tween.parallel().tween_property(grownup_sprite, "modulate:a", 1.0, 1.5)
return true return true
return false return false