This commit is contained in:
Reed 2025-12-29 11:54:31 +08:00
commit 4334f4a4b0
576 changed files with 30488 additions and 0 deletions

4
.editorconfig Normal file
View File

@ -0,0 +1,4 @@
root = true
[*]
charset = utf-8

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Godot 4+ specific ignores
.godot/
/android/

13
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# Rider 忽略的文件
/contentModel.xml
/.idea.phantom-agnes.iml
/modules.xml
/projectSettingsUpdater.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

4
.idea/encodings.xml Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
</project>

8
.idea/indexLayout.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="GdUnusedClass" enabled="false" level="INFORMATION" enabled_by_default="false" />
</profile>
</component>

View File

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="GdSdk" type="GdScript">
<CLASSES />
<JAVADOC />
<SOURCES>
<root url="file://$APPLICATION_HOME_DIR$/plugins/rider-gdscript/sdk/extracted/Master" />
</SOURCES>
</library>
</component>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

BIN
NOTENGINE/all.aseprite Normal file

Binary file not shown.

BIN
NOTENGINE/all.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

40
NOTENGINE/all.png.import Normal file
View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://oiqrlng3jvnu"
path="res://.godot/imported/all.png-42a8cf7109de190bbde0339d31b78a8d.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://NOTENGINE/all.png"
dest_files=["res://.godot/imported/all.png-42a8cf7109de190bbde0339d31b78a8d.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

BIN
_asset/all.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

40
_asset/all.png.import Normal file
View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://doxhsab56pe50"
path="res://.godot/imported/all.png-666b3389ee629c05e6ece1ebc382b254.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://_asset/all.png"
dest_files=["res://.godot/imported/all.png-666b3389ee629c05e6ece1ebc382b254.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

View File

@ -0,0 +1,26 @@
All assets in the pack have been repackaged and many have been modified by Brackeys.
LICENSE for all assets:
Creative Commons Zero (CC0)
CREDIT:
SPRITES by analogStudios_:
knight (https://analogstudios.itch.io/camelot)
slime (https://analogstudios.itch.io/dungeonsprites)
platforms and coin (https://analogstudios.itch.io/four-seasons-platformer-sprites)
SPRITES by RottingPixels:
world_tileset and fruit (https://rottingpixels.itch.io/four-seasons-platformer-tileset-16x16free)
WORLD TILESET originally
SOUNDS by Brackeys, Asbjørn Thirslund
MUSIC by Brackeys, Sofia Thirslund
FONTS by Jayvee Enaguas - HarvettFox96 - (https://www.dafont.com/pixel-operator.font?l[]=10&l[]=1)

View File

@ -0,0 +1,36 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://cbytas3yrpcm"
path="res://.godot/imported/PixelOperator8-Bold.ttf-b1cba22c9dd47952662a77198c0d4c94.fontdata"
[deps]
source_file="res://_asset/brackeys_platformer_assets/fonts/PixelOperator8-Bold.ttf"
dest_files=["res://.godot/imported/PixelOperator8-Bold.ttf-b1cba22c9dd47952662a77198c0d4c94.fontdata"]
[params]
Rendering=null
antialiasing=1
generate_mipmaps=false
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
modulate_color_glyphs=false
hinting=1
subpixel_positioning=4
keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}

View File

@ -0,0 +1,36 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://cqtuqjbnswp2q"
path="res://.godot/imported/PixelOperator8.ttf-c3448ca90e1667ccda726c5e4dff9ea8.fontdata"
[deps]
source_file="res://_asset/brackeys_platformer_assets/fonts/PixelOperator8.ttf"
dest_files=["res://.godot/imported/PixelOperator8.ttf-c3448ca90e1667ccda726c5e4dff9ea8.fontdata"]
[params]
Rendering=null
antialiasing=1
generate_mipmaps=false
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
modulate_color_glyphs=false
hinting=1
subpixel_positioning=4
keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}

View File

@ -0,0 +1,19 @@
[remap]
importer="mp3"
type="AudioStreamMP3"
uid="uid://qitj6xva2whp"
path="res://.godot/imported/time_for_adventure.mp3-650c944b52016e3af9f2ccdac8b50c4c.mp3str"
[deps]
source_file="res://_asset/brackeys_platformer_assets/music/time_for_adventure.mp3"
dest_files=["res://.godot/imported/time_for_adventure.mp3-650c944b52016e3af9f2ccdac8b50c4c.mp3str"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

Binary file not shown.

View File

@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://ev0r1v3ikw84"
path="res://.godot/imported/coin.wav-fc0d38a2d5098eeb7fa27e34a266ab06.sample"
[deps]
source_file="res://_asset/brackeys_platformer_assets/sounds/coin.wav"
dest_files=["res://.godot/imported/coin.wav-fc0d38a2d5098eeb7fa27e34a266ab06.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2

Binary file not shown.

View File

@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://dikl0lf6yck1h"
path="res://.godot/imported/explosion.wav-9065931af2ee674a8c896c6c4f8fb4cc.sample"
[deps]
source_file="res://_asset/brackeys_platformer_assets/sounds/explosion.wav"
dest_files=["res://.godot/imported/explosion.wav-9065931af2ee674a8c896c6c4f8fb4cc.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2

Binary file not shown.

View File

@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://bttfdx40rlhgb"
path="res://.godot/imported/hurt.wav-59fed8a2d9027ab66e8c222616ee6ca7.sample"
[deps]
source_file="res://_asset/brackeys_platformer_assets/sounds/hurt.wav"
dest_files=["res://.godot/imported/hurt.wav-59fed8a2d9027ab66e8c222616ee6ca7.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2

Binary file not shown.

View File

@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://biew65u5bw68p"
path="res://.godot/imported/jump.wav-f543d4993c937381059c98b4a0fe0f50.sample"
[deps]
source_file="res://_asset/brackeys_platformer_assets/sounds/jump.wav"
dest_files=["res://.godot/imported/jump.wav-f543d4993c937381059c98b4a0fe0f50.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2

Binary file not shown.

View File

@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://d2cg4al661d7a"
path="res://.godot/imported/power_up.wav-3502c78671bb1aa46d526d676fb311c9.sample"
[deps]
source_file="res://_asset/brackeys_platformer_assets/sounds/power_up.wav"
dest_files=["res://.godot/imported/power_up.wav-3502c78671bb1aa46d526d676fb311c9.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2

Binary file not shown.

View File

@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://dbrbmsi8uyul7"
path="res://.godot/imported/tap.wav-0dad550acf74388091fffd2a612c0bd6.sample"
[deps]
source_file="res://_asset/brackeys_platformer_assets/sounds/tap.wav"
dest_files=["res://.godot/imported/tap.wav-0dad550acf74388091fffd2a612c0bd6.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2

Binary file not shown.

After

Width:  |  Height:  |  Size: 500 B

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://blmcygf06lxay"
path="res://.godot/imported/coin.png-beb87bd1229e7a2d53bf557ba3336f7d.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://_asset/brackeys_platformer_assets/sprites/coin.png"
dest_files=["res://.godot/imported/coin.png-beb87bd1229e7a2d53bf557ba3336f7d.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://d3c7aj54lphin"
path="res://.godot/imported/fruit.png-a5a033fdb4a109b0ce0a99320ddfdcf0.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://_asset/brackeys_platformer_assets/sprites/fruit.png"
dest_files=["res://.godot/imported/fruit.png-a5a033fdb4a109b0ce0a99320ddfdcf0.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://db2kdmupks7xw"
path="res://.godot/imported/knight.png-10aa663a6019c3fc4ba27406a490bb65.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://_asset/brackeys_platformer_assets/sprites/knight.png"
dest_files=["res://.godot/imported/knight.png-10aa663a6019c3fc4ba27406a490bb65.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cyojkecmj2toq"
path="res://.godot/imported/platforms.png-201b994e8f646c2c9f88ffe6124bfb7e.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://_asset/brackeys_platformer_assets/sprites/platforms.png"
dest_files=["res://.godot/imported/platforms.png-201b994e8f646c2c9f88ffe6124bfb7e.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 908 B

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dw2i7jelr4a8q"
path="res://.godot/imported/slime_green.png-420249250f66a0ec31a3bd05dc2e2425.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://_asset/brackeys_platformer_assets/sprites/slime_green.png"
dest_files=["res://.godot/imported/slime_green.png-420249250f66a0ec31a3bd05dc2e2425.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://hh7y2udy3o41"
path="res://.godot/imported/slime_purple.png-e4c795221083c86fb16dcd605ac250e5.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://_asset/brackeys_platformer_assets/sprites/slime_purple.png"
dest_files=["res://.godot/imported/slime_purple.png-e4c795221083c86fb16dcd605ac250e5.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cmwkvb4c2n45h"
path="res://.godot/imported/world_tileset.png-80a9cd9d2174af6586e1c33c362cefcd.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://_asset/brackeys_platformer_assets/sprites/world_tileset.png"
dest_files=["res://.godot/imported/world_tileset.png-80a9cd9d2174af6586e1c33c362cefcd.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

View File

@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://bbdeag44ynd4"
path="res://.godot/imported/ai_jump_dirt.wav-89c40af2c8bcd6ee2b9de25fded3be4f.sample"
[deps]
source_file="res://_asset/sound/jump/ai_jump_dirt.wav"
dest_files=["res://.godot/imported/ai_jump_dirt.wav-89c40af2c8bcd6ee2b9de25fded3be4f.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2

12
_game/Game.tscn Normal file
View File

@ -0,0 +1,12 @@
[gd_scene load_steps=3 format=3 uid="uid://3vc8ojbiyy5w"]
[ext_resource type="PackedScene" uid="uid://gwhff4qaouxy" path="res://_player/Agens.tscn" id="1_fdx6o"]
[ext_resource type="PackedScene" uid="uid://1l06de041i40" path="res://_levels/l_level_1.tscn" id="1_pvnxo"]
[node name="Game" type="Node2D"]
[node name="level_1" parent="." instance=ExtResource("1_pvnxo")]
[node name="Agens" parent="." instance=ExtResource("1_fdx6o")]
position = Vector2(218, 251)
collision_mask = 4

View File

@ -0,0 +1,12 @@
[gd_scene load_steps=3 format=3 uid="uid://3vc8ojbiyy5w"]
[ext_resource type="PackedScene" uid="uid://gwhff4qaouxy" path="res://_player/Agens.tscn" id="1_fdx6o"]
[ext_resource type="PackedScene" uid="uid://1l06de041i40" path="res://_levels/l_level_1.tscn" id="1_pvnxo"]
[node name="Game" type="Node2D"]
[node name="level_1" parent="." instance=ExtResource("1_pvnxo")]
[node name="Agens" parent="." instance=ExtResource("1_fdx6o")]
position = Vector2(218, 251)
collision_mask = 4

View File

@ -0,0 +1,12 @@
[gd_scene load_steps=3 format=3 uid="uid://3vc8ojbiyy5w"]
[ext_resource type="PackedScene" uid="uid://gwhff4qaouxy" path="res://_player/Agens.tscn" id="1_fdx6o"]
[ext_resource type="PackedScene" uid="uid://1l06de041i40" path="res://_levels/l_level_1.tscn" id="1_pvnxo"]
[node name="Game" type="Node2D"]
[node name="level_1" parent="." instance=ExtResource("1_pvnxo")]
[node name="Agens" parent="." instance=ExtResource("1_fdx6o")]
position = Vector2(218, 251)
collision_mask = 4

17
_game/GameMain.tscn Normal file
View File

@ -0,0 +1,17 @@
[gd_scene load_steps=3 format=3 uid="uid://ctqkbmyjo65bk"]
[ext_resource type="Script" uid="uid://dn0ksjoswquf5" path="res://addons/reedscene/scene/SceneManager.gd" id="1_0sb54"]
[ext_resource type="Script" uid="uid://bwvbeodhvhrmw" path="res://addons/reedfx/vfx/VFXLayer.gd" id="2_ghnqe"]
[node name="GameMain" type="Node" node_paths=PackedStringArray("TransitionNode")]
script = ExtResource("1_0sb54")
TransitionNode = NodePath("Transition")
metadata/_custom_type_script = "uid://dn0ksjoswquf5"
[node name="Transition" type="Control" parent="."]
layout_mode = 3
anchors_preset = 0
[node name="ReedVFXLayer" type="CanvasLayer" parent="."]
script = ExtResource("2_ghnqe")
metadata/_custom_type_script = "uid://bwvbeodhvhrmw"

8
_levels/l_level_1.tscn Normal file

File diff suppressed because one or more lines are too long

8
_levels/l_test.tscn Normal file

File diff suppressed because one or more lines are too long

218
_player/Agens.tscn Normal file
View File

@ -0,0 +1,218 @@
[gd_scene load_steps=38 format=3 uid="uid://gwhff4qaouxy"]
[ext_resource type="Script" uid="uid://dq1g1qp66chwy" path="res://_player/agens.gd" id="1_rkqpu"]
[ext_resource type="Script" uid="uid://isu8onknb75o" path="res://_player/states/character_state_machine.gd" id="1_wvs5h"]
[ext_resource type="Script" uid="uid://15n8yfyr4eqj" path="res://_player/states/grounded.gd" id="2_5p50s"]
[ext_resource type="Texture2D" uid="uid://doxhsab56pe50" path="res://_asset/all.png" id="2_8nsdm"]
[ext_resource type="Script" uid="uid://dcfq4wnx2g6bs" path="res://_player/player_locomotion.gd" id="2_11vl8"]
[ext_resource type="Script" uid="uid://b5hkfpjbye70" path="res://_player/states/idle.gd" id="4_30i7g"]
[ext_resource type="BlackboardPlan" uid="uid://nlw7rxugv5uh" path="res://_player/bbp_player.tres" id="4_mwufa"]
[ext_resource type="Script" uid="uid://bpd54nf8oxwsb" path="res://_player/states/player_hsm.gd" id="6_8q4ov"]
[ext_resource type="Script" uid="uid://po21boe8iqcc" path="res://_player/states/move.gd" id="7_rrwxs"]
[ext_resource type="Script" uid="uid://cjf7kds0cipkw" path="res://_tools/limbo_state_helper.gd" id="8_clxy3"]
[ext_resource type="Script" uid="uid://bbsdsqxujlsbp" path="res://_player/states/airbone.gd" id="8_d42ye"]
[ext_resource type="Script" uid="uid://db6ttwe3skqfv" path="res://_player/states/fall.gd" id="9_iqoog"]
[ext_resource type="Script" uid="uid://dh3115a8iyabg" path="res://_player/states/jump.gd" id="10_mwufa"]
[ext_resource type="Script" uid="uid://cky34pinqpewd" path="res://_player/states/ghost.gd" id="12_8nsdm"]
[ext_resource type="Script" uid="uid://dhlg4ct8al76c" path="res://_player/states/wall_jump.gd" id="12_basl5"]
[ext_resource type="Script" uid="uid://fpfkas0s46xq" path="res://_player/states/on_wall.gd" id="13_l6fs8"]
[ext_resource type="Script" uid="uid://cpruvcwcgmdrx" path="res://_player/states/climb_jump.gd" id="15_l6fs8"]
[ext_resource type="Script" uid="uid://bjjatv4bxv7w" path="res://_player/states/climb.gd" id="15_mt2s8"]
[ext_resource type="Script" uid="uid://d0mw2e4u5u8g" path="res://_player/states/grap_hook.gd" id="16_f07it"]
[ext_resource type="Script" uid="uid://diq7vk63exae7" path="res://_player/states/hook_shooting.gd" id="16_xcbik"]
[ext_resource type="Script" uid="uid://ca88urm45gx2c" path="res://_player/states/dead.gd" id="17_5r2pj"]
[ext_resource type="PackedScene" uid="uid://blm8q46h3v2im" path="res://addons/reedcomponent/locomotion/wall_detector.tscn" id="20_air0b"]
[ext_resource type="Script" uid="uid://bhexx6mj1xv3q" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="20_ogl63"]
[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="21_5r2pj"]
[ext_resource type="Script" uid="uid://bkkkyugppu7sl" path="res://addons/reedcomponent/grap_hook/spawn_hook_component.gd" id="21_p14kj"]
[ext_resource type="Script" uid="uid://ta2r2bc1nrwe" path="res://addons/reedfx/vfx/VFXManager.gd" id="24_mwlgv"]
[ext_resource type="Script" uid="uid://lp1ge1qbyfr3" path="res://addons/reedfx/sfx/SFXManager.gd" id="24_x5g5e"]
[ext_resource type="Script" uid="uid://du267phqvtqyr" path="res://addons/reedfx/sfx/SFXSignalBinding.gd" id="25_rjd7i"]
[ext_resource type="Script" uid="uid://dipfdfnp506hl" path="res://addons/reedfx/vfx/VFXSignalBinding.gd" id="25_s5egm"]
[ext_resource type="Resource" uid="uid://cb73bysplqpo7" path="res://_player/effect_binding/jump_sound.tres" id="26_256x0"]
[ext_resource type="Resource" uid="uid://do0bnwse614jw" path="res://_player/effect_binding/land_dust.tres" id="26_s5egm"]
[ext_resource type="Script" uid="uid://bijoqygv6tncj" path="res://addons/reedcomponent/SingleComponentRemotor.gd" id="28_mxt3b"]
[ext_resource type="Resource" uid="uid://bdad4yjv1q0uu" path="res://_player/effect_binding/jump_dust.tres" id="30_hquoe"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_qnulu"]
size = Vector2(9, 23)
[sub_resource type="AtlasTexture" id="AtlasTexture_basl5"]
atlas = ExtResource("2_8nsdm")
region = Rect2(9, 22, 13, 26)
[sub_resource type="Resource" id="Resource_p14kj"]
script = ExtResource("21_5r2pj")
[sub_resource type="RectangleShape2D" id="RectangleShape2D_ogl63"]
size = Vector2(10, 25)
[node name="Agens" type="CharacterBody2D" groups=["PLAYER"]]
collision_layer = 2
collision_mask = 0
platform_wall_layers = 4
script = ExtResource("1_rkqpu")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("RectangleShape2D_qnulu")
[node name="Sprite2D" type="Sprite2D" parent="."]
texture_filter = 1
position = Vector2(0, -2)
texture = SubResource("AtlasTexture_basl5")
[node name="LimboStateDebugger" type="Node2D" parent="." node_paths=PackedStringArray("state_root")]
script = ExtResource("8_clxy3")
state_root = NodePath("../PlayerHSM/Normal")
draw_offset = Vector2(20, -10)
[node name="PlayerHSM" type="LimboHSM" parent="."]
blackboard_plan = ExtResource("4_mwufa")
unique_name_in_owner = true
script = ExtResource("6_8q4ov")
[node name="Normal" type="LimboHSM" parent="PlayerHSM"]
unique_name_in_owner = true
script = ExtResource("1_wvs5h")
[node name="Grounded" type="LimboHSM" parent="PlayerHSM/Normal"]
unique_name_in_owner = true
script = ExtResource("2_5p50s")
[node name="Idle" type="LimboState" parent="PlayerHSM/Normal/Grounded"]
unique_name_in_owner = true
script = ExtResource("4_30i7g")
[node name="Move" type="LimboState" parent="PlayerHSM/Normal/Grounded"]
unique_name_in_owner = true
script = ExtResource("7_rrwxs")
[node name="Airbone" type="LimboHSM" parent="PlayerHSM/Normal"]
unique_name_in_owner = true
script = ExtResource("8_d42ye")
[node name="Fall" type="LimboState" parent="PlayerHSM/Normal/Airbone"]
unique_name_in_owner = true
script = ExtResource("9_iqoog")
[node name="Jump" type="LimboState" parent="PlayerHSM/Normal/Airbone"]
unique_name_in_owner = true
script = ExtResource("10_mwufa")
[node name="WallJump" type="LimboState" parent="PlayerHSM/Normal/Airbone"]
unique_name_in_owner = true
script = ExtResource("12_basl5")
[node name="OnWall" type="LimboHSM" parent="PlayerHSM/Normal"]
unique_name_in_owner = true
script = ExtResource("13_l6fs8")
[node name="Climb" type="LimboState" parent="PlayerHSM/Normal/OnWall"]
unique_name_in_owner = true
script = ExtResource("15_mt2s8")
[node name="ClimbJump" type="LimboState" parent="PlayerHSM/Normal/OnWall"]
unique_name_in_owner = true
script = ExtResource("15_l6fs8")
[node name="GrapHook" type="LimboHSM" parent="PlayerHSM/Normal"]
unique_name_in_owner = true
script = ExtResource("16_f07it")
[node name="HookShooting" type="LimboState" parent="PlayerHSM/Normal/GrapHook"]
unique_name_in_owner = true
script = ExtResource("16_xcbik")
grap_hook_shooting_time = 0.2
[node name="Hooking" type="LimboState" parent="PlayerHSM/Normal/GrapHook"]
unique_name_in_owner = true
[node name="Dash" type="LimboState" parent="PlayerHSM/Normal"]
unique_name_in_owner = true
script = ExtResource("12_8nsdm")
[node name="Dead" type="LimboState" parent="PlayerHSM"]
unique_name_in_owner = true
script = ExtResource("17_5r2pj")
[node name="LocomotionComponent" type="Node" parent="."]
unique_name_in_owner = true
script = ExtResource("2_11vl8")
dash_speed = 400.0
end_dash_speed = 190.0
climb_hop_velocity_x = 180.0
climb_hop_velocity_y = 334.0
wall_jump_base_force_x = 260.0
wall_jump_base_force_y = 220.0
fall_maxium_speed = 430.0
air_control_mult = 0.7
run_accel = 2100.0
run_reduce = 420.0
move_speed_max = 157.0
[node name="WallDetector" parent="LocomotionComponent" instance=ExtResource("20_air0b")]
unique_name_in_owner = true
[node name="MidRayCast2D" parent="LocomotionComponent/WallDetector" index="1"]
position = Vector2(0, 3)
[node name="SpawnHookComponet" type="Node" parent="." node_paths=PackedStringArray("binded_hook_ray_cast_2d")]
script = ExtResource("21_p14kj")
binded_hook_ray_cast_2d = NodePath("HookCheckRayer")
binded_hook_move_input_property_name = &"m_input_intent_direction"
metadata/_custom_type_script = "uid://bkkkyugppu7sl"
[node name="HookCheckRayer" type="RayCast2D" parent="SpawnHookComponet"]
collision_mask = 4
[node name="ReedSFXMananger" type="Node" parent="."]
script = ExtResource("24_x5g5e")
bindings = Array[ExtResource("25_rjd7i")]([ExtResource("26_256x0")])
metadata/_custom_type_script = "uid://lp1ge1qbyfr3"
[node name="ReedVFXManager" type="Node" parent="."]
script = ExtResource("24_mwlgv")
bindings = Array[ExtResource("25_s5egm")]([ExtResource("26_s5egm"), ExtResource("30_hquoe")])
metadata/_custom_type_script = "uid://ta2r2bc1nrwe"
[node name="PhantomCamera2D" type="Node2D" parent="."]
position = Vector2(50, -75)
script = ExtResource("20_ogl63")
tween_resource = SubResource("Resource_p14kj")
metadata/_custom_type_script = "uid://bhexx6mj1xv3q"
[node name="HitBox" type="Area2D" parent="."]
unique_name_in_owner = true
collision_layer = 0
collision_mask = 8
[node name="CollisionShape2D" type="CollisionShape2D" parent="HitBox"]
position = Vector2(0, -2.5)
shape = SubResource("RectangleShape2D_ogl63")
debug_color = Color(0.95815283, 0, 0.5313341, 0.41960785)
[node name="RemotePositionSetting" type="Node2D" parent="."]
[node name="Remotor[HookCheckRayer]" type="RemoteTransform2D" parent="RemotePositionSetting"]
remote_path = NodePath("../../SpawnHookComponet/HookCheckRayer")
update_rotation = false
update_scale = false
script = ExtResource("28_mxt3b")
observed_remote_path = NodePath("../../SpawnHookComponet/HookCheckRayer")
metadata/_custom_type_script = "uid://bijoqygv6tncj"
[node name="Remotor[WallDetector]" type="RemoteTransform2D" parent="RemotePositionSetting"]
remote_path = NodePath("../../LocomotionComponent/WallDetector")
update_rotation = false
update_scale = false
script = ExtResource("28_mxt3b")
observed_remote_path = NodePath("../../LocomotionComponent/WallDetector")
metadata/_custom_type_script = "uid://bijoqygv6tncj"
[node name="FootPosMarker" type="Marker2D" parent="."]
unique_name_in_owner = true
position = Vector2(0, 11)
[connection signal="v_land_dust" from="." to="." method="_on_v_land_dust"]
[editable path="LocomotionComponent/WallDetector"]

View File

@ -0,0 +1,120 @@
[gd_scene load_steps=21 format=3 uid="uid://gwhff4qaouxy"]
[ext_resource type="Script" uid="uid://dq1g1qp66chwy" path="res://_player/agens.gd" id="1_rkqpu"]
[ext_resource type="Script" uid="uid://isu8onknb75o" path="res://_player/states/character_state_machine.gd" id="1_wvs5h"]
[ext_resource type="Script" uid="uid://15n8yfyr4eqj" path="res://_player/states/grounded.gd" id="2_5p50s"]
[ext_resource type="Texture2D" uid="uid://doxhsab56pe50" path="res://_asset/all.png" id="2_8nsdm"]
[ext_resource type="Script" uid="uid://dcfq4wnx2g6bs" path="res://_player/player_locomotion.gd" id="2_11vl8"]
[ext_resource type="Script" uid="uid://b5hkfpjbye70" path="res://_player/states/idle.gd" id="4_30i7g"]
[ext_resource type="BlackboardPlan" uid="uid://nlw7rxugv5uh" path="res://_player/bbp_player.tres" id="4_mwufa"]
[ext_resource type="Script" uid="uid://bpd54nf8oxwsb" path="res://_player/states/player_hsm.gd" id="6_8q4ov"]
[ext_resource type="Script" uid="uid://po21boe8iqcc" path="res://_player/states/move.gd" id="7_rrwxs"]
[ext_resource type="Script" uid="uid://cjf7kds0cipkw" path="res://_tools/limbo_state_helper.gd" id="8_clxy3"]
[ext_resource type="Script" uid="uid://bbsdsqxujlsbp" path="res://_player/states/airbone.gd" id="8_d42ye"]
[ext_resource type="Script" uid="uid://db6ttwe3skqfv" path="res://_player/states/fall.gd" id="9_iqoog"]
[ext_resource type="Script" uid="uid://dh3115a8iyabg" path="res://_player/states/jump.gd" id="10_mwufa"]
[ext_resource type="Script" uid="uid://cky34pinqpewd" path="res://_player/states/ghost.gd" id="12_8nsdm"]
[ext_resource type="Script" uid="uid://dhlg4ct8al76c" path="res://_player/states/wall_jump.gd" id="12_basl5"]
[ext_resource type="Script" uid="uid://fpfkas0s46xq" path="res://_player/states/on_wall.gd" id="13_l6fs8"]
[ext_resource type="Script" uid="uid://bjjatv4bxv7w" path="res://_player/states/climb.gd" id="15_mt2s8"]
[ext_resource type="PackedScene" uid="uid://blm8q46h3v2im" path="res://addons/reedcomponent/locomotion/wall_detector.tscn" id="20_air0b"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_qnulu"]
size = Vector2(9, 23)
[sub_resource type="AtlasTexture" id="AtlasTexture_basl5"]
atlas = ExtResource("2_8nsdm")
region = Rect2(9, 22, 13, 26)
[node name="Agens" type="CharacterBody2D"]
platform_wall_layers = 4
script = ExtResource("1_rkqpu")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(-0.5, -0.5)
shape = SubResource("RectangleShape2D_qnulu")
[node name="Sprite2D" type="Sprite2D" parent="."]
texture_filter = 1
position = Vector2(0, -2)
texture = SubResource("AtlasTexture_basl5")
[node name="PlayerHSM" type="LimboHSM" parent="."]
blackboard_plan = ExtResource("4_mwufa")
unique_name_in_owner = true
script = ExtResource("6_8q4ov")
[node name="Normal" type="LimboHSM" parent="PlayerHSM"]
unique_name_in_owner = true
script = ExtResource("1_wvs5h")
[node name="Grounded" type="LimboHSM" parent="PlayerHSM/Normal"]
unique_name_in_owner = true
script = ExtResource("2_5p50s")
[node name="Idle" type="LimboState" parent="PlayerHSM/Normal/Grounded"]
unique_name_in_owner = true
script = ExtResource("4_30i7g")
[node name="Move" type="LimboState" parent="PlayerHSM/Normal/Grounded"]
unique_name_in_owner = true
script = ExtResource("7_rrwxs")
[node name="Airbone" type="LimboHSM" parent="PlayerHSM/Normal"]
unique_name_in_owner = true
script = ExtResource("8_d42ye")
[node name="Fall" type="LimboState" parent="PlayerHSM/Normal/Airbone"]
unique_name_in_owner = true
script = ExtResource("9_iqoog")
[node name="Jump" type="LimboState" parent="PlayerHSM/Normal/Airbone"]
unique_name_in_owner = true
script = ExtResource("10_mwufa")
[node name="WallJump" type="LimboState" parent="PlayerHSM/Normal/Airbone"]
unique_name_in_owner = true
script = ExtResource("12_basl5")
[node name="OnWall" type="LimboHSM" parent="PlayerHSM/Normal"]
unique_name_in_owner = true
script = ExtResource("13_l6fs8")
[node name="Climb" type="LimboState" parent="PlayerHSM/Normal/OnWall"]
unique_name_in_owner = true
script = ExtResource("15_mt2s8")
[node name="ClimbHop" type="LimboState" parent="PlayerHSM/Normal/OnWall"]
unique_name_in_owner = true
[node name="ClimbJump" type="LimboState" parent="PlayerHSM/Normal/OnWall"]
unique_name_in_owner = true
[node name="Dash" type="LimboState" parent="PlayerHSM/Normal"]
unique_name_in_owner = true
script = ExtResource("12_8nsdm")
[node name="Dead" type="LimboState" parent="PlayerHSM"]
unique_name_in_owner = true
[node name="LocomotionComponent" type="Node" parent="."]
unique_name_in_owner = true
script = ExtResource("2_11vl8")
fall_maxium_speed = 430.0
air_control_mult = 0.7
run_accel = 2100.0
run_reduce = 420.0
move_speed_max = 157.0
[node name="LimboStateDebugger" type="Node2D" parent="." node_paths=PackedStringArray("state_root")]
script = ExtResource("8_clxy3")
state_root = NodePath("../PlayerHSM/Normal")
draw_offset = Vector2(20, -10)
[node name="WallCheckRayer" type="RayCast2D" parent="."]
unique_name_in_owner = true
target_position = Vector2(14, 0)
collision_mask = 4
[node name="WallDetector" parent="." instance=ExtResource("20_air0b")]
unique_name_in_owner = true

174
_player/agens.gd Normal file
View File

@ -0,0 +1,174 @@
class_name Player extends CharacterBody2D
@onready var locomotion_comp: LocomotionComponent = %LocomotionComponent
@onready var hsm: LimboHSM = %PlayerHSM
@onready var wall_detector: WallDetector = %WallDetector
@onready var hit_box: Area2D = %HitBox
@onready var spawn_hook_comp: SpawnHookComponet = $SpawnHookComponet
@onready var foot_pos_marker: Marker2D = %FootPosMarker
enum Direction{LEFT,RIGHT}
var direction: Direction = Direction.RIGHT: set = _player_direction_changed
var m_jump_press: bool = false
var m_dash_press: bool = false
var m_climb_press: bool = false
var m_grap_hook_press: bool = false
##用于记录当前玩家输入的朝向
var m_input_intent_direction: Vector2
var is_dead: bool = false:
set(value):
is_dead = value
if is_dead:
locomotion_comp.is_active = false
GlobalEvent.boradcast_player_dead_event()
player_dead.emit()
signal player_direction_changed(direction: Direction)
signal player_dead
##落地尘土特效
signal v_land_dust
##奔跑尘土特效
signal v_run_dust
##跳跃尘土特效
signal v_jump_dust
##跳跃声音特效
signal s_jump_sound
func _ready() -> void:
self.player_direction_changed.connect(_handle_direction_changed)
self.hit_box.area_entered.connect(_handle_hit_box_entered)
self.hit_box.body_entered.connect(_handle_hit_box_entered)
func _draw() -> void:
draw_string(ThemeDB.fallback_font,Vector2.ZERO,str(get_wall_normal()))
func _process(delta: float) -> void:
queue_redraw()
func _physics_process(delta: float) -> void:
##用於更新輸入的朝向
m_input_intent_direction = Input.get_vector(
"move_left",
"move_right",
"move_up",
"move_down"
)
spawn_hook_comp.set_ray_direction(m_input_intent_direction)
func _unhandled_input(event: InputEvent) -> void:
if event.is_echo():
return
#jump input
if event.is_action_pressed(&"jump"):
m_jump_press = true
_handle_jump_press()
if event.is_action_released(&"jump"):
m_jump_press = false
_handle_jump_release()
#dash input
if event.is_action_pressed(&"dash"):
m_dash_press = true
_handle_dash_press()
if event.is_action_released(&"dash"):
m_dash_press = false
#climb input
if event.is_action_pressed(&"climb"):
m_climb_press = true
_handle_climb_press()
if event.is_action_released(&"climb"):
m_climb_press = false
_handle_climb_release()
#grap hook input
if event.is_action_pressed(&"grap_hook"):
m_grap_hook_press = true
_handle_grap_hook_press()
if event.is_action_released(&"grap_hook"):
m_grap_hook_press = false
_handle_grap_hook_release()
#region 输入处理
'''对于单次的输入触发动作,我们发送一个格式为
want_to_...hsm
'''
##处理 jump 单次输入
func _handle_jump_press() -> void:
if not m_jump_press:
return
hsm.dispatch(&"trigger_jump")
func _handle_jump_release() -> void:
hsm.dispatch(&"completed_jump")
##处理 Dash 单次输入
func _handle_dash_press() -> void:
if not m_dash_press:
return
hsm.dispatch(&"trigger_dash")
##处理 climb 输入
func _handle_climb_press() -> void:
if not m_climb_press:
return
hsm.dispatch(&"trigger_climb")
func _handle_climb_release() -> void:
hsm.dispatch(&"completed_climb")
##处理 Grap Hook 输入
func _handle_grap_hook_press() -> void:
hsm.dispatch(&"trigger_grap_hook")
func _handle_grap_hook_release() -> void:
hsm.dispatch(&"completed_grap_hook")
#endregion
##玩家方向改变时更新
func _handle_direction_changed(value: Direction):
match value:
Direction.RIGHT:
wall_detector.flip_h = false
Direction.LEFT:
wall_detector.flip_h = true
func _handle_hit_box_entered(node: Node2D)-> void:
hsm.dispatch(&"try_enter_dead")
func _player_direction_changed(value: Direction):
if self.direction == value:
return
direction = value
player_direction_changed.emit(direction)
##播放落地尘土特效
func on_land_dust() -> void:
v_land_dust.emit({"world_pos": foot_pos_marker.global_position})
##播放落地尘土特效
func on_run_dust() -> void:
v_run_dust.emit({"world_pos": foot_pos_marker.global_position})
##播放落地尘土特效
func on_jump() -> void:
v_jump_dust.emit({"world_pos": foot_pos_marker.global_position})
s_jump_sound.emit()
##工具函数
static func get_direction_vector(dir: Direction) -> Vector2:
return Vector2(1,0) if dir == Direction.RIGHT else Vector2(-1,0)

1
_player/agens.gd.uid Normal file
View File

@ -0,0 +1 @@
uid://dq1g1qp66chwy

23
_player/bbp_player.tres Normal file
View File

@ -0,0 +1,23 @@
[gd_resource type="BlackboardPlan" format=3 uid="uid://nlw7rxugv5uh"]
[resource]
var/want_to_jump/name = &"want_to_jump"
var/want_to_jump/type = 1
var/want_to_jump/value = false
var/want_to_jump/hint = 0
var/want_to_jump/hint_string = ""
var/had_jump/name = &"had_jump"
var/had_jump/type = 1
var/had_jump/value = false
var/had_jump/hint = 0
var/had_jump/hint_string = ""
var/is_dashing/name = &"is_dashing"
var/is_dashing/type = 1
var/is_dashing/value = false
var/is_dashing/hint = 0
var/is_dashing/hint_string = ""
var/lock_direction_changed/name = &"lock_direction_changed"
var/lock_direction_changed/type = 1
var/lock_direction_changed/value = false
var/lock_direction_changed/hint = 0
var/lock_direction_changed/hint_string = ""

View File

@ -0,0 +1,12 @@
[gd_resource type="Resource" script_class="VFXSignalBinding" load_steps=3 format=3 uid="uid://bdad4yjv1q0uu"]
[ext_resource type="Script" uid="uid://dipfdfnp506hl" path="res://addons/reedfx/vfx/VFXSignalBinding.gd" id="1_solj8"]
[ext_resource type="PackedScene" uid="uid://bs14s8ox4tk0i" path="res://_vfx/dust/land_dust.tscn" id="2_ttrqd"]
[resource]
script = ExtResource("1_solj8")
target_node = NodePath("..")
signal_name = &"v_jump_dust"
vfx_scene = ExtResource("2_ttrqd")
spawn_space = 1
metadata/_custom_type_script = "uid://dipfdfnp506hl"

View File

@ -0,0 +1,12 @@
[gd_resource type="Resource" script_class="SFXSignalBinding" load_steps=3 format=3 uid="uid://cb73bysplqpo7"]
[ext_resource type="Script" uid="uid://du267phqvtqyr" path="res://addons/reedfx/sfx/SFXSignalBinding.gd" id="1_isv5v"]
[ext_resource type="AudioStream" uid="uid://b4moh3s41xi44" path="res://_sfx/player/jump.tres" id="1_ri55b"]
[resource]
script = ExtResource("1_isv5v")
target_node = NodePath("..")
signal_name = &"s_jump_sound"
audio_stream = ExtResource("1_ri55b")
debug_print = true
metadata/_custom_type_script = "uid://du267phqvtqyr"

View File

@ -0,0 +1,12 @@
[gd_resource type="Resource" script_class="VFXSignalBinding" load_steps=3 format=3 uid="uid://do0bnwse614jw"]
[ext_resource type="Script" uid="uid://dipfdfnp506hl" path="res://addons/reedfx/vfx/VFXSignalBinding.gd" id="1_rik1v"]
[ext_resource type="PackedScene" uid="uid://bs14s8ox4tk0i" path="res://_vfx/dust/land_dust.tscn" id="2_t6jy7"]
[resource]
script = ExtResource("1_rik1v")
target_node = NodePath("..")
signal_name = &"v_land_dust"
vfx_scene = ExtResource("2_t6jy7")
spawn_space = 1
metadata/_custom_type_script = "uid://dipfdfnp506hl"

68
_player/ghost/Ghost.tscn Normal file
View File

@ -0,0 +1,68 @@
[gd_scene load_steps=8 format=3 uid="uid://cr372ml2gqjrw"]
[ext_resource type="Script" uid="uid://b7e4wue7oegre" path="res://_player/ghost/ghost.gd" id="1_4fcft"]
[ext_resource type="Texture2D" uid="uid://blmcygf06lxay" path="res://_asset/brackeys_platformer_assets/sprites/coin.png" id="1_jujku"]
[ext_resource type="Script" uid="uid://bvlda3myvuoy3" path="res://_player/ghost/ghost_locomotion.gd" id="2_23gor"]
[sub_resource type="CircleShape2D" id="CircleShape2D_xwnqk"]
radius = 6.0
[sub_resource type="Animation" id="Animation_23gor"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Sprite2D:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [0]
}
[sub_resource type="Animation" id="Animation_jujku"]
resource_name = "idle"
length = 1.5000125
loop_mode = 1
step = 0.125
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Sprite2D:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1, 1.125, 1.25, 1.375),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
"update": 1,
"values": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_s1rgc"]
_data = {
&"RESET": SubResource("Animation_23gor"),
&"idle": SubResource("Animation_jujku")
}
[node name="Ghost" type="CharacterBody2D"]
texture_filter = 1
script = ExtResource("1_4fcft")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("CircleShape2D_xwnqk")
[node name="Sprite2D" type="Sprite2D" parent="."]
texture = ExtResource("1_jujku")
hframes = 12
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
libraries = {
&"": SubResource("AnimationLibrary_s1rgc")
}
[node name="GhostLocomotion" type="Node" parent="."]
script = ExtResource("2_23gor")
should_post_process = true
should_apply_gravity = false

17
_player/ghost/ghost.gd Normal file
View File

@ -0,0 +1,17 @@
class_name Ghost extends CharacterBody2D
var _last_frame_direction : Vector2 = Vector2(1.0,0)
func _physics_process(delta: float) -> void:
#优先让移动的方向等于上一帧的方向防止出现Zero的情况上一帧移动方向的默认值是水平向右的
var h = Input.get_axis(&"move_left",&"move_right")
var v = Input.get_axis(&"move_down",&"move_up")
var _current_frame_direction = Vector2(h,v).normalized()
#只有在输入存在的情况下,我们才更新上一帧的方向
if _current_frame_direction != Vector2.ZERO:
_last_frame_direction = _current_frame_direction
var move_dir = _last_frame_direction

View File

@ -0,0 +1 @@
uid://b7e4wue7oegre

View File

@ -0,0 +1 @@
extends LocomotionComponent

View File

@ -0,0 +1 @@
uid://bvlda3myvuoy3

View File

@ -0,0 +1 @@
extends DashComponent

View File

@ -0,0 +1 @@
uid://dxakl6tx1wvfc

View File

@ -0,0 +1,191 @@
class_name CelesteLocomotionComponent extends JumpLocomotionComponent
#region 冲刺相关参数
@export_category("Dash Properties")
##最大的冲刺次数
@export var maxium_dash_count:int = 1
##Dash时的速度
@export var dash_speed: float = 240
##结束Dash的速度
@export var end_dash_speed: float = 160
##Dash的冷却时间
@export var dash_cold_down: float = .2
##是否在组件ready时自动补充所有的Dash次数
@export var auto_recover_dash_count_at_ready: bool = true
#endregion
#region 攀爬相关参数
@export_category("Climb Properties")
##角色最大耐力
@export var climb_max_stamina: float
##角色向上时的速度
@export var climb_max_speed_upward: float = 45.0
##角色向下时的速度
@export var climb_max_speed_downward: float = 80.0
##角色速度变化时的最大加速度
@export var climb_acceleration: float = 900.0
##攀爬到顶点时候的自动代偿速度X
@export var climb_hop_velocity_x: float = 80
##攀爬到顶点时候的自动代偿速度Y
@export var climb_hop_velocity_y: float = 160
##攀爬跳的速度X
@export var climb_jump_velocity_x: float = 160
##攀爬跳的速度Y
@export var climb_jump_velocity_y: float = 160
##攀爬跳的最大可输入时长
@export var climb_jump_time: float = .14
#endregion
#region 冲刺field
var last_dash_count: int
##此变量为总开关如果关闭则在物理更新里无论如何也是不会更新Dash的这里默认为false因为Dash需要手动触发最好不要常开
var can_dash: bool = false
var _dash_direction: Vector2 #存储Dash的Direction
signal dash_count_changed(count: int)
signal dash_brusted
signal dash_prepared
#endregion
#region 攀爬field
var can_climb: bool = false
var _climb_input: float
var _climb_hop_flag: bool = false
var _is_climb_jumping: bool = false
#endregion
func _init_component() -> void:
super._init_component()
if auto_recover_dash_count_at_ready:
full_recover_dash_count()
func _physics_process(delta: float) -> void:
if Engine.is_editor_hint():
return
if can_climb:
print("攀爬更新中")
_update_climb(delta)
characterbody.move_and_slide() #移动更新
return
if can_dash:
characterbody.move_and_slide()
return
super._physics_process(delta)
func _update_climb(delta) -> void:
var target_abs: float
#更新目标速度
if sign(_climb_input) == .0:
target_abs = 0
elif sign(_climb_input) > 0:
target_abs = climb_max_speed_downward
else:
target_abs = climb_max_speed_upward
var target = target_abs * _climb_input
characterbody.velocity.y = speed_approach(characterbody.velocity.y,target,climb_acceleration * delta)
func _update_dash(delta) -> void:
return
##整合之后的函数如果不需要额外的逻辑可以直接通过这个触发Dash
func integrate_dash(dash_dir: Vector2) -> bool:
if not predash(dash_dir):
return false
await get_tree().process_frame #等待一帧
brust_dash()
return true
##dash函数输入一个Dash的方向返回是否成功
func brust_dash() -> bool:
var old: Vector2 = characterbody.velocity;
var burst: Vector2 = _dash_direction.normalized() * dash_speed;
if sign(old.x) == sign(burst.x) and abs(old.x) > abs(burst.x):
burst.x = old.x
characterbody.velocity = burst
dash_brusted.emit()
return true
##dash准备函数需要在dash的前一帧触发
func predash(dash_dir: Vector2) -> bool:
if not get_can_dash():
return false
dash_prepared.emit()
last_dash_count = maxi(last_dash_count -1,0)
can_dash = true
_dash_direction = dash_dir
return true
##停止Dash实际上是关闭Dash标识符
func stop_dash(force_stop: bool = false) -> void:
if force_stop:
characterbody.velocity = Vector2.ZERO
characterbody.move_and_slide()
can_dash = false
##完全回复的Dash次数
func full_recover_dash_count() -> void:
dash_count_changed.emit(last_dash_count)
last_dash_count = maxium_dash_count
##回复指定数量的Dash次数
func recover_dash_count(recover_count : int) -> void:
last_dash_count = clampi(last_dash_count+ recover_count, 0,maxium_dash_count)
##子类可以重写此方法以自定义Dash的条件
func get_can_dash() -> bool:
return last_dash_count > 0
##添加攀爬的输入
func add_climb_input(input: float) -> bool:
_climb_input = input
return true
##开始攀爬
func start_climb(force_reset: bool = false) -> void:
if force_reset:
characterbody.velocity = Vector2.ZERO
characterbody.move_and_slide()
can_climb = true
##终止攀爬
func suspend_climb() -> void:
can_climb = false
##攀爬补充跳跃
func climb_hop() -> void:
_climb_hop_flag = true
characterbody.velocity = Vector2(climb_hop_velocity_x * Player.get_direction_vector(characterbody.direction).x,-1 * climb_hop_velocity_y)
func start_climb_jump() -> bool:
if _is_jumping : return false
#给与一个跳跃的补正速度
characterbody.velocity.x = _movement_input * climb_jump_velocity_x # 跳跃的水平补正速度
_jump_timer = climb_jump_time
_is_jumping = true
_is_climb_jumping = true
can_climb = false #取消掉原本的climb如果后续重新触发climb则重新判断
characterbody.velocity.y = _get_jump_force()
return true
func stop_climb_jump() -> void:
_is_jumping = false
_is_climb_jumping = false
func _get_jump_force() -> float:
if _is_climb_jumping:
return -1 * climb_jump_velocity_y
return super._get_jump_force()

View File

@ -0,0 +1 @@
uid://dcfq4wnx2g6bs

59
_player/states/airbone.gd Normal file
View File

@ -0,0 +1,59 @@
extends LimboHSM
@onready var root: Normal = %Normal
##自动跳跃逻辑
@export var auto_jump_cached_time: float = .2
var auto_jump_timer: float
func _setup() -> void:
#region Jump and fall
#Jump State -> Fall State
self.add_transition(root.jump_state,root.fall_state,root.jump_state.EVENT_FINISHED)
#Fall State -> Jump State
self.add_transition(root.fall_state,root.jump_state,&"air_to_jump")
#endregion
#region Wall jump
#ANYSTATE -> Wall Jump State
self.add_transition(ANYSTATE,root.wall_jump_state,&"wall_jump")
#Wall Jump State -> Fall State
self.add_transition(root.wall_jump_state,root.fall_state,root.wall_jump_state.EVENT_FINISHED)
#endregion
self.add_event_handler(&"trigger_jump",_handler_trigger_jump)
func _enter() -> void:
var want_to_jump = blackboard.get_var(&"want_to_jump",false)
initial_state = root.fall_state
if want_to_jump:
initial_state = root.jump_state
self.blackboard.set_var(&"want_to_jump",false)
func _update(delta: float) -> void:
if auto_jump_timer > 0:
auto_jump_timer -= delta
if agent.is_on_floor() && agent.velocity.y >= 0:
#自动跳
if auto_jump_timer > 0:
auto_jump_timer = 0
self.blackboard.set_var(&"want_to_jump",true)
change_active_state(root.jump_state)
get_root().dispatch(self.EVENT_FINISHED)
func _cache_auto_jump_timer() -> void:
auto_jump_timer = auto_jump_cached_time
#region 输入绑定事件
func _handler_trigger_jump() -> bool:
if agent.is_on_wall_only():
get_root().dispatch(&"wall_jump")
_cache_auto_jump_timer()
return true
#endregion

View File

@ -0,0 +1 @@
uid://bbsdsqxujlsbp

View File

@ -0,0 +1,92 @@
class_name Normal extends LimboHSM
@onready var ground_state : LimboHSM = %Grounded
@onready var idle_state: LimboState = %Idle
@onready var move_state: LimboState = %Move
@onready var airbone_state : LimboHSM = %Airbone
@onready var fall_state: LimboState = %Fall
@onready var jump_state: LimboState = %Jump
@onready var wall_jump_state: LimboState = %WallJump
@onready var on_wall_state: LimboHSM = %OnWall
@onready var climb_state: LimboState = %Climb
@onready var climb_jump_state: LimboState = %ClimbJump
@onready var dash_state: LimboState = %Dash
@onready var grap_hook_state: LimboHSM = %GrapHook
@onready var hook_shooting_state: LimboState = %HookShooting
@onready var hooking_state: LimboState = %Hooking
func _setup() -> void:
self._init_trans()
self._init_handler()
func _init_handler() -> void:
self.add_event_handler(&"trigger_dash",_handler_trigger_dash) ##处理Dash输入
self.add_event_handler(&"trigger_climb",_handler_trigger_climb) ##处理瞬时的climb
self.add_event_handler(&"trigger_grap_hook",_handler_grap_hook) ##处理grap hook 的輸入
func _init_trans() -> void:
self.add_transition(ground_state,airbone_state,ground_state.EVENT_FINISHED)
self.add_transition(airbone_state,ground_state,airbone_state.EVENT_FINISHED)
self.add_transition(ANYSTATE,dash_state,&"want_to_dash")
self.add_transition(dash_state,ground_state,&"exit_on_ground")
self.add_transition(dash_state,airbone_state,&"exit_on_air")
##用於處理貼在墻面的State流轉
self.add_transition(ANYSTATE,on_wall_state,&"want_to_on_wall")
self.add_transition(on_wall_state,airbone_state,&"exit_on_ground")
self.add_transition(on_wall_state,ground_state,&"exit_on_air")
##用於處理鈎爪的State流轉
self.add_transition(ANYSTATE,grap_hook_state,&"want_to_grap_hook")
self.add_transition(grap_hook_state,airbone_state,&"exit_on_ground")
self.add_transition(grap_hook_state,ground_state,&"exit_on_air")
func _update(delta: float) -> void:
process_direction()
##如果玩家当前在墙上并且玩家按下了climb
if agent.wall_detector.is_on_wall and agent.m_climb_press:
self.dispatch(&"want_to_on_wall")
##处理Dash输入
func _handler_trigger_dash() -> bool:
#如果当前无法Dash则返回
if not agent.locomotion_comp.get_can_dash():
return false
if get_root().blackboard.get_var(&"is_dashing",false):
return false
self.dispatch(&"want_to_dash")
return true
func _handler_trigger_climb() -> bool:
if not agent.is_on_wall():
return false
return true
func _handler_grap_hook() -> bool:
self.dispatch(&"want_to_grap_hook")
return true
func process_direction() -> void:
var b = get_root().blackboard.get_var(&"lock_direction_changed",false) as bool
if b: return
##切换方向的逻辑
var move_direction = Input.get_axis(&"move_left",&"move_right") as float
if move_direction * Player.get_direction_vector(agent.direction).x <= 0 and move_direction != 0:
agent.direction = Player.Direction.RIGHT if move_direction> 0 else Player.Direction.LEFT
func _get_dash_exit_enter_state()->LimboState:
if agent.is_on_floor():
return ground_state
else:
return airbone_state

View File

@ -0,0 +1 @@
uid://isu8onknb75o

30
_player/states/climb.gd Normal file
View File

@ -0,0 +1,30 @@
extends LimboState
func _setup() -> void:
self.add_event_handler(&"completed_climb",_handler_completed_climb)
func _enter() -> void:
agent.locomotion_comp.suspend_movement()
agent.locomotion_comp.stop_dash(true)
agent.locomotion_comp.start_climb(true)
get_root().blackboard.set_var(&"lock_direction_changed",true)
func _exit() -> void:
agent.locomotion_comp.enable_movement()
agent.locomotion_comp.suspend_climb()
get_root().blackboard.set_var(&"lock_direction_changed",false)
func _update(delta: float) -> void:
var climb_dir = Input.get_axis("move_up","move_down") as float
agent.locomotion_comp.add_climb_input(climb_dir)
var _enter_climb_hop = not agent.wall_detector.up_ray_on_wall and not agent.wall_detector.mid_ray_on_wall and agent.wall_detector.down_ray_on_wall and climb_dir< 0
if _enter_climb_hop:
agent.locomotion_comp.climb_hop()
self.dispatch(self.EVENT_FINISHED)
func _handler_completed_climb() -> bool:
self.dispatch(self.EVENT_FINISHED)
return true

View File

@ -0,0 +1 @@
uid://bjjatv4bxv7w

View File

@ -0,0 +1,4 @@
extends LimboState
func _enter() -> void:
agent.locomotion_comp.climb_hop()

View File

@ -0,0 +1 @@
uid://dpg7wsht1mg8d

View File

@ -0,0 +1,18 @@
extends LimboState
func _setup() -> void:
self.add_event_handler(&"completed_jump",_handler_completed_jump)
func _enter() -> void:
agent.locomotion_comp.start_climb_jump()
func _update(delta: float) -> void:
if agent.velocity.y >= 0:
get_root().dispatch(self.EVENT_FINISHED)
func _exit() -> void:
agent.locomotion_comp.stop_climb_jump()
func _handler_completed_jump() -> bool:
get_root().dispatch(self.EVENT_FINISHED)
return true

View File

@ -0,0 +1 @@
uid://cpruvcwcgmdrx

8
_player/states/dead.gd Normal file
View File

@ -0,0 +1,8 @@
extends LimboState
func _enter() -> void:
agent.is_dead = true
await get_tree().create_timer(.5).timeout
agent.queue_free()

View File

@ -0,0 +1 @@
uid://ca88urm45gx2c

29
_player/states/fall.gd Normal file
View File

@ -0,0 +1,29 @@
extends LimboState
##土狼跳缓存时间
@export var jump_grace_time: float = .14
var jump_grace_timer: float
func _setup() -> void:
self.add_event_handler(&"trigger_jump",_handler_trigger_jump)
func _enter() -> void:
jump_grace_timer = jump_grace_time
func _update(delta: float) -> void:
if jump_grace_timer > 0:
jump_grace_timer -= delta
var move_direction = Input.get_axis(&"move_left",&"move_right") as float
agent.locomotion_comp.add_movement_input(move_direction)
if move_direction == 0.0:
get_root().dispatch(self.EVENT_FINISHED)
return
func _handler_trigger_jump() -> bool:
if not get_root().blackboard.get_var(&"is_jumping",false):
if jump_grace_timer > 0:
get_root().dispatch(&"air_to_jump")
return false

View File

@ -0,0 +1 @@
uid://db6ttwe3skqfv

48
_player/states/ghost.gd Normal file
View File

@ -0,0 +1,48 @@
''' Dash的生命周期
1.
'''
extends LimboState
const DASH_FREEZE_TIME: float = .05
@export var dash_time: float = .15
var _dash_timer: float
func _enter() -> void:
get_root().blackboard.set_var(&"is_dashing",true) ##BB里锁住Dash状态
#禁用原本Locomotion Component的更新
agent.locomotion_comp.stop_movement()
agent.locomotion_comp.suspend_movement()
var dash_start_on_ground: bool = agent.is_on_floor()
agent.locomotion_comp.integrate_dash(_get_dash_direction())
_dash_timer = dash_time
func _exit() -> void:
blackboard.set_var(&"is_dashing",false) ##BB里清除Dash状态
agent.locomotion_comp.enable_movement()
agent.locomotion_comp.can_dash = false
func _update(delta: float) -> void:
if _dash_timer > 0:
_dash_timer -= delta
return
if agent.is_on_floor():
self.dispatch(&"exit_on_ground")
else:
self.dispatch(&"exit_on_air")
return
func _get_dash_direction() -> Vector2:
var r : Vector2
r = Vector2(1,0) if agent.direction == Player.Direction.RIGHT else Vector2(-1,0)
var dash_direction_x = Input.get_axis(&"move_left",&"move_right") as float
var dash_direction_y = Input.get_axis(&"move_up",&"move_down") as float
if dash_direction_x != 0 or dash_direction_y != 0:
r = Vector2(dash_direction_x,dash_direction_y)
return r

View File

@ -0,0 +1 @@
uid://cky34pinqpewd

View File

@ -0,0 +1,10 @@
extends LimboHSM
@onready var root: Normal = %Normal
func _setup() -> void:
self.add_transition(root.hook_shooting_state,root.hooking_state,root.hook_shooting_state.EVENT_FINISHED)
func _exit() -> void:
agent.locomotion_comp.enable_movement()
agent.spawn_hook_comp._current_grap_hook_inst._leave_rope()

View File

@ -0,0 +1 @@
uid://d0mw2e4u5u8g

View File

@ -0,0 +1,36 @@
extends LimboHSM
@onready var root: Normal = %Normal
func _setup() -> void:
self.add_transition(root.idle_state,root.move_state,root.idle_state.EVENT_FINISHED)
self.add_transition(root.move_state,root.idle_state,root.move_state.EVENT_FINISHED)
self.add_event_handler(&"trigger_jump",_handler_trigger_jump)
func _enter() -> void:
_land_from_air_check()
get_root().blackboard.set_var(&"is_jumping",false)
agent.locomotion_comp.full_recover_dash_count()
func _update(delta: float) -> void:
if not agent.is_on_floor() :
dispatch(self.EVENT_FINISHED)
func _handler_trigger_jump() -> bool:
self.blackboard.set_var(&"want_to_jump",true)
self.dispatch(self.EVENT_FINISHED)
return true
##无法在jump state 的时候进入grounded state
func _can_enter_grounded() -> bool:
return not get_active_state() == root.jump_state
func _land_from_air_check() -> bool:
var last_state = root.get_previous_active_state() as LimboState
if last_state and last_state == root.airbone_state :
agent.on_land_dust()
return true
return false

View File

@ -0,0 +1 @@
uid://15n8yfyr4eqj

View File

@ -0,0 +1,25 @@
extends LimboState
@export var grap_hook_shooting_time: float
var _timer: float
func _enter() -> void:
agent.locomotion_comp.suspend_movement()
agent.locomotion_comp.stop_dash(true)
agent.spawn_hook_comp.spawn_grap_hook_inst()
agent.spawn_hook_comp.grap_reach_target(grap_hook_shooting_time)
_timer = grap_hook_shooting_time
func _update(delta: float) -> void:
if _timer <= 0:
self.dispatch(self.EVENT_FINISHED)
_timer -= delta
func _exit() -> void:
#agent.locomotion_comp.enable_movement()
pass

View File

@ -0,0 +1 @@
uid://diq7vk63exae7

8
_player/states/idle.gd Normal file
View File

@ -0,0 +1,8 @@
extends LimboState
func _enter() -> void:
return
func _update(delta: float) -> void:
if Input.get_axis(&"move_left",&"move_right") != 0.0:
get_root().dispatch(self.EVENT_FINISHED)

View File

@ -0,0 +1 @@
uid://b5hkfpjbye70

36
_player/states/jump.gd Normal file
View File

@ -0,0 +1,36 @@
extends LimboState
@onready var root: Normal = %Normal
func _setup() -> void:
self.add_event_handler(&"completed_jump",_handler_completed_jump)
func _enter() -> void:
_jump_from_land_check()
var _j = agent.locomotion_comp.jump() as bool
get_root().blackboard.set_var(&"is_jumping",true) #标记jump
func _exit() -> void:
#这里强制重置一下
agent.locomotion_comp.stop_jump()
func _update(delta: float) -> void:
var move_dir = Input.get_axis(&"move_left",&"move_right")
agent.locomotion_comp.add_movement_input(move_dir)
if agent.velocity.y >= 0:
get_root().dispatch(self.EVENT_FINISHED)
func _handler_completed_jump() -> bool:
agent.locomotion_comp.stop_jump()
return true
func _jump_from_land_check() -> bool:
var last_state = root.get_previous_active_state() as LimboState
if last_state and last_state == root.ground_state :
agent.on_jump()
return true
return false

View File

@ -0,0 +1 @@
uid://dh3115a8iyabg

63
_player/states/move.gd Normal file
View File

@ -0,0 +1,63 @@
extends LimboState
@export var run_dust_distance:= 50
var _accelerated_distance: float
var _is_first_update: bool
var _last_frame_position: Vector2
var _run_dust_counter: float
func _enter() -> void:
_reset_distance()
_reset_run_dust_counter()
_is_first_update = true
return
func _exit() -> void:
_reset_distance()
func _update(delta: float) -> void:
_handle_move_input()
## 更新並獲取到delta ditance
var delta_distance = _update_accelerated_distance() as float
print(delta_distance)
## 如果移動了一定的距離則播放dust特效
_run_dust_counter -= delta_distance
if _run_dust_counter < 0:
agent.on_run_dust()
_reset_run_dust_counter()
func _handle_move_input() -> void:
var move_direction = Input.get_axis(&"move_left",&"move_right") as float
if move_direction == 0.0:
get_root().dispatch(self.EVENT_FINISHED)
agent.locomotion_comp.add_movement_input(0.0) #用0唤起制动加速度
return
agent.locomotion_comp.add_movement_input(move_direction)
##更新距離返回的是Delta Distance
func _update_accelerated_distance() -> float:
var c = agent.global_position as Vector2
if _is_first_update:
_last_frame_position = c
_accelerated_distance = 0
_is_first_update = false
return _accelerated_distance
var _delta = c.distance_to(_last_frame_position) as float
_last_frame_position = c
_accelerated_distance += _delta
return _delta
func _reset_distance() -> void:
_accelerated_distance = 0
_last_frame_position = Vector2.ZERO
func _reset_run_dust_counter() -> void:
_run_dust_counter = run_dust_distance

View File

@ -0,0 +1 @@
uid://po21boe8iqcc

Some files were not shown because too many files have changed in this diff Show More