增加 player 根据所选角色而变化动画的功能;配置小小蝶的动画

This commit is contained in:
cakipaul 2025-01-14 18:20:31 +08:00
parent 12d3c62ff4
commit 4796909ca8
81 changed files with 1566 additions and 939 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1,6 +1,7 @@
keys,zh_CN,en,_character,_notes,_tags
c02_张胖子_招呼吕萍5,“来来来,过来,过来”,"""come on, come on""",张胖子,,[#anonymous]
c02_芦昌路26,芦昌路26弄3号,,,孤寂的氛围 [#wave] [#shake],
c02_吕萍_01_梦楼,“这是梦里的那栋楼”,,,,
c02_吕萍_01_梦楼,“这是梦里的那栋楼”,,吕萍,,
c02_吕萍_天冷,“冷飕飕的,早知道多穿一件出来了”,,吕萍,,
c02_吕萍_天暗,“天色变暗了”,,吕萍,,
c02_吕萍_井旁01,“这么冷的天,怎么这树的叶子还这么茂盛”,,吕萍,,[#wait=3]
@ -37,7 +38,6 @@ c02_张胖子_招呼吕萍1,“老方,小朋友又不懂,和她讲这些干
c02_张胖子_招呼吕萍2,“小蝶啊,回头记得带妈妈来叔叔这儿买肉啊”,,张胖子,,[#anonymous]
c02_张胖子_招呼吕萍3,“外面没的买,叔叔这里多的是”,,张胖子,,[#anonymous]
c02_张胖子_招呼吕萍4,“这些人是在跟我说话吗”,,吕萍,,
c02_张胖子_招呼吕萍5,“来来来,过来,过来”,"""come on, come on""",张胖子,,[#anonymous]
c02_张胖子_招呼吕萍6,“悄悄和你讲,让你妈妈来我这里买肉,给你们家便宜点”,,张胖子,,[#anonymous]
c02_张胖子_招呼吕萍7,“不行到时候我给你们把肉送到家里去,好哇”,,张胖子,,[#anonymous]
c02_张胖子_招呼吕萍8,“呃,不用......不用了......”,,吕萍,,

1 keys zh_CN en _character _notes _tags
2 c02_张胖子_招呼吕萍5 “来来来,过来,过来” "come on, come on" 张胖子 [#anonymous]
3 c02_芦昌路26 (芦昌路26弄3号) 孤寂的氛围 [#wave] [#shake]
4 c02_吕萍_01_梦楼 “这是梦里的那栋楼” 吕萍
5 c02_吕萍_天冷 “冷飕飕的,早知道多穿一件出来了” 吕萍
6 c02_吕萍_天暗 “天色变暗了” 吕萍
7 c02_吕萍_井旁01 “这么冷的天,怎么这树的叶子还这么茂盛” 吕萍 [#wait=3]
38 c02_张胖子_招呼吕萍2 “小蝶啊,回头记得带妈妈来叔叔这儿买肉啊” 张胖子 [#anonymous]
39 c02_张胖子_招呼吕萍3 “外面没的买,叔叔这里多的是” 张胖子 [#anonymous]
40 c02_张胖子_招呼吕萍4 “这些人是在跟我说话吗” 吕萍
c02_张胖子_招呼吕萍5 “来来来,过来,过来” "come on, come on" 张胖子 [#anonymous]
41 c02_张胖子_招呼吕萍6 “悄悄和你讲,让你妈妈来我这里买肉,给你们家便宜点” 张胖子 [#anonymous]
42 c02_张胖子_招呼吕萍7 “不行到时候我给你们把肉送到家里去,好哇” 张胖子 [#anonymous]
43 c02_张胖子_招呼吕萍8 “呃,不用......不用了......” 吕萍

View File

@ -2,7 +2,7 @@
~ c02_s01_门口
##孤寂的氛围 [#wave] [#shake]
芦昌路26弄3号 [ID:c02_芦昌路26]
“这是梦里的那栋楼” [ID:c02_吕萍_01_梦楼]
吕萍: “这是梦里的那栋楼” [ID:c02_吕萍_01_梦楼]
=> END
#~ c02_s01_boy1

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -50,7 +50,17 @@
"c02_吕萍_爬行_idle_l": "",
"c02_吕萍_爬行_idle_r": "",
"c02_吕萍_爬行_left": "",
"c01_信碎片_falling": ""
"c01_信碎片_falling": "",
"c01_小小蝶 _idle": "",
"c01_小小蝶_running": "",
"c01_小小蝶_walking": "",
"c01_小小蝶_抬头": "",
"c01_小小蝶 _idle_l": "",
"c01_小小蝶_running_l": "",
"c01_小小蝶_walking_l": "",
"c01_小小蝶_抬头_l": "",
"c01_小小蝶_idle": "",
"c01_小小蝶_idle_l": ""
},
"mirror_mapping": {
"c00_吕萍_idle_left": "",
@ -103,7 +113,17 @@
"c02_吕萍_爬行_idle_l": "",
"c02_吕萍_爬行_idle_r": "",
"c02_吕萍_爬行_left": "",
"c01_信碎片_falling": ""
"c01_信碎片_falling": "",
"c01_小小蝶 _idle": "",
"c01_小小蝶_running": "",
"c01_小小蝶_walking": "",
"c01_小小蝶_抬头": "",
"c01_小小蝶 _idle_l": "",
"c01_小小蝶_running_l": "",
"c01_小小蝶_walking_l": "",
"c01_小小蝶_抬头_l": "",
"c01_小小蝶_idle": "",
"c01_小小蝶_idle_l": ""
},
"dirs": {
"c00_吕萍_idle_left": {
@ -408,6 +428,154 @@
"10"
]
},
"c01_小小蝶_idle": {
"path": "res://asset/art/animation/c01_小小蝶_idle",
"frames": {
"1": "res://asset/art/animation/c01_小小蝶_idle/1.png",
"2": "res://asset/art/animation/c01_小小蝶_idle/2.png",
"3": "res://asset/art/animation/c01_小小蝶_idle/3.png"
},
"ids": [
"1",
"2",
"3"
]
},
"c01_小小蝶_idle_l": {
"path": "res://asset/art/animation/c01_小小蝶_idle_l",
"frames": {
"1": "res://asset/art/animation/c01_小小蝶_idle_l/1.png",
"2": "res://asset/art/animation/c01_小小蝶_idle_l/2.png",
"3": "res://asset/art/animation/c01_小小蝶_idle_l/3.png"
},
"ids": [
"1",
"2",
"3"
]
},
"c01_小小蝶_running": {
"path": "res://asset/art/animation/c01_小小蝶_running",
"frames": {
"1": "res://asset/art/animation/c01_小小蝶_running/1.png",
"2": "res://asset/art/animation/c01_小小蝶_running/2.png",
"3": "res://asset/art/animation/c01_小小蝶_running/3.png",
"4": "res://asset/art/animation/c01_小小蝶_running/4.png",
"5": "res://asset/art/animation/c01_小小蝶_running/5.png",
"6": "res://asset/art/animation/c01_小小蝶_running/6.png",
"7": "res://asset/art/animation/c01_小小蝶_running/7.png"
},
"ids": [
"1",
"2",
"3",
"4",
"5",
"6",
"7"
]
},
"c01_小小蝶_running_l": {
"path": "res://asset/art/animation/c01_小小蝶_running_l",
"frames": {
"1": "res://asset/art/animation/c01_小小蝶_running_l/1.png",
"2": "res://asset/art/animation/c01_小小蝶_running_l/2.png",
"3": "res://asset/art/animation/c01_小小蝶_running_l/3.png",
"4": "res://asset/art/animation/c01_小小蝶_running_l/4.png",
"5": "res://asset/art/animation/c01_小小蝶_running_l/5.png",
"6": "res://asset/art/animation/c01_小小蝶_running_l/6.png",
"7": "res://asset/art/animation/c01_小小蝶_running_l/7.png"
},
"ids": [
"1",
"2",
"3",
"4",
"5",
"6",
"7"
]
},
"c01_小小蝶_walking": {
"path": "res://asset/art/animation/c01_小小蝶_walking",
"frames": {
"1": "res://asset/art/animation/c01_小小蝶_walking/1.png",
"2": "res://asset/art/animation/c01_小小蝶_walking/2.png",
"3": "res://asset/art/animation/c01_小小蝶_walking/3.png",
"4": "res://asset/art/animation/c01_小小蝶_walking/4.png",
"5": "res://asset/art/animation/c01_小小蝶_walking/5.png",
"6": "res://asset/art/animation/c01_小小蝶_walking/6.png"
},
"ids": [
"1",
"2",
"3",
"4",
"5",
"6"
]
},
"c01_小小蝶_walking_l": {
"path": "res://asset/art/animation/c01_小小蝶_walking_l",
"frames": {
"1": "res://asset/art/animation/c01_小小蝶_walking_l/1.png",
"2": "res://asset/art/animation/c01_小小蝶_walking_l/2.png",
"3": "res://asset/art/animation/c01_小小蝶_walking_l/3.png",
"4": "res://asset/art/animation/c01_小小蝶_walking_l/4.png",
"5": "res://asset/art/animation/c01_小小蝶_walking_l/5.png",
"6": "res://asset/art/animation/c01_小小蝶_walking_l/6.png"
},
"ids": [
"1",
"2",
"3",
"4",
"5",
"6"
]
},
"c01_小小蝶_抬头": {
"path": "res://asset/art/animation/c01_小小蝶_抬头",
"frames": {
"1": "res://asset/art/animation/c01_小小蝶_抬头/1.png",
"2": "res://asset/art/animation/c01_小小蝶_抬头/2.png",
"3": "res://asset/art/animation/c01_小小蝶_抬头/3.png",
"4": "res://asset/art/animation/c01_小小蝶_抬头/4.png",
"5": "res://asset/art/animation/c01_小小蝶_抬头/5.png",
"6": "res://asset/art/animation/c01_小小蝶_抬头/6.png",
"7": "res://asset/art/animation/c01_小小蝶_抬头/7.png"
},
"ids": [
"1",
"2",
"3",
"4",
"5",
"6",
"7"
]
},
"c01_小小蝶_抬头_l": {
"path": "res://asset/art/animation/c01_小小蝶_抬头_l",
"frames": {
"1": "res://asset/art/animation/c01_小小蝶_抬头_l/1.png",
"2": "res://asset/art/animation/c01_小小蝶_抬头_l/2.png",
"3": "res://asset/art/animation/c01_小小蝶_抬头_l/3.png",
"4": "res://asset/art/animation/c01_小小蝶_抬头_l/4.png",
"5": "res://asset/art/animation/c01_小小蝶_抬头_l/5.png",
"6": "res://asset/art/animation/c01_小小蝶_抬头_l/6.png",
"7": "res://asset/art/animation/c01_小小蝶_抬头_l/7.png"
},
"ids": [
"1",
"2",
"3",
"4",
"5",
"6",
"7"
]
},
"c01_捡球男孩_关键帧": {
"path": "res://asset/art/animation/c01_捡球男孩_关键帧",
"frames": {
@ -1337,14 +1505,14 @@
}
},
"mapping": {
"c00_吕萍_idle_left": "idle_l",
"c00_吕萍_idle_right": "idle_r",
"c00_吕萍_jogging_left": "jogging_l",
"c00_吕萍_jogging_right": "jogging_r",
"c00_吕萍_running_left": "running_l",
"c00_吕萍_running_right": "running_r",
"c00_吕萍_walking_left": "walking_l",
"c00_吕萍_walking_right": "walking_r",
"c00_吕萍_idle_left": "c00_吕萍_idle_left",
"c00_吕萍_idle_right": "c00_吕萍_idle_right",
"c00_吕萍_jogging_left": "c00_吕萍_jogging_left",
"c00_吕萍_jogging_right": "c00_吕萍_jogging_right",
"c00_吕萍_running_left": "c00_吕萍_running_left",
"c00_吕萍_running_right": "c00_吕萍_running_right",
"c00_吕萍_walking_left": "c00_吕萍_walking_left",
"c00_吕萍_walking_right": "c00_吕萍_walking_right",
"c00_吕萍_记笔记_right": "c00_吕萍_记笔记_right",
"c00_吕萍带小猫_idle_left": "c00_吕萍带小猫_idle_left",
"c00_吕萍带小猫_idle_right": "c00_吕萍带小猫_idle_right",
@ -1360,7 +1528,7 @@
"c02_吕萍_头痛蹲下": "c02_吕萍_头痛蹲下",
"c02_吕萍_柜前被吓到后退": "c02_吕萍_柜前被吓到后退",
"c02_吕萍_爬出洞口": "c02_吕萍_爬出洞口",
"c02_吕萍_爬行_right": "laying_moving_r",
"c02_吕萍_爬行_right": "c02_吕萍_爬行_right",
"c02_吕萍_看小猫玩具_right": "c02_吕萍_看小猫玩具_right",
"c02_吕萍_背靠起身": "c02_吕萍_背靠起身",
"c02_吕萍_蹲下来查看": "c02_吕萍_蹲下来查看",
@ -1384,10 +1552,20 @@
"c02_瞎子_蹲着呼吸": "c02_瞎子_蹲着呼吸",
"c02_门前弹珠": "c02_门前弹珠",
"c02_黑手_捂屏幕": "c02_黑手_捂屏幕",
"c02_吕萍_爬行_idle_l": "laying_stay_l",
"c02_吕萍_爬行_idle_r": "laying_stay_r",
"c02_吕萍_爬行_left": "laying_moving_l",
"c01_信碎片_falling": "c01_信碎片_falling"
"c02_吕萍_爬行_idle_l": "c02_吕萍_爬行_idle_l",
"c02_吕萍_爬行_idle_r": "c02_吕萍_爬行_idle_r",
"c02_吕萍_爬行_left": "c02_吕萍_爬行_left",
"c01_信碎片_falling": "c01_信碎片_falling",
"c01_小小蝶 _idle": "c01_小小蝶 _idle_r",
"c01_小小蝶_running": "c01_小小蝶_running_r",
"c01_小小蝶_walking": "c01_小小蝶_walking_r",
"c01_小小蝶_抬头": "c01_小小蝶_抬头_r",
"c01_小小蝶 _idle_l": "c01_小小蝶 _idle_l",
"c01_小小蝶_running_l": "c01_小小蝶_running_l",
"c01_小小蝶_walking_l": "c01_小小蝶_walking_l",
"c01_小小蝶_抬头_l": "c01_小小蝶_抬头_l",
"c01_小小蝶_idle": "c01_小小蝶_idle_r",
"c01_小小蝶_idle_l": "c01_小小蝶_idle_l"
},
"frames_per_second": {
"c00_吕萍_idle_left": 2,
@ -1440,6 +1618,16 @@
"c02_吕萍_爬行_idle_l": 2,
"c02_吕萍_爬行_idle_r": 2,
"c02_吕萍_爬行_left": 6,
"c01_信碎片_falling": 7
"c01_信碎片_falling": 7,
"c01_小小蝶 _idle": 2,
"c01_小小蝶_running": 8,
"c01_小小蝶_walking": 6,
"c01_小小蝶_抬头": 5,
"c01_小小蝶 _idle_l": 2,
"c01_小小蝶_running_l": 8,
"c01_小小蝶_walking_l": 6,
"c01_小小蝶_抬头_l": 5,
"c01_小小蝶_idle": 2,
"c01_小小蝶_idle_l": 2
}
}

View File

@ -57,17 +57,23 @@ func reload_frames():
else:
sprite_frames.add_animation(mirror_mapping)
for id in frames_data.ids:
var frame_path = frames_data.frames[id]
var frame_path = frames_data.frames[id] as String
var frame_texture = load(frame_path) as Texture2D
sprite_frames.add_frame(mapping_name, frame_texture)
sprite_frames.set_animation_speed(mapping_name, frames_per_sec)
# mirror the frame
if mirror_mapping != "":
# mkdir the mirror mapping
var mirror_dir_path = "res://asset/art/animation/" + mirror_mapping
if !DirAccess.dir_exists_absolute(mirror_dir_path):
DirAccess.make_dir_absolute(mirror_dir_path)
var mirrored_frame = frame_texture.duplicate() as Texture2D
var flipped_image = mirrored_frame.get_image()
var flipped_image = mirrored_frame.get_image() as Image
flipped_image.flip_x()
mirrored_frame = ImageTexture.create_from_image(flipped_image)
sprite_frames.add_frame(mirror_mapping, mirrored_frame)
var flipped_img_path = mirror_dir_path + "/" + id + ".png"
flipped_image.resource_path = flipped_img_path
flipped_image.save_png(flipped_img_path)
sprite_frames.add_frame(mirror_mapping, load(flipped_img_path))
sprite_frames.set_animation_speed(mapping_name, frames_per_sec)
animated_sprite.play(mapping_name)
# scale down if the frame is too big

View File

@ -13,7 +13,7 @@ var autosave_timer := Timer.new()
func _ready() -> void:
# disable auto quit
# 禁用默认退出行为,在 _notification 处理 NOTIFICATION_WM_CLOSE_REQUEST 时保存数据
get_tree().set_auto_accept_quit(false)
if not _check_dirs_and_archives():
_handle_load_error("存档目录", "读写")
@ -23,8 +23,8 @@ func _ready() -> void:
add_child(autosave_timer)
# config should be loaded first
load_config()
# NOTICE auto load archive on debug mode
if GlobalConfig.DEBUG:
# 在 debug or editor 模式下,直接保证有 archive
if GlobalConfig.DEBUG or Engine.is_editor_hint():
if archives.size() == 0:
create_and_use_new_archive()
else:

View File

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

View File

@ -27,6 +27,18 @@ func get_current_prop(must_selected: bool) -> String:
return ""
func enable_prop_item(prop_key: String) -> void:
var prop_hud = get_prop_hud()
if prop_hud:
prop_hud.enable_prop_item(prop_key)
func disable_prop_item(prop_key: String) -> void:
var prop_hud = get_prop_hud()
if prop_hud:
prop_hud.disable_prop_item(prop_key)
func pop_os(lines := []):
var player = get_player()
if player:

View File

@ -4,8 +4,10 @@ extends Node2D
signal player_entered
@export var one_shot := true
# 首次进入 tree 就直接启用
@export var on_first_enter_tree := false
@export var freeze_time := 5.0
@export var hook_animation = ""
var hook_animation = ""
@export var lock_player_on_playing_dialogue = true
@export_enum("c01", "c02") var hook_dialogue_res = "c01":
set(val):
@ -40,30 +42,50 @@ var played_time := 0.0
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
var animation_player = _get_animation_player()
# 更新 hook_animation 的可选项
if animation_player:
animation_player.animation_libraries_updated.connect(notify_property_list_changed)
if Engine.is_editor_hint():
return
if one_shot and played:
if GlobalConfig.DEBUG:
print("Ambush already played, name=", name)
return
if on_first_enter_tree:
_entered(null)
area2d.body_entered.connect(_entered)
func _get_animation_player() -> AnimationPlayer:
return get_node_or_null("../../AnimationPlayer") as AnimationPlayer
var enter_mutex = Mutex.new()
func _entered(_body):
var time = Time.get_ticks_msec()
if not one_shot:
# 确保只有一个线程进入该逻辑,因为有时 player 碰撞和首次进入 tree 都会触发该方法
if not enter_mutex.try_lock():
return
if not one_shot and freeze_time > 0:
var time_left = freeze_time - (time - played_time) * 0.001
if time_left > 0:
if GlobalConfig.DEBUG:
print("Ambush freeze time not reached, time left=", time_left)
enter_mutex.unlock()
return
elif played:
if one_shot and played:
enter_mutex.unlock()
return
played_time = time
played = true
# hook_animation
if hook_animation:
$AnimationPlayer.play(hook_animation)
var animation_player = _get_animation_player()
if animation_player:
animation_player.play(hook_animation)
# hook_dialogue
if hook_dialogue_title:
if lock_player_on_playing_dialogue:
@ -73,6 +95,7 @@ func _entered(_body):
player_entered.emit()
if GlobalConfig.DEBUG:
print("ambush body_entered!")
enter_mutex.unlock()
func _on_dialogue_ended(_res):
@ -85,6 +108,8 @@ func _on_dialogue_ended(_res):
func _get(property: StringName) -> Variant:
if property == "hook_dialogue_title":
return hook_dialogue_title
elif property == "hook_animation":
return hook_animation
return null
@ -92,15 +117,28 @@ func _set(property: StringName, value: Variant) -> bool:
if property == "hook_dialogue_title":
hook_dialogue_title = value
return true
elif property == "hook_animation":
hook_animation = value
return true
return false
func _get_property_list() -> Array[Dictionary]:
var animation_list: PackedStringArray
var animation_player = _get_animation_player()
if animation_player:
animation_list = animation_player.get_animation_list()
return [
{
"name": "hook_dialogue_title",
"type": TYPE_STRING,
"hint": PROPERTY_HINT_ENUM_SUGGESTION,
"hint_string": ",".join(dialogue_res.get_ordered_titles())
},
{
"name": "hook_animation",
"type": TYPE_STRING,
"hint": PROPERTY_HINT_ENUM_SUGGESTION,
"hint_string": ",".join(animation_list)
}
]

View File

@ -9,11 +9,10 @@ size = Vector2(10, 70)
[node name="Ambush" type="Node2D"]
script = ExtResource("1_rxgbr")
hook_dialogue_title = ""
hook_animation = ""
[node name="Area2D" type="Area2D" parent="."]
unique_name_in_owner = true
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
shape = SubResource("RectangleShape2D_iwrfx")
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]

View File

@ -82,17 +82,14 @@ func _on_interacted() -> void:
if one_shot and interacted_times:
return
var key = SceneManager.get_current_prop(false)
var prop_hud = SceneManager.get_prop_hud() as PropHud
if key != prop_key:
sfx_invalid.play()
sign_mark.invalid_shake()
# prop_hud.on_toggle_invalid_prop()
# SceneManager.on_toggle_invalid_prop()
return
sfx_success.play()
if one_shot:
prop_hud.disable_prop_item(prop_key)
else:
prop_hud.on_toggle_valid_prop()
SceneManager.disable_prop_item(prop_key)
interacted_times += 1
if texture_after:
texture = texture_after

View File

@ -20,7 +20,6 @@ var scenes_dir = "res://scene/ground/scene/"
var ground_dict = {}
func _ready() -> void:
_read_grounds()
ground = get_node_or_null("Ground")

View File

@ -1 +1,78 @@
# @tool
class_name AnimationRoot extends AnimationPlayer
# 在继承 AnimationRoot 的各场景内的脚本中,可以直接调用 DialogueResource
var dialogue_c01 := preload("res://asset/dialogue/c01.dialogue") as DialogueResource
var dialogue_c02 := preload("res://asset/dialogue/c02.dialogue") as DialogueResource
@export var data = {
# 首次进入场景时触发
"oneshot_animation_played": false
}
var oneshot_animation := ""
var ground_archive: GroundArchive
# 继承覆盖该方法
func _default_data() -> Dictionary:
print("read default data from root")
return {}
func _ready() -> void:
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 = _default_data()
var archive_data = ground_archive.get_data(name)
# merge data
for key in archive_data.keys():
if data.has(key):
data[key] = archive_data[key]
func _notification(what: int) -> void:
# 仅在首次进入场景时触发
if what == NOTIFICATION_READY:
if oneshot_animation and not data["oneshot_animation_played"]:
play(oneshot_animation)
animation_finished.connect(_oneshot_animation_finished, CONNECT_ONE_SHOT)
func _oneshot_animation_finished() -> void:
set_data("oneshot_animation_played", true)
func set_data(property: StringName, value: Variant) -> bool:
if data.has(property):
ground_archive.set_pair(name, property, value)
data[property] = value
return true
return false
func _get(property: StringName) -> Variant:
if property == "oneshot_animation":
return oneshot_animation
return null
func _set(property: StringName, value: Variant) -> bool:
if property == "oneshot_animation":
oneshot_animation = value
return true
return false
func _get_property_list() -> Array[Dictionary]:
return [
{
"name": "oneshot_animation",
"type": TYPE_STRING,
"hint": PROPERTY_HINT_ENUM_SUGGESTION,
"hint_string": ",".join(get_animation_list()),
}
]

View File

@ -0,0 +1,12 @@
@tool
extends AnimationRoot
# 覆盖该方法
func _default_data() -> Dictionary:
return {}
func _ready() -> void:
super._ready()

View File

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

View File

@ -1,7 +1,7 @@
[gd_scene load_steps=24 format=3 uid="uid://dlx5xxbg53rb8"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_ff4yb"]
[ext_resource type="Script" path="res://scene/ground/scene/c01/s05_animations.gd" id="2_j5oim"]
[ext_resource type="Script" path="res://scene/ground/scene/c01/s05_animation.gd" id="2_j5oim"]
[ext_resource type="Texture2D" uid="uid://bx5we5pgnlhl5" path="res://asset/art/scene/c01/s05_院长房间/bg_房间背景.png" id="3_3r1q2"]
[ext_resource type="Texture2D" uid="uid://dkufmwg07maun" path="res://asset/art/scene/c01/s05_院长房间/全局参考.png" id="3_7u4bh"]
[ext_resource type="Texture2D" uid="uid://bp2r4s6v6ag2f" path="res://asset/art/scene/c01/s05_院长房间/fg_前景.png" id="3_vmr0f"]
@ -42,6 +42,10 @@ size = Vector2(35, 70)
[node name="AnimationPlayer" parent="Ground" index="0"]
script = ExtResource("2_j5oim")
data = {
"oneshot_animation_played": false
}
oneshot_animation = null
[node name="BGSprite2D" parent="Ground" index="2"]
position = Vector2(23, -118)
@ -122,6 +126,8 @@ shape = SubResource("RectangleShape2D_40ng7")
[node name="Ambush" parent="Ground/DeployLayer" index="9" instance=ExtResource("15_1uixh")]
position = Vector2(113, 46)
on_first_enter_tree = null
hook_animation = ""
[node name="PointLight墙" type="PointLight2D" parent="Ground/AmbientLayer" index="0"]
visible = false

View File

@ -0,0 +1,23 @@
@tool
extends AnimationRoot
# 覆盖该方法
func _default_data() -> Dictionary:
return {"received_letter": false}
func _ready() -> void:
super._ready()
if not data["received_letter"]:
SceneManager.freeze_player(0.5)
get_tree().create_timer(0.5).timeout.connect(_give_letter)
elif GlobalConfig.DEBUG:
print("_give_letter 已发放")
func _give_letter() -> void:
set_data("received_letter", true)
SceneManager.enable_prop_item("prop_令牌")
print("_give_letter")

View File

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

View File

@ -2,7 +2,7 @@
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_gdcov"]
[ext_resource type="Texture2D" uid="uid://kc4726andgy2" path="res://asset/art/scene/c02/s01_街道/bg_公寓入口.png" id="2_ni1a4"]
[ext_resource type="Script" path="res://scene/ground/scene/c02/s01_animations.gd" id="2_uuwn3"]
[ext_resource type="Script" path="res://scene/ground/scene/c02/s01_animation.gd" id="2_uuwn3"]
[ext_resource type="PackedScene" uid="uid://jr1yd46wm5je" path="res://scene/entity/note.tscn" id="3_6lnxd"]
[ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="6_vgxa0"]
@ -12,6 +12,10 @@
[node name="AnimationPlayer" parent="Ground" index="0"]
script = ExtResource("2_uuwn3")
data = {
"oneshot_animation_played": false
}
oneshot_animation = null
[node name="BGSprite2D" parent="Ground" index="2"]
texture = ExtResource("2_ni1a4")
@ -36,9 +40,9 @@ note_key = "c02_s01_门口"
[node name="Ambush" parent="Ground/DeployLayer" index="4" instance=ExtResource("6_vgxa0")]
position = Vector2(135, 56)
hook_animation = null
lock_player_on_playing_dialogue = null
hook_dialogue_res = null
hook_animation = null
[node name="FGSprite2D" parent="Ground/ParallaxForeground/FGParallaxLayer" index="0"]
texture = null

View File

@ -0,0 +1,23 @@
@tool
extends AnimationRoot
# 覆盖该方法
func _default_data() -> Dictionary:
return {}
func _ready() -> void:
super._ready()
func _oneshot_wind():
SceneManager.freeze_player(0, "c02_吕萍_风吹过")
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():
SceneManager.release_player()

View File

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

View File

@ -1,22 +1,41 @@
[gd_scene load_steps=14 format=3 uid="uid://brck77w81fhvc"]
[gd_scene load_steps=12 format=3 uid="uid://brck77w81fhvc"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_wrr6r"]
[ext_resource type="Script" path="res://scene/ground/scene/c02/s02_animations.gd" id="2_5p8ev"]
[ext_resource type="Script" path="res://scene/ground/scene/c02/s02_animation.gd" id="2_5p8ev"]
[ext_resource type="Texture2D" uid="uid://c4647gof464ws" path="res://asset/art/scene/c02/s02_走道/bg_过道.png" id="2_cn1s8"]
[ext_resource type="PackedScene" uid="uid://jr1yd46wm5je" path="res://scene/entity/note.tscn" id="3_fy0o1"]
[ext_resource type="PackedScene" uid="uid://wyj4qdjyn4ql" path="res://scene/entity/old/inspectable.tscn" id="5_nhtbp"]
[ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="6_70vqn"]
[ext_resource type="Texture2D" uid="uid://ds4yw1wqelhm1" path="res://asset/art/scene/c02/s02_走道/ux_进门鼠疫海报yz.png" id="7_wdwbi"]
[ext_resource type="Texture2D" uid="uid://dd0sn5e4hwq5m" path="res://asset/art/scene/c02/s02_走道/e_纸人.png" id="7_xsghn"]
[ext_resource type="PackedScene" uid="uid://bj4ufua0b0k34" path="res://scene/entity/hd_entity.tscn" id="10_3c313"]
[ext_resource type="Texture2D" uid="uid://dtk3c3uqhn8ue" path="res://asset/art/scene/c01/s04_旧版序章/e_轿车.png" id="11_x0h3x"]
[ext_resource type="PackedScene" uid="uid://ci5anaxsa1apl" path="res://scene/entity/local_inspectable.tscn" id="12_0fckv"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_vc6i4"]
resource_local_to_scene = true
size = Vector2(35, 70)
[sub_resource type="Animation" id="Animation_abofy"]
resource_name = "oneshot_天冷"
length = 3.0
tracks/0/type = "method"
tracks/0/imported = false
tracks/0/enabled = true
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),
"values": [{
"args": [],
"method": &"_oneshot_wind"
}, {
"args": [],
"method": &"_oneshot_dialog"
}]
}
[sub_resource type="RectangleShape2D" id="RectangleShape2D_3qhvr"]
[sub_resource type="AnimationLibrary" id="AnimationLibrary_fjkfm"]
_data = {
"oneshot_天冷": SubResource("Animation_abofy")
}
[sub_resource type="RectangleShape2D" id="RectangleShape2D_vc6i4"]
resource_local_to_scene = true
size = Vector2(35, 70)
@ -25,7 +44,14 @@ size = Vector2(35, 70)
[node name="Ground" parent="." instance=ExtResource("1_wrr6r")]
[node name="AnimationPlayer" parent="Ground" index="0"]
libraries = {
"": SubResource("AnimationLibrary_fjkfm")
}
script = ExtResource("2_5p8ev")
data = {
"oneshot_animation_played": false
}
oneshot_animation = "oneshot_天冷"
[node name="BGSprite2D" parent="Ground" index="2"]
texture = ExtResource("2_cn1s8")
@ -58,27 +84,11 @@ offset_bottom = 36.0
[node name="CollisionShape2D" parent="Ground/DeployLayer/纸人/Area2D" index="0"]
shape = SubResource("RectangleShape2D_vc6i4")
[node name="Ambush" parent="Ground/DeployLayer" index="5" instance=ExtResource("6_70vqn")]
position = Vector2(502, 54)
[node name="HdEntity" parent="Ground/DeployLayer" index="6" node_paths=PackedStringArray("sprite_ref") instance=ExtResource("10_3c313")]
position = Vector2(147, 75)
sprite_name = "car"
texture = ExtResource("11_x0h3x")
sprite_ref = NodePath("../../SubViewportContainer/SubViewport/HdLayer/car")
[node name="Sign" parent="Ground/DeployLayer/HdEntity" index="1"]
offset_left = -9.0
offset_top = -32.0
offset_right = 74.0
offset_bottom = 48.0
[node name="CollisionShape2D" parent="Ground/DeployLayer/HdEntity/Area2D" index="0"]
shape = SubResource("RectangleShape2D_3qhvr")
[node name="MainPlayer" parent="Ground" index="5"]
position = Vector2(50, 45)
[node name="FGSprite2D" parent="Ground/ParallaxForeground/FGParallaxLayer" index="0"]
texture = null
[editable path="Ground"]
[editable path="Ground/DeployLayer/纸人"]
[editable path="Ground/DeployLayer/HdEntity"]

View File

@ -0,0 +1,12 @@
@tool
extends AnimationRoot
# 覆盖该方法
func _default_data() -> Dictionary:
return {}
func _ready() -> void:
super._ready()

View File

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

View File

@ -1,7 +1,7 @@
[gd_scene load_steps=14 format=3 uid="uid://djc2uaefhmu7"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_lheeb"]
[ext_resource type="Script" path="res://scene/ground/scene/c02/s03_animations.gd" id="2_l2oec"]
[ext_resource type="Script" path="res://scene/ground/scene/c02/s03_animation.gd" id="2_l2oec"]
[ext_resource type="PackedScene" uid="uid://0sofmhrl358m" path="res://scene/entity/npc.tscn" id="2_r5smg"]
[ext_resource type="PackedScene" uid="uid://jr1yd46wm5je" path="res://scene/entity/note.tscn" id="3_6x7xl"]
[ext_resource type="Texture2D" uid="uid://bb3f72fla7mvs" path="res://asset/art/scene/c02/s03_院子切换/bg_院子1楼(黄昏无人).png" id="3_78bcp"]
@ -26,6 +26,10 @@ size = Vector2(40, 70)
[node name="AnimationPlayer" parent="Ground" index="0"]
script = ExtResource("2_l2oec")
data = {
"oneshot_animation_played": false
}
oneshot_animation = null
[node name="BGSprite2D" parent="Ground" index="2"]
texture = SubResource("CanvasTexture_41q0k")
@ -40,7 +44,7 @@ position = Vector2(629, 2)
[node name="Npc" parent="Ground/DeployLayer" index="2" instance=ExtResource("2_r5smg")]
position = Vector2(465, 23)
frame_progress = 0.54706
frame_progress = 0.647752
character_name = "张胖子"
dialogue_title = "张胖子_01"
@ -50,9 +54,11 @@ note_key = "c02_老鼠洞2"
[node name="Ambush" parent="Ground/DeployLayer" index="4" instance=ExtResource("6_gg4jv")]
position = Vector2(343, 33)
on_first_enter_tree = null
freeze_time = 15.0
hook_dialogue_res = "c02"
hook_dialogue_title = "c02_s04_张胖子卖肉"
hook_animation = ""
[node name="CollisionShape2D" parent="Ground/DeployLayer/Ambush/Area2D" index="0"]
shape = SubResource("RectangleShape2D_ec3g1")

View File

@ -0,0 +1,11 @@
@tool
extends AnimationRoot
# 覆盖该方法
func _default_data() -> Dictionary:
return {}
func _ready() -> void:
super._ready()

View File

@ -334,14 +334,3 @@ func on_toggle_invalid_prop():
func _reset_prop_modulate():
prop.modulate = Color(1.0, 1.0, 1.0, 1.0)
func on_toggle_valid_prop():
if GlobalConfig.DEBUG:
print("使用有效道具. current prop:", inventory.current_item_key())
# 展示 mark
if not selected:
focus_mode = FOCUS_ALL
grab_focus()
selected = true
_mouse_moved_on_listening()

View File

@ -1,5 +1,7 @@
extends Control
signal exit(passed: bool)
# answer for the puzzle, by columns
# @export var answer := [1, 0, 0, 0, 0, 0, 0, 0, 0]
@export var answer := [1, 4, 3, 1, 3, 6, 4, 3, 2]
@ -153,7 +155,8 @@ func _move_button(delta: int) -> void:
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("cancel"):
pass
var success = ArchiveManager.archive.bayinhe_mode == "finished"
exit.emit(success)
if ArchiveManager.archive.bayinhe_mode == "closed":
# move button
if event.is_action_pressed("up"):

View File

@ -13,3 +13,4 @@ func _ready() -> void:
%ColorRectTop.visible = true
%ColorRectBottom.visible = true

View File

@ -19,7 +19,6 @@ environment = ExtResource("9_jsof5")
[node name="GroundLoader" parent="." instance=ExtResource("10_8rc5n")]
position = Vector2(1, 0)
ignore_archive = true
current_scene = "c01_s05"
entrance_portal = "right"
[node name="ShadingLayer" parent="." instance=ExtResource("2_d1re1")]

View File

@ -1,47 +1,31 @@
@tool
extends CharacterBody2D
class_name MainPlayer
enum MOVEMENT_STATUS {
IDLE,
WALKING,
RUNNING,
LAYING_STAY,
LAYING_MOVING,
CLIMBING_STAY,
CLIMBING,
}
@export var shadow_color := Color(0.1, 0.1, 0.1, 0.7)
var shadow_y := 0.0
@export_enum("吕萍", "吕萍爬行", "吕萍带小猫", "小蝶", "小小蝶") var character := "吕萍":
set(val):
character = val
current_animation_config = PlayerAnimationConfig.ANIMATION_CONFIG[val]
current_status = PlayerAnimationConfig.MOVEMENT_IDLE
# @export var shadow_color := Color(0.1, 0.1, 0.1, 0.7)
# var shadow_y := 0.0
@export var player_movement_rect := Rect2(50, -500, 1400, 1000)
@export var velocity_ratio := 1.0
@export var action_locked := false:
set(val):
action_locked = val
_process_action_lock()
@export var current_status: MOVEMENT_STATUS
@export var facing_direction := Vector2(1.0, -1.0)
@export var is_laying := false:
@export_enum("idle", "walking", "running") var current_status := 0:
set(val):
is_laying = val
# reset the facing direction wether the player is laying or not.
_reset_face_direction()
if is_laying:
is_climbing = false
@export var is_climbing := false:
current_status = val
_play_animation()
@export var facing_direction := Vector2(1.0, -1.0):
set(val):
is_climbing = val
# reset the facing direction wether the player is climbing or not.
_reset_face_direction()
if is_climbing:
is_laying = false
@export var running_locked := false
@export var speed_walking := 75.0 #55
@export var speed_runnig := 120.0 #125
@export var speed_laying := 50.0
@export var speed_climbing := 50.0
#const JUMP_VELOCITY = -400.0
facing_direction = val
_play_animation()
var current_animation_config := PlayerAnimationConfig.ANIMATION_CONFIG[character] as Dictionary
@onready var footstep_timer = %FootstepTimer as Timer
@onready var sprite = %AnimatedSprite2D as AnimatedSprite2D
@ -49,17 +33,17 @@ var shadow_y := 0.0
@onready var os_contaner = %PanelContainer as PanelContainer
@onready var os_label = %OSLabel as DialogueLabel
# animation -> {frame -> {shadow polygon}}
var animation_shadow_polygons = {}
# # animation -> {frame -> {shadow polygon}}
# var animation_shadow_polygons = {}
func _ready() -> void:
# _reset_face_direction()
os_contaner.modulate.a = 0.0
_play_animation()
if Engine.is_editor_hint():
return
footstep_timer.timeout.connect(_on_footstep_timer_timeout)
footstep_timer.stop()
SceneManager.focus_player(self)
os_contaner.modulate.a = 0.0
sprite.frame_changed.connect(queue_redraw)
func _on_footstep_timer_timeout():
@ -69,47 +53,28 @@ func _on_footstep_timer_timeout():
ground_loader.play_footstep_sound()
func _reset_face_direction() -> void:
facing_direction = Vector2(1, -1)
func _process_action_lock() -> void:
# reset status to idle or stay
if action_locked:
velocity = Vector2.ZERO
if current_status == MOVEMENT_STATUS.WALKING or current_status == MOVEMENT_STATUS.RUNNING:
current_status = MOVEMENT_STATUS.IDLE
elif current_status == MOVEMENT_STATUS.LAYING_MOVING:
current_status = MOVEMENT_STATUS.LAYING_STAY
elif current_status == MOVEMENT_STATUS.CLIMBING:
current_status = MOVEMENT_STATUS.CLIMBING_STAY
_play_animation()
if (
current_status == PlayerAnimationConfig.MOVEMENT_WALKING
or current_status == PlayerAnimationConfig.MOVEMENT_RUNNING
):
current_status = PlayerAnimationConfig.MOVEMENT_IDLE
# return whether the player status or facing direction has changed.
func _check_status(direction) -> bool:
var tmp_status = current_status
var new_facing_direction := facing_direction
if is_laying:
if direction.x:
new_facing_direction.x = direction.x
tmp_status = MOVEMENT_STATUS.LAYING_MOVING
else:
tmp_status = MOVEMENT_STATUS.LAYING_STAY
elif is_climbing:
if direction.y:
new_facing_direction.y = direction.y
tmp_status = MOVEMENT_STATUS.CLIMBING
else:
tmp_status = MOVEMENT_STATUS.CLIMBING_STAY
if direction.x:
new_facing_direction.x = direction.x
tmp_status = PlayerAnimationConfig.MOVEMENT_WALKING
if Input.is_action_pressed("run") and !current_animation_config["running_locked"]:
tmp_status = PlayerAnimationConfig.MOVEMENT_RUNNING
else:
if direction.x:
new_facing_direction.x = direction.x
tmp_status = MOVEMENT_STATUS.WALKING
if !running_locked and Input.is_action_pressed("run"):
tmp_status = MOVEMENT_STATUS.RUNNING
else:
tmp_status = MOVEMENT_STATUS.IDLE
tmp_status = PlayerAnimationConfig.MOVEMENT_IDLE
if new_facing_direction != facing_direction or tmp_status != current_status:
facing_direction = new_facing_direction
current_status = tmp_status
@ -119,86 +84,47 @@ func _check_status(direction) -> bool:
func set_facing_direction(direction: Vector2) -> void:
facing_direction = direction
# update status
_check_status(direction)
func _play_animation() -> void:
if not sprite:
return
# reset the os label position on animation changed.
_reset_os_and_shadow_position()
if facing_direction.x > 0.0:
sprite.play(current_animation_config[current_status][1])
else:
sprite.play(current_animation_config[current_status][0])
match current_status:
MOVEMENT_STATUS.IDLE:
if facing_direction.x > 0.0:
sprite.play(&"idle_r")
else:
sprite.play(&"idle_l")
PlayerAnimationConfig.MOVEMENT_IDLE:
footstep_timer.stop()
MOVEMENT_STATUS.WALKING:
if facing_direction.x > 0.0:
sprite.play(&"walking_r")
else:
sprite.play(&"walking_l")
footstep_timer.wait_time = 0.5
PlayerAnimationConfig.MOVEMENT_WALKING:
footstep_timer.wait_time = current_animation_config["walk_footstep"]
footstep_timer.start()
MOVEMENT_STATUS.RUNNING:
if facing_direction.x > 0.0:
sprite.play(&"running_r")
else:
sprite.play(&"running_l")
footstep_timer.wait_time = 7.0 / 10.0 / 2.0
PlayerAnimationConfig.MOVEMENT_RUNNING:
footstep_timer.wait_time = current_animation_config["run_footstep"]
footstep_timer.start()
MOVEMENT_STATUS.LAYING_STAY:
if facing_direction.x > 0.0:
sprite.play(&"laying_stay_r")
else:
sprite.play(&"laying_stay_l")
footstep_timer.stop()
MOVEMENT_STATUS.LAYING_MOVING:
if facing_direction.x > 0.0:
sprite.play(&"laying_moving_r")
else:
sprite.play(&"laying_moving_l")
footstep_timer.wait_time = 2.0 / 3.0
footstep_timer.start()
# MOVEMENT_STATUS.CLIMBING_STAY:
# sprite.play(&"climbing_stay")
# footstep_timer.stop()
# MOVEMENT_STATUS.CLIMBING:
# if facing_direction.y > 0.0:
# sprite.play(&"climbing_down")
# else:
# sprite.play(&"climbing_up")
# footstep_timer.wait_time = 2.0 / 3.0
# footstep_timer.start()
func _get_speed(direction: Vector2) -> Vector2:
match current_status:
MOVEMENT_STATUS.WALKING:
PlayerAnimationConfig.MOVEMENT_WALKING:
var speed_walking = current_animation_config["speed_walking"]
return Vector2(speed_walking * direction.x, 0.0)
MOVEMENT_STATUS.RUNNING:
PlayerAnimationConfig.MOVEMENT_RUNNING:
var speed_runnig = current_animation_config["speed_runnig"]
return Vector2(speed_runnig * direction.x, 0.0)
MOVEMENT_STATUS.LAYING_MOVING:
return Vector2(speed_laying * direction.x, 0.0)
MOVEMENT_STATUS.CLIMBING:
return Vector2(0, speed_climbing * direction.y)
return Vector2(0, 0)
func _physics_process(_delta: float) -> void:
if action_locked:
if action_locked or Engine.is_editor_hint():
velocity = Vector2.ZERO
return
# Add the gravity.
#if not is_on_floor():
#velocity += get_gravity() * delta
#if Input.is_action_just_pressed("jump") and is_on_floor():
#velocity.y = JUMP_VELOCITY
var x_direction := Input.get_axis("left", "right")
var y_direction := Input.get_axis("up", "down")
var direction := Vector2(x_direction, y_direction)
if _check_status(direction):
_play_animation()
_check_status(direction)
var speed := _get_speed(direction) as Vector2
velocity.x = move_toward(velocity.x, speed.x, 300.0) * velocity_ratio
velocity.y = move_toward(velocity.y, speed.y, 300.0) * velocity_ratio
@ -246,9 +172,8 @@ func release_player():
_play_animation()
func _draw() -> void:
pass
# # 绘制阴影,咱不启用
# func _draw() -> void:
# # 绘制阴影,暂不启用
# var animation = sprite.animation
# if not animation:
# return
@ -295,13 +220,13 @@ func _draw() -> void:
func _reset_os_and_shadow_position():
if sprite.animation:
if sprite and sprite.animation:
var texture = sprite.sprite_frames.get_frame_texture(sprite.animation, 0) as Texture2D
var size = texture.get_size()
# reset the os label position
os_pivot.position.y = -size.y * 0.5 * sprite.scale.x
# reset the shadow position
shadow_y = size.y * 0.5
# shadow_y = size.y * 0.5
var os_tween: Tween

View File

@ -26,17 +26,22 @@ region_rect = Rect2(24, 76, 38, 24)
modulate_color = Color(0.996078, 0.92549, 0.85098, 0.733333)
[node name="MainPlayer" type="CharacterBody2D"]
position = Vector2(50, 0)
collision_mask = 2
script = ExtResource("1_3a78y")
character = "小小蝶"
facing_direction = Vector2(-1, -1)
[node name="FootstepTimer" type="Timer" parent="."]
unique_name_in_owner = true
wait_time = 0.5
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."]
unique_name_in_owner = true
scale = Vector2(0.6, 0.6)
sprite_frames = ExtResource("2_3w63u")
animation = &"idle_r"
animation = &"c01_小小蝶_idle_l"
frame_progress = 0.927887
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("RectangleShape2D_fno82")
@ -53,8 +58,8 @@ height = 20.0
unique_name_in_owner = true
layout_mode = 3
anchors_preset = 0
offset_top = -20.0
offset_bottom = -20.0
offset_top = -37.2
offset_bottom = -37.2
mouse_filter = 2
[node name="MarginContainer" type="MarginContainer" parent="OSPivot"]
@ -75,6 +80,7 @@ mouse_filter = 2
[node name="PanelContainer" type="PanelContainer" parent="OSPivot/MarginContainer"]
unique_name_in_owner = true
modulate = Color(1, 1, 1, 0)
custom_minimum_size = Vector2(70, 0)
layout_mode = 2
size_flags_horizontal = 4

View File

@ -0,0 +1,65 @@
class_name PlayerAnimationConfig extends Object
enum {
MOVEMENT_IDLE,
MOVEMENT_WALKING,
MOVEMENT_RUNNING,
}
const ANIMATION_CONFIG = {
"吕萍":
{
"speed_walking": 75.0,
"running_locked": false,
"speed_runnig": 120.0,
"walk_footstep": 0.5,
"run_footstep": 7.0 / 10.0 / 2.0,
MOVEMENT_IDLE: [&"c00_吕萍_idle_left", &"c00_吕萍_idle_right"],
MOVEMENT_WALKING: [&"c00_吕萍_walking_left", &"c00_吕萍_walking_right"],
MOVEMENT_RUNNING: [&"c00_吕萍_running_left", &"c00_吕萍_running_right"],
},
"吕萍爬行":
{
"speed_walking": 50.0,
"running_locked": true,
"speed_runnig": 50.0,
"walk_footstep": 0.7,
"run_footstep": 0.7,
MOVEMENT_IDLE: [&"c02_吕萍_爬行_idle_l", &"c02_吕萍_爬行_idle_r"],
MOVEMENT_WALKING: [&"c02_吕萍_爬行_left", &"c02_吕萍_爬行_right"],
MOVEMENT_RUNNING: [&"c02_吕萍_爬行_left", &"c02_吕萍_爬行_right"],
},
"吕萍带小猫":
{
"speed_walking": 75.0,
"running_locked": true,
"speed_runnig": 75.0,
"walk_footstep": 0.5,
"run_footstep": 0.5,
MOVEMENT_IDLE: [&"c00_吕萍带小猫_idle_left", &"c00_吕萍带小猫_idle_right"],
MOVEMENT_WALKING: [&"c00_吕萍带小猫_walking_left", &"c00_吕萍带小猫_walking_right"],
MOVEMENT_RUNNING: [&"c00_吕萍带小猫_walking_left", &"c00_吕萍带小猫_walking_right"],
},
"小蝶":
{
"speed_walking": 75.0,
"running_locked": true,
"speed_runnig": 75.0,
"walk_footstep": 0.5,
"run_footstep": 7.0 / 10.0 / 2.0,
MOVEMENT_IDLE: [&"c00_吕萍_idle_left", &"c00_吕萍_idle_right"],
MOVEMENT_WALKING: [&"c00_吕萍_walking_left", &"c00_吕萍_walking_right"],
MOVEMENT_RUNNING: [&"c00_吕萍_running_left", &"c00_吕萍_running_right"],
},
"小小蝶":
{
"speed_walking": 75.0,
"running_locked": true,
"speed_runnig": 75.0,
"walk_footstep": 0.5,
"run_footstep": 7.0 / 10.0 / 2.0,
MOVEMENT_IDLE: [&"c01_小小蝶_idle_l", &"c01_小小蝶_idle_r"],
MOVEMENT_WALKING: [&"c01_小小蝶_walking_l", &"c01_小小蝶_walking_r"],
MOVEMENT_RUNNING: [&"c01_小小蝶_running_l", &"c01_小小蝶_running_r"],
},
}