ProAnimatedSprite2D 配置项跳过保存默认值,有利于统一控制、变更默认值

This commit is contained in:
cakipaul 2025-01-23 22:21:53 +08:00
parent b58cbe3e66
commit dee479d4ab
6 changed files with 93 additions and 81 deletions

View File

@ -28,6 +28,7 @@ ProAnimatedSprite2D增强 AnimatedSprite2D 的表现,在其基础上增加
1. action configs 配置动画跳转逻辑 1. action configs 配置动画跳转逻辑
2. move configs 配置播放特定动画时的移动速度 2. move configs 配置播放特定动画时的移动速度
3. ProAnimatedSprite2D 配置项跳过保存默认值,有利于统一控制、变更默认值
## Ground 与 GroundLoader ## Ground 与 GroundLoader

View File

@ -2,18 +2,7 @@
class_name ProAnimatedSprite2D extends AnimatedSprite2D class_name ProAnimatedSprite2D extends AnimatedSprite2D
@export var autostart := true @export var autostart := true
# 从 intro 到 next 的配置信息
# {
# "animation_intro": "",
# "intro_loop": 1,
# "animation_wait_time": 0.0,
# "animation_next": ""
# }
@export var action_configs: Array[Dictionary] = [] @export var action_configs: Array[Dictionary] = []
# {
# "animation": "",
# "velocity": Vector2(0, 0)
# }
@export var move_configs: Array[Dictionary] = [] @export var move_configs: Array[Dictionary] = []
# 从 intro 到 next 的配置信息 # 从 intro 到 next 的配置信息
@ -25,6 +14,20 @@ var animation_velocity = {
# animation -> velocity # animation -> velocity
} }
const ACTION_CONFIG = {
"animation_intro": "", "intro_loop": 1, "animation_wait_time": 0.0, "animation_next": ""
}
const MOVE_CONFIG = {"animation": "", "velocity": Vector2.ZERO, "duration": 10000000.0}
static func new_move_config() -> Dictionary:
return MOVE_CONFIG.duplicate()
static func new_action_config() -> Dictionary:
return ACTION_CONFIG.duplicate()
func _ready() -> void: func _ready() -> void:
if Engine.is_editor_hint(): if Engine.is_editor_hint():
@ -42,6 +45,7 @@ func _ready() -> void:
func _load_config(): func _load_config():
# load auto_checkout_dict # load auto_checkout_dict
for i in range(action_configs.size()): for i in range(action_configs.size()):
action_configs[i].merge(ACTION_CONFIG)
var state_config = action_configs[i] var state_config = action_configs[i]
if sprite_frames and sprite_frames.has_animation(state_config.animation_intro): if sprite_frames and sprite_frames.has_animation(state_config.animation_intro):
# intro 的 animation 关闭循环 # intro 的 animation 关闭循环
@ -49,6 +53,7 @@ func _load_config():
auto_checkout_dict[state_config.animation_intro] = action_configs[i] auto_checkout_dict[state_config.animation_intro] = action_configs[i]
# load animation_frame_offsets # load animation_frame_offsets
for i in range(move_configs.size()): for i in range(move_configs.size()):
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_velocity[move_config.animation] = move_config.velocity

View File

@ -22,18 +22,16 @@ func _init():
# Make sure the control is able to retain the focus. # Make sure the control is able to retain the focus.
add_focusable(v_box) add_focusable(v_box)
func _add_line(check_updating := false): func _add_line(check_updating := false):
if check_updating and updating: if check_updating and updating:
return return
var updated := false
# 最后一个是 add button所以 -1 # 最后一个是 add button所以 -1
var id = line_nodes.size() var id = line_nodes.size()
if id >= _get_property().size(): if id >= _get_property().size():
_get_property().append(_new_res()) _get_property().append(_new_res())
updated = true var prop = _get_property()[id].duplicate()
if _get_property()[id].is_empty(): prop.merge(ProAnimatedSprite2D.ACTION_CONFIG)
_get_property()[id] = _new_res()
updated = true
var line_box = VBoxContainer.new() var line_box = VBoxContainer.new()
line_box.add_child(HSeparator.new()) line_box.add_child(HSeparator.new())
var h_box = HBoxContainer.new() var h_box = HBoxContainer.new()
@ -43,11 +41,13 @@ func _add_line(check_updating := false):
h_box.add_child(label) h_box.add_child(label)
# add animation intro line edit # add animation intro line edit
var line_edit = LineEdit.new() var line_edit = LineEdit.new()
line_edit.text = str(_get_property()[id].animation_intro) line_edit.text = str(prop.animation_intro)
h_box.add_child(line_edit) h_box.add_child(line_edit)
# line_edit.custom_minimum_size.x = 50 # line_edit.custom_minimum_size.x = 50
line_edit.expand_to_text_length = true line_edit.expand_to_text_length = true
line_edit.focus_exited.connect(_on_line_edit_text_submitted.bind(line_edit, id, "animation_intro")) line_edit.focus_exited.connect(
_on_line_edit_text_submitted.bind(line_edit, id, "animation_intro")
)
line_edit.text_submitted.connect(_on_line_edit_text_submitted.bind(id, "animation_intro")) line_edit.text_submitted.connect(_on_line_edit_text_submitted.bind(id, "animation_intro"))
# next row # next row
line_box.add_child(h_box) line_box.add_child(h_box)
@ -58,7 +58,7 @@ func _add_line(check_updating := false):
h_box.add_child(label) h_box.add_child(label)
# add line edit # add line edit
line_edit = LineEdit.new() line_edit = LineEdit.new()
line_edit.text = str(_get_property()[id].intro_loop) line_edit.text = str(prop.intro_loop)
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, "intro_loop")) line_edit.focus_exited.connect(_on_line_edit_text_submitted.bind(line_edit, id, "intro_loop"))
line_edit.text_submitted.connect(_on_line_edit_text_submitted.bind(id, "intro_loop")) line_edit.text_submitted.connect(_on_line_edit_text_submitted.bind(id, "intro_loop"))
@ -68,9 +68,11 @@ func _add_line(check_updating := false):
h_box.add_child(label) h_box.add_child(label)
# add line edit # add line edit
line_edit = LineEdit.new() line_edit = LineEdit.new()
line_edit.text = str(_get_property()[id].animation_wait_time) line_edit.text = str(prop.animation_wait_time)
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, "animation_wait_time")) line_edit.focus_exited.connect(
_on_line_edit_text_submitted.bind(line_edit, id, "animation_wait_time")
)
line_edit.text_submitted.connect(_on_line_edit_text_submitted.bind(id, "animation_wait_time")) line_edit.text_submitted.connect(_on_line_edit_text_submitted.bind(id, "animation_wait_time"))
# next row # next row
line_box.add_child(h_box) line_box.add_child(h_box)
@ -81,10 +83,12 @@ func _add_line(check_updating := false):
h_box.add_child(label) h_box.add_child(label)
# add animation next edit # add animation next edit
line_edit = LineEdit.new() line_edit = LineEdit.new()
line_edit.text = str(_get_property()[id].animation_next) line_edit.text = str(prop.animation_next)
h_box.add_child(line_edit) h_box.add_child(line_edit)
line_edit.expand_to_text_length = true 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.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")) 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()
@ -94,22 +98,28 @@ func _add_line(check_updating := false):
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)
if updated: _update_change()
emit_changed(property_name, _get_property())
func _new_res() -> Dictionary: func _new_res() -> Dictionary:
var res = { var res = ProAnimatedSprite2D.new_action_config()
"animation_intro": "",
"intro_loop": 1,
"animation_wait_time": 0.0,
"animation_next": ""
}
if get_edited_object().animation: if get_edited_object().animation:
res.animation_intro = get_edited_object().animation res.animation_intro = get_edited_object().animation
return res return res
func _update_change():
var arr = _get_property()
var default_config = ProAnimatedSprite2D.new_action_config()
# 只保存改动的部分
for i in range(arr.size()):
var config = arr[i]
for key in default_config.keys():
if config.has(key) and config[key] == default_config[key]:
config.erase(key)
emit_changed(property_name, arr)
func _get_property() -> Array[Dictionary]: func _get_property() -> Array[Dictionary]:
return get_edited_object()[property_name] return get_edited_object()[property_name]
@ -128,7 +138,7 @@ func _on_line_edit_text_submitted(text, id, property):
_get_property()[id].animation_wait_time = max(0, float(text)) _get_property()[id].animation_wait_time = max(0, float(text))
elif property == "animation_next": elif property == "animation_next":
_get_property()[id].animation_next = text _get_property()[id].animation_next = text
emit_changed(property_name, _get_property()) _update_change()
func _on_delete_button_pressed(id): func _on_delete_button_pressed(id):
@ -138,12 +148,10 @@ func _on_delete_button_pressed(id):
line_nodes[id].queue_free() line_nodes[id].queue_free()
_get_property().remove_at(id) _get_property().remove_at(id)
refresh_controls() refresh_controls()
emit_changed(property_name, _get_property()) _update_change()
func _update_property(): func _update_property():
# Read the current value from the property.
var new_value = get_edited_object()[property_name]
# Update the control with the new value. # Update the control with the new value.
updating = true updating = true
refresh_controls() refresh_controls()

View File

@ -27,15 +27,12 @@ func _init():
func _add_line(check_updating := false): func _add_line(check_updating := false):
if check_updating and updating: if check_updating and updating:
return return
var updated := false
# 最后一个是 add button所以 -1 # 最后一个是 add button所以 -1
var id = line_nodes.size() var id = line_nodes.size()
if id >= _get_property().size(): if id >= _get_property().size():
_get_property().append(_new_res()) _get_property().append(_new_res())
updated = true var prop = _get_property()[id].duplicate()
if _get_property()[id].is_empty(): prop.merge(ProAnimatedSprite2D.MOVE_CONFIG)
_get_property()[id] = _new_res()
updated = true
var line_box = VBoxContainer.new() var line_box = VBoxContainer.new()
line_box.add_child(HSeparator.new()) line_box.add_child(HSeparator.new())
var h_box = HBoxContainer.new() var h_box = HBoxContainer.new()
@ -45,7 +42,7 @@ func _add_line(check_updating := false):
h_box.add_child(label) h_box.add_child(label)
# add animation line edit # add animation line edit
var line_edit = LineEdit.new() var line_edit = LineEdit.new()
line_edit.text = str(_get_property()[id].animation) line_edit.text = str(prop.animation)
h_box.add_child(line_edit) h_box.add_child(line_edit)
# line_edit.custom_minimum_size.x = 50 # line_edit.custom_minimum_size.x = 50
line_edit.expand_to_text_length = true line_edit.expand_to_text_length = true
@ -59,7 +56,7 @@ func _add_line(check_updating := false):
h_box.add_child(label) h_box.add_child(label)
# add velocity.x line edit # add velocity.x line edit
line_edit = LineEdit.new() line_edit = LineEdit.new()
line_edit.text = str(_get_property()[id].velocity.x) line_edit.text = str(prop.velocity.x)
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:x")) line_edit.focus_exited.connect(_on_line_edit_text_submitted.bind(line_edit, id, "velocity:x"))
line_edit.text_submitted.connect(_on_line_edit_text_submitted.bind(id, "velocity:x")) line_edit.text_submitted.connect(_on_line_edit_text_submitted.bind(id, "velocity:x"))
@ -69,7 +66,7 @@ func _add_line(check_updating := false):
h_box.add_child(label) h_box.add_child(label)
# add velocity.y line edit # add velocity.y line edit
line_edit = LineEdit.new() line_edit = LineEdit.new()
line_edit.text = str(_get_property()[id].velocity.y) line_edit.text = str(prop.velocity.y)
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"))
@ -81,20 +78,28 @@ func _add_line(check_updating := false):
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)
if updated: _update_change()
emit_changed(property_name, _get_property())
func _new_res() -> Dictionary: func _new_res() -> Dictionary:
var res = { var res = ProAnimatedSprite2D.new_move_config()
"animation": "",
"velocity": Vector2(0, 0)
}
if get_edited_object().animation: if get_edited_object().animation:
res.animation = get_edited_object().animation res.animation = get_edited_object().animation
return res return res
func _update_change():
var arr = _get_property()
var default_config = ProAnimatedSprite2D.new_move_config()
# 只保存改动的部分
for i in range(arr.size()):
var config = arr[i]
for key in default_config.keys():
if config.has(key) and config[key] == default_config[key]:
config.erase(key)
emit_changed(property_name, arr)
func _get_property() -> Array[Dictionary]: func _get_property() -> Array[Dictionary]:
return get_edited_object()[property_name] return get_edited_object()[property_name]
@ -106,12 +111,14 @@ func _on_line_edit_text_submitted(text, id, property):
text = text.text text = text.text
# update the property by id # update the property by id
if property == "animation": if property == "animation":
_get_property()[id].animation = text _get_property()[id]["animation"] = text
elif property == "velocity:x": elif property == "velocity:x":
_get_property()[id].velocity.x = float(text) _get_property()[id]["velocity"].x = float(text)
elif property == "velocity:y": elif property == "velocity:y":
_get_property()[id].velocity.y = float(text) _get_property()[id]["velocity"].y = float(text)
emit_changed(property_name, _get_property()) elif property == "duration":
_get_property()[id]["duration"] = float(text)
_update_change()
func _on_delete_button_pressed(id): func _on_delete_button_pressed(id):
@ -121,13 +128,10 @@ func _on_delete_button_pressed(id):
line_nodes[id].queue_free() line_nodes[id].queue_free()
_get_property().remove_at(id) _get_property().remove_at(id)
refresh_controls() refresh_controls()
emit_changed(property_name, _get_property()) _update_change()
func _update_property(): func _update_property():
# Read the current value from the property.
var new_value = get_edited_object()[property_name]
# Update the control with the new value.
updating = true updating = true
refresh_controls() refresh_controls()
updating = false updating = false

View File

@ -421,6 +421,14 @@ animations = [{
}, { }, {
"frames": [{ "frames": [{
"duration": 30.0, "duration": 30.0,
"texture": ExtResource("72_2ac2n")
}],
"loop": true,
"name": &"【胖小孩背着残疾小孩】奔跑",
"speed": 5.0
}, {
"frames": [{
"duration": 30.0,
"texture": ExtResource("76_ksjfk") "texture": ExtResource("76_ksjfk")
}, { }, {
"duration": 30.0, "duration": 30.0,

View File

@ -133,17 +133,14 @@ animation = &"【画画小女孩】呼吸"
action_configs = Array[Dictionary]([{ action_configs = Array[Dictionary]([{
"animation_intro": "【画画小女孩】画画", "animation_intro": "【画画小女孩】画画",
"animation_next": "【画画小女孩】回头", "animation_next": "【画画小女孩】回头",
"animation_wait_time": 0,
"intro_loop": 2 "intro_loop": 2
}, { }, {
"animation_intro": "【画画小女孩】回头", "animation_intro": "【画画小女孩】回头",
"animation_next": "【画画小女孩】呼吸", "animation_next": "【画画小女孩】呼吸",
"animation_wait_time": 1.0, "animation_wait_time": 1.0
"intro_loop": 1
}, { }, {
"animation_intro": &"【画画小女孩】呼吸", "animation_intro": &"【画画小女孩】呼吸",
"animation_next": "【画画小女孩】画画", "animation_next": "【画画小女孩】画画",
"animation_wait_time": 0.0,
"intro_loop": 3 "intro_loop": 3
}]) }])
@ -154,12 +151,10 @@ animation = &"【画画男孩-1】呼吸"
action_configs = Array[Dictionary]([{ action_configs = Array[Dictionary]([{
"animation_intro": "【画画男孩-1】呼吸", "animation_intro": "【画画男孩-1】呼吸",
"animation_next": "【画画男孩-1】画画", "animation_next": "【画画男孩-1】画画",
"animation_wait_time": 0.0,
"intro_loop": 2 "intro_loop": 2
}, { }, {
"animation_intro": "【画画男孩-1】画画", "animation_intro": "【画画男孩-1】画画",
"animation_next": "【画画男孩-1】呼吸", "animation_next": "【画画男孩-1】呼吸",
"animation_wait_time": 0.0,
"intro_loop": 2 "intro_loop": 2
}]) }])
@ -169,13 +164,10 @@ sprite_frames = ExtResource("7_dsj2r")
animation = &"【画画男孩-2】呼吸" animation = &"【画画男孩-2】呼吸"
action_configs = Array[Dictionary]([{ action_configs = Array[Dictionary]([{
"animation_intro": "【画画男孩-2】呼吸", "animation_intro": "【画画男孩-2】呼吸",
"animation_next": "【画画男孩-2】画画", "animation_next": "【画画男孩-2】画画"
"animation_wait_time": 0.0,
"intro_loop": 1
}, { }, {
"animation_intro": "【画画男孩-2】画画", "animation_intro": "【画画男孩-2】画画",
"animation_next": "【画画男孩-2】呼吸", "animation_next": "【画画男孩-2】呼吸",
"animation_wait_time": 0.0,
"intro_loop": 3 "intro_loop": 3
}]) }])
@ -186,13 +178,10 @@ animation = &"【站立小孩-1】侧面呼吸"
action_configs = Array[Dictionary]([{ action_configs = Array[Dictionary]([{
"animation_intro": "【站立小孩-1】侧面呼吸", "animation_intro": "【站立小孩-1】侧面呼吸",
"animation_next": "【站立小孩-1】挠痒呼吸", "animation_next": "【站立小孩-1】挠痒呼吸",
"animation_wait_time": 0,
"intro_loop": 3 "intro_loop": 3
}, { }, {
"animation_intro": "【站立小孩-1】挠痒呼吸", "animation_intro": "【站立小孩-1】挠痒呼吸",
"animation_next": "【站立小孩-1】侧面呼吸", "animation_next": "【站立小孩-1】侧面呼吸"
"animation_wait_time": 0,
"intro_loop": 1
}]) }])
move_configs = Array[Dictionary]([{ move_configs = Array[Dictionary]([{
"animation": &"【站立小孩-1】走路", "animation": &"【站立小孩-1】走路",
@ -205,9 +194,7 @@ sprite_frames = ExtResource("7_dsj2r")
animation = &"【站立小孩-2】呼吸" animation = &"【站立小孩-2】呼吸"
action_configs = Array[Dictionary]([{ action_configs = Array[Dictionary]([{
"animation_intro": &"【站立小孩-2】转身", "animation_intro": &"【站立小孩-2】转身",
"animation_next": "【站立小孩-2】侧面呼吸", "animation_next": "【站立小孩-2】侧面呼吸"
"animation_wait_time": 0,
"intro_loop": 1
}]) }])
move_configs = Array[Dictionary]([{ move_configs = Array[Dictionary]([{
"animation": "【站立小孩-2】走路", "animation": "【站立小孩-2】走路",
@ -220,9 +207,7 @@ sprite_frames = ExtResource("7_dsj2r")
animation = &"【站立小孩-3】呼吸" animation = &"【站立小孩-3】呼吸"
action_configs = Array[Dictionary]([{ action_configs = Array[Dictionary]([{
"animation_intro": &"【站立小孩-3】转身", "animation_intro": &"【站立小孩-3】转身",
"animation_next": "【站立小孩-3】侧面呼吸", "animation_next": "【站立小孩-3】侧面呼吸"
"animation_wait_time": 0.0,
"intro_loop": 1
}]) }])
move_configs = Array[Dictionary]([{ move_configs = Array[Dictionary]([{
"animation": &"【站立小孩-3】走路", "animation": &"【站立小孩-3】走路",
@ -235,15 +220,16 @@ sprite_frames = ExtResource("7_dsj2r")
animation = &"【胖小孩背着残疾小孩】呼吸" animation = &"【胖小孩背着残疾小孩】呼吸"
action_configs = Array[Dictionary]([{ action_configs = Array[Dictionary]([{
"animation_intro": "【胖小孩背着残疾小孩】呼吸", "animation_intro": "【胖小孩背着残疾小孩】呼吸",
"animation_next": "【胖小孩背着残疾小孩】画画", "animation_next": "【胖小孩背着残疾小孩】画画"
"animation_wait_time": 0.0,
"intro_loop": 1
}, { }, {
"animation_intro": "【胖小孩背着残疾小孩】画画", "animation_intro": "【胖小孩背着残疾小孩】画画",
"animation_next": "【胖小孩背着残疾小孩】呼吸", "animation_next": "【胖小孩背着残疾小孩】呼吸",
"animation_wait_time": 0.0,
"intro_loop": 2 "intro_loop": 2
}]) }])
move_configs = Array[Dictionary]([{
"animation": &"【胖小孩背着残疾小孩】奔跑",
"velocity": Vector2(50, 0)
}])
[node name="Note院长房间" parent="Ground/DeployLayer" index="12" instance=ExtResource("12_28t76")] [node name="Note院长房间" parent="Ground/DeployLayer" index="12" instance=ExtResource("12_28t76")]