Compare commits

...

30 Commits

Author SHA1 Message Date
Reed fd64d64adf 新视角下角色钩锁修正 2026-01-16 17:23:58 +08:00
Valerie ed424fc250 tilemap 2026-01-16 15:03:29 +08:00
Reed 16c3204375 Merge branch 'main' of http://47.99.99.211:3000/ReedZhu/godot-plateformer
OK
2026-01-16 14:16:36 +08:00
Reed a16ab33e4f 角色跳跃数据迭代 2026-01-16 14:16:25 +08:00
Valerie a7fbcfe7a6 character02 2026-01-16 14:15:33 +08:00
Valerie ddd50c9d5f new character and tile 2026-01-16 13:46:15 +08:00
Reed 11fc120236 新地图tile 规格测试 2026-01-16 13:22:02 +08:00
Valerie 00bd30e3b4 collisionTile 2026-01-16 10:51:56 +08:00
Reed c154b11ed2 简单建立ui 2026-01-15 17:43:58 +08:00
Reed 0e68c6e666 Merge branch 'main' of http://47.99.99.211:3000/ReedZhu/godot-plateformer 2026-01-15 16:09:33 +08:00
Reed 4e632582cf 暗物质球版本2 2026-01-15 16:09:20 +08:00
Valerie 7d4dc68196 Merge branch 'main' of http://47.99.99.211:3000/ReedZhu/godot-plateformer 2026-01-15 13:29:33 +08:00
Valerie 5993ef0769 tile 2026-01-15 13:24:31 +08:00
Valerie e1ac43a7a2 tile02 2026-01-15 13:21:12 +08:00
Valerie 477227a9cf new tile02 2026-01-15 13:19:10 +08:00
Reed c17031e029 暗物质球版本1 2026-01-15 13:01:31 +08:00
Valerie 0c4300d2ec new tile and spike 2026-01-15 12:55:37 +08:00
RedisTKey 0f8dcdd4b5 钩爪抓住下侧直接启动矿车逻辑 2026-01-14 23:34:00 +08:00
Valerie 876d08c4df tile and spike 2026-01-14 21:35:22 +08:00
Es 8e938469df 落石,矿车尺寸和数据调整,添加涟漪shader 2026-01-14 21:18:37 +08:00
RedisTKey 744a9010d6 关卡重置逻辑 2026-01-14 19:39:23 +08:00
RedisTKey 94bcf60a6d 相机follow的配置更新 2026-01-13 22:42:41 +08:00
Valerie 54936007b9 new tile02 2026-01-13 22:28:17 +08:00
Valerie 383a06ae9f new tile 2026-01-13 21:56:01 +08:00
Valerie 5bb225df93 new 2026-01-13 21:49:42 +08:00
Valerie f3e6848418 上传单元大小为96像素的基础地块 2026-01-13 21:06:46 +08:00
RedisTKey b18a1c0294 Merge branch 'feature/camera-refactor' 2026-01-13 20:14:54 +08:00
Es 4f109c218b 新增物件-易碎矿块;Lv1 s7-10微调;攀爬落石优化 2026-01-13 17:22:28 +08:00
Es b1fa8edf53 Level1 修改s4,s9;s10设计中 2026-01-12 19:25:33 +08:00
Es 15f9b93d95 Level1 s4-s9流程优化 2026-01-12 16:12:09 +08:00
95 changed files with 2799 additions and 487 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
# Godot 4+ specific ignores
.godot/
/android/
addons/limboai/bin/~liblimboai.windows.editor.x86_64.dll

108
__settings/SettingModel.gd Normal file
View File

@ -0,0 +1,108 @@
# scripts/settings/SettingsModel.gd
extends Node
class_name SettingsModel
## ===============================
## Dependencies
## ===============================
const SettingsSchema = preload("res://__settings/SettingSchema.gd")
const SettingsStorage = preload("res://__settings/SettingStorage.gd")
## ===============================
## Signals
## ===============================
signal setting_changed(section: String, key: String, value)
signal settings_applied
signal settings_reverted
## ===============================
## Internal State
## ===============================
var _data_committed : Dictionary = {} # 已生效 / 已保存
var _data_working : Dictionary = {} # UI 正在修改
var _storage := SettingsStorage.new()
## ===============================
## Lifecycle
## ===============================
func _ready() -> void:
_load()
## ===============================
## Public API (Read)
## ===============================
func get_setting(section: String, key: String) -> Variant:
return _data_working.get(section, {}).get(key)
func get_section(section: String) -> Dictionary:
return _data_working.get(section, {}).duplicate(true)
## ===============================
## Public API (Write - Working Only)
## ===============================
func set_setting(section: String, key: String, value: Variant) -> void:
if not _data_working.has(section):
_data_working[section] = {}
_data_working[section][key] = value
emit_signal("setting_changed", section, key, value)
## ===============================
## Typed Getters
## ===============================
func get_bool(section: String, key: String) -> bool:
var value = get_setting(section, key)
return value if typeof(value) == TYPE_BOOL else false
func get_int(section: String, key: String) -> int:
var value = get_setting(section, key)
return value if typeof(value) == TYPE_INT else 0
func get_float(section: String, key: String) -> float:
var value = get_setting(section, key)
if typeof(value) == TYPE_FLOAT or typeof(value) == TYPE_INT:
return float(value)
return 0.0
func get_string(section: String, key: String) -> String:
var value = get_setting(section, key)
return value if typeof(value) == TYPE_STRING else ""
## ===============================
## Transaction Control
## ===============================
func apply() -> void:
_data_committed = _data_working.duplicate(true)
for section in _data_committed.keys():
for key in _data_committed[section].keys():
_storage.set_value(section, key, _data_committed[section][key])
_storage.save()
emit_signal("settings_applied")
func revert() -> void:
_data_working = _data_committed.duplicate(true)
emit_signal("settings_reverted")
func has_unsaved_changes() -> bool:
return _data_working != _data_committed
## ===============================
## Internal
## ===============================
func _load() -> void:
_storage.load()
# 1. Load defaults
_data_committed = SettingsSchema.defaults().duplicate(true)
# 2. Override with saved values
for section in _data_committed.keys():
for key in _data_committed[section].keys():
var default_value = _data_committed[section][key]
var value = _storage.get_value(section, key, default_value)
_data_committed[section][key] = value
# 3. Init working copy
_data_working = _data_committed.duplicate(true)

View File

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

View File

@ -0,0 +1,22 @@
class_name SettingSchema
extends RefCounted
## ===============================
## 默认设置定义
## ===============================
static func defaults() -> Dictionary:
return {
"audio": {
"master_volume": 1.0,
"music_volume": 0.8,
"sfx_volume": 0.8,
},
"graphics": {
"quality": 2, # 0=low,1=mid,2=high
"fullscreen": true,
},
"input": {
# 这里只是占位,后面可扩展
"mouse_sensitivity": 1.0,
}
}

View File

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

View File

@ -0,0 +1,22 @@
# scripts/settings/SettingsStorage.gd
extends RefCounted
class_name SettingsStorage
const FILE_PATH := "user://settings.cfg"
var _config := ConfigFile.new()
func load() -> void:
_config.load(FILE_PATH)
func save() -> void:
_config.save(FILE_PATH)
func has(section: String, key: String) -> bool:
return _config.has_section_key(section, key)
func get_value(section: String, key: String, default):
return _config.get_value(section, key, default)
func set_value(section: String, key: String, value) -> void:
_config.set_value(section, key, value)

View File

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

View File

@ -0,0 +1,35 @@
extends RefCounted
class_name InputSchema
static func defaults() -> Dictionary:
return {
"move_left": [
_key(KEY_A),
_key(KEY_LEFT),
],
"move_right": [
_key(KEY_D),
_key(KEY_RIGHT),
],
"jump": [
_key(KEY_SPACE),
],
"attack": [
_mouse(MOUSE_BUTTON_LEFT),
],
}
## ===============================
## Helpers (序列化友好)
## ===============================
static func _key(keycode: int) -> Dictionary:
return {
"type": "key",
"keycode": keycode,
}
static func _mouse(button: int) -> Dictionary:
return {
"type": "mouse",
"button": button,
}

View File

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

View File

@ -0,0 +1,121 @@
extends Node
class_name InputSettingsModel
## ===============================
## Dependencies
## ===============================
const InputSchema = preload("res://__settings/input/InputSchema.gd")
const SettingsStorage = preload("res://__settings/SettingStorage.gd")
## ===============================
## Signals
## ===============================
signal binding_changed(action: String)
signal bindings_applied
signal bindings_reverted
## ===============================
## Internal State
## ===============================
var _bindings_committed : Dictionary = {}
var _bindings_working : Dictionary = {}
var _storage := SettingsStorage.new()
const SECTION := "input"
## ===============================
## Lifecycle
## ===============================
func _ready() -> void:
_load()
## ===============================
## Public API (Read)
## ===============================
func get_bindings(action: String) -> Array:
return _bindings_working.get(action, []).duplicate(true)
func get_all_bindings() -> Dictionary:
return _bindings_working.duplicate(true)
## ===============================
## Public API (Write)
## ===============================
func set_bindings(action: String, bindings: Array) -> void:
_bindings_working[action] = bindings
emit_signal("binding_changed", action)
func add_binding(action: String, binding: Dictionary) -> void:
if not _bindings_working.has(action):
_bindings_working[action] = []
_bindings_working[action].append(binding)
emit_signal("binding_changed", action)
func clear_bindings(action: String) -> void:
_bindings_working[action] = []
emit_signal("binding_changed", action)
## ===============================
## Transaction
## ===============================
func apply() -> void:
_bindings_committed = _bindings_working.duplicate(true)
_save_to_storage()
_apply_to_input_map()
emit_signal("bindings_applied")
func revert() -> void:
_bindings_working = _bindings_committed.duplicate(true)
emit_signal("bindings_reverted")
func has_unsaved_changes() -> bool:
return _bindings_working != _bindings_committed
## ===============================
## Internal
## ===============================
func _load() -> void:
_storage.load()
# 1. defaults
_bindings_committed = InputSchema.defaults().duplicate(true)
# 2. override from storage
for action in _bindings_committed.keys():
var saved = _storage.get_value(SECTION, action, null)
if saved != null:
_bindings_committed[action] = saved
_bindings_working = _bindings_committed.duplicate(true)
# 3. apply to engine at startup
_apply_to_input_map()
func _save_to_storage() -> void:
for action in _bindings_committed.keys():
_storage.set_value(SECTION, action, _bindings_committed[action])
_storage.save()
func _apply_to_input_map() -> void:
for action in _bindings_committed.keys():
if not InputMap.has_action(action):
InputMap.add_action(action)
InputMap.action_erase_events(action)
for binding in _bindings_committed[action]:
var event = _binding_to_event(binding)
if event:
InputMap.action_add_event(action, event)
func _binding_to_event(binding: Dictionary) -> InputEvent:
match binding.get("type"):
"key":
var e := InputEventKey.new()
e.keycode = binding.get("keycode", 0)
return e
"mouse":
var e := InputEventMouseButton.new()
e.button_index = binding.get("button", 0)
return e
return null

View File

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

BIN
_asset/ksw/basicTile.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

View File

@ -2,16 +2,16 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://dted7geb331y2"
path="res://.godot/imported/character.png-7c44b4524e7faa111c3b7a3476538724.ctex"
uid="uid://7psxuet3jk1p"
path="res://.godot/imported/basicTile.png-a3220d84fae075d6d47d258dcf4fbeb7.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://_asset/ksw/character.png"
dest_files=["res://.godot/imported/character.png-7c44b4524e7faa111c3b7a3476538724.ctex"]
source_file="res://_asset/ksw/basicTile.png"
dest_files=["res://.godot/imported/basicTile.png-a3220d84fae075d6d47d258dcf4fbeb7.ctex"]
[params]

BIN
_asset/ksw/basicTile01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dd622t4mw5vva"
path="res://.godot/imported/basicTile01.png-ad20f7bda4b3d3d772ec1022f2bd469c.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://_asset/ksw/basicTile01.png"
dest_files=["res://.godot/imported/basicTile01.png-ad20f7bda4b3d3d772ec1022f2bd469c.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/ksw/basicTile02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dufe0liirugbw"
path="res://.godot/imported/basicTile02.png-5b96d40d75bf5493c22086c9606c2acf.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://_asset/ksw/basicTile02.png"
dest_files=["res://.godot/imported/basicTile02.png-5b96d40d75bf5493c22086c9606c2acf.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.

Before

Width:  |  Height:  |  Size: 36 KiB

BIN
_asset/ksw/character01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bryuhk1hqe4hh"
path="res://.godot/imported/character01.png-4ae759f7a7c8b54af8e62bf3e502a8de.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://_asset/ksw/character01.png"
dest_files=["res://.godot/imported/character01.png-4ae759f7a7c8b54af8e62bf3e502a8de.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/ksw/character02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b4k06j8chs2el"
path="res://.godot/imported/character02.png-17a0c468b9f208a10603c306ed77416b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://_asset/ksw/character02.png"
dest_files=["res://.godot/imported/character02.png-17a0c468b9f208a10603c306ed77416b.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.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

BIN
_asset/ksw/spike.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

View File

@ -2,16 +2,16 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://cfjprjiin3dnk"
path="res://.godot/imported/normal.png-2812748d0b3fe0e26bf430a863bce9c7.ctex"
uid="uid://hs7vhn5ecn0v"
path="res://.godot/imported/spike.png-2ddb568331f47f3ae80c8d1db0cc2be4.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://_asset/ksw/normal.png"
dest_files=["res://.godot/imported/normal.png-2812748d0b3fe0e26bf430a863bce9c7.ctex"]
source_file="res://_asset/ksw/spike.png"
dest_files=["res://.godot/imported/spike.png-2ddb568331f47f3ae80c8d1db0cc2be4.ctex"]
[params]

BIN
_asset/ksw/tile/tile.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

@ -2,16 +2,16 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://dkip6i0oyhnlx"
path="res://.godot/imported/damage.png-75c6a469140d15eab0a2b7301c5e8959.ctex"
uid="uid://ntm66vo10u2q"
path="res://.godot/imported/tile.png-289c3a7c75eaae83df78711948565daf.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://_asset/ksw/damage.png"
dest_files=["res://.godot/imported/damage.png-75c6a469140d15eab0a2b7301c5e8959.ctex"]
source_file="res://_asset/ksw/tile/tile.png"
dest_files=["res://.godot/imported/tile.png-289c3a7c75eaae83df78711948565daf.ctex"]
[params]

BIN
_asset/ksw/tile/tile02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cchtbbig85jcm"
path="res://.godot/imported/tile02.png-e8381a8c1a148c3eb8ce3bc8009de863.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://_asset/ksw/tile/tile02.png"
dest_files=["res://.godot/imported/tile02.png-e8381a8c1a148c3eb8ce3bc8009de863.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

@ -1,4 +1,4 @@
[gd_scene load_steps=13 format=3 uid="uid://3vc8ojbiyy5w"]
[gd_scene load_steps=15 format=3 uid="uid://3vc8ojbiyy5w"]
[ext_resource type="Script" uid="uid://crgac4manhoud" path="res://_game/game.gd" id="1_yksyv"]
[ext_resource type="PackedScene" uid="uid://cvqehvdjpoar4" path="res://_player/player_controller.tscn" id="2_x2i0j"]
@ -12,6 +12,8 @@
[ext_resource type="PackedScene" uid="uid://7424nctotch0" path="res://_scene/level1/l1_s6.tscn" id="9_m1t3p"]
[ext_resource type="PackedScene" uid="uid://dr8a26hfqkh12" path="res://_scene/level1/l1_s7.tscn" id="10_5s0xe"]
[ext_resource type="PackedScene" uid="uid://2d457ndb7toe" path="res://_scene/level1/l1_s8.tscn" id="11_ktxjv"]
[ext_resource type="PackedScene" uid="uid://dcoq4q3brnkw6" path="res://_scene/level1/l1_s9.tscn" id="12_enubi"]
[ext_resource type="PackedScene" uid="uid://dsw3o2bhc8bve" path="res://_scene/level1/l1_s10.tscn" id="13_53pmm"]
[node name="Game" type="Node2D" groups=["PLAYER_RESPAWN"]]
script = ExtResource("1_yksyv")
@ -37,3 +39,7 @@ script = ExtResource("1_yksyv")
[node name="L1_S7" parent="." instance=ExtResource("10_5s0xe")]
[node name="L1_S8" parent="." groups=["GRAPABLE"] instance=ExtResource("11_ktxjv")]
[node name="L1_S9" parent="." instance=ExtResource("12_enubi")]
[node name="L1_S10" parent="." instance=ExtResource("13_53pmm")]

15
_game/GameMainNew.tscn Normal file
View File

@ -0,0 +1,15 @@
[gd_scene load_steps=5 format=3 uid="uid://x041oerqe1iu"]
[ext_resource type="Script" uid="uid://crgac4manhoud" path="res://_game/game.gd" id="1_n75l0"]
[ext_resource type="PackedScene" uid="uid://cvqehvdjpoar4" path="res://_player/player_controller.tscn" id="2_uvy3i"]
[ext_resource type="PackedScene" uid="uid://cw6buluknvjj" path="res://_camera/PlateformerCamera.tscn" id="3_j30v4"]
[ext_resource type="PackedScene" uid="uid://d3x8beboy1e6y" path="res://_scene/level1/l1_s1_new.tscn" id="4_w37b4"]
[node name="Game" type="Node2D" groups=["PLAYER_RESPAWN"]]
script = ExtResource("1_n75l0")
[node name="PlayerController" parent="." instance=ExtResource("2_uvy3i")]
[node name="PlateformerCamera" parent="." instance=ExtResource("3_j30v4")]
[node name="L1_S1" parent="." instance=ExtResource("4_w37b4")]

View File

@ -10,5 +10,6 @@ func _ready() -> void:
#$L1_S6.switch_act_by_id(1)
#$L1_S7.switch_act_by_id(1)
#$L1_S8.switch_act_by_id(1)
#$L1_S9.switch_act_by_id(1)
await get_tree().process_frame
get_tree().call_group(&"PLAYER_RESPAWN",&"respawn_avatar")

View File

@ -0,0 +1,46 @@
extends CanvasLayer
@export var target: Node2D
@onready var rect = $ColorRect
var mat: ShaderMaterial
var last_pos: Vector2
func _ready():
mat = rect.material as ShaderMaterial
if target != null:
last_pos = target.global_position
func _process(delta: float) -> void:
if target == null:
return
if mat == null:
return
var vp_size: Vector2 = get_viewport().get_visible_rect().size
# 玩家世界坐标
var world_pos: Vector2 = target.global_position
# ✅ 世界 -> 屏幕像素坐标(包含相机影响)
var screen_pos: Vector2 = get_viewport().get_canvas_transform() * world_pos
# 速度方向(世界空间)
var vel: Vector2 = (world_pos - last_pos) / max(delta, 0.0001)
last_pos = world_pos
var speed: float = vel.length()
var dir: Vector2 = Vector2.RIGHT
if speed > 0.001:
dir = vel / speed
# ✅ 船头前移(拨水发生在玩家前面)
var front_offset_px: Vector2 = dir * 30.0
var uv_front: Vector2 = (screen_pos + front_offset_px) / vp_size
uv_front = uv_front.clamp(Vector2(0, 0), Vector2(1, 1))
mat.set_shader_parameter("obj_uv", uv_front)
mat.set_shader_parameter("obj_dir", dir)
mat.set_shader_parameter("obj_speed", clamp(speed / 600.0, 0.0, 2.0))

View File

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

View File

@ -1,9 +1,8 @@
[gd_scene load_steps=41 format=3 uid="uid://gwhff4qaouxy"]
[gd_scene load_steps=40 format=3 uid="uid://gwhff4qaouxy"]
[ext_resource type="Script" uid="uid://dq1g1qp66chwy" path="res://_player/avatar.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://btm85tbxvjmex" path="res://_camera/camera_shake/CameraShakePreset.gd" id="2_u7cua"]
[ext_resource type="Resource" uid="uid://iv3hfxqm5503" path="res://_camera/camera_shake/CSP_HorizontalOnly.tres" id="3_1a1t3"]
@ -11,6 +10,7 @@
[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="Resource" uid="uid://cs50mkt830f8r" path="res://_camera/camera_shake/CSP_XY.tres" id="5_ciuu3"]
[ext_resource type="Texture2D" uid="uid://bryuhk1hqe4hh" path="res://_asset/ksw/character01.png" id="6_01uoa"]
[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"]
@ -37,18 +37,15 @@
[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="CircleShape2D" id="CircleShape2D_1a1t3"]
radius = 3.0
[sub_resource type="RectangleShape2D" id="RectangleShape2D_01uoa"]
size = Vector2(173, 50)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_qnulu"]
size = Vector2(9, 23)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_ciuu3"]
size = Vector2(203, 245)
[sub_resource type="AtlasTexture" id="AtlasTexture_basl5"]
atlas = ExtResource("2_8nsdm")
region = Rect2(9, 22, 13, 26)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_ogl63"]
size = Vector2(10, 25)
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_ciuu3"]
radius = 134.0
height = 338.0
[node name="Avatar" type="CharacterBody2D" groups=["PLAYER"]]
collision_layer = 2
@ -63,25 +60,25 @@ camera_shake_preset = Dictionary[StringName, ExtResource("2_u7cua")]({
&"y_only_light": ExtResource("4_01uoa")
})
[node name="Sprite2D" type="Sprite2D" parent="."]
position = Vector2(0, 3.9999998)
texture = ExtResource("6_01uoa")
[node name="GroundCompanion" type="Area2D" parent="."]
unique_name_in_owner = true
position = Vector2(0, 11)
position = Vector2(0, 160)
collision_layer = 0
collision_mask = 4
[node name="CollisionShape2D" type="CollisionShape2D" parent="GroundCompanion"]
shape = SubResource("CircleShape2D_1a1t3")
position = Vector2(0, -10)
shape = SubResource("RectangleShape2D_01uoa")
debug_color = Color(0, 0.63529414, 0.40784314, 0.41960785)
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
unique_name_in_owner = true
shape = SubResource("RectangleShape2D_qnulu")
[node name="Sprite2D" type="Sprite2D" parent="."]
visible = false
texture_filter = 1
position = Vector2(0, -2)
texture = SubResource("AtlasTexture_basl5")
position = Vector2(0, 40)
shape = SubResource("RectangleShape2D_ciuu3")
[node name="LimboStateDebugger" type="Node2D" parent="." node_paths=PackedStringArray("state_root")]
script = ExtResource("8_clxy3")
@ -155,6 +152,7 @@ release_distance = 20.0
[node name="Dash" type="LimboState" parent="PlayerHSM/Normal"]
unique_name_in_owner = true
script = ExtResource("12_8nsdm")
dash_time = 1.0
[node name="Dead" type="LimboState" parent="PlayerHSM"]
unique_name_in_owner = true
@ -165,28 +163,47 @@ 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
jump_force = 460.0
climb_max_speed_upward = 450.0
climb_max_speed_downward = 800.0
climb_acceleration = 3000.0
climb_hop_velocity_x = 1400.0
climb_hop_velocity_y = 2600.0
climb_jump_velocity_x = 1800.0
climb_jump_velocity_y = 3300.0
custom_move_force = 10000.0
custom_move_max_speed = 4500.0
custom_move_stop_distance = 40.0
jump_force = 5800.0
jump_hold_maxium_time = 0.125
jump_horizontal_Boost = 160.0
jump_countinus_horizontal_Boost = 500.0
jump_horizontal_Boost = 5600.0
jump_countinus_horizontal_Boost = 4000.0
jump_horizontal_Boost_last_time = 0.12
light_gravity_threshold = 135.0
max_jump_horizontal_boost_speed = 3600.0
light_gravity_threshold = 1200.0
light_gravity_mult = 0.6
wall_jump_base_force_x = 260.0
wall_jump_base_force_y = 220.0
fall_maxium_speed = 430.0
air_control_mult = 0.35
run_accel = 1300.0
run_reduce = 2400.0
move_speed_max = 202.0
wall_slide_fall_maxium_speed = 5000.0
wall_jump_base_force_x = 2800.0
wall_jump_base_force_y = 1600.0
fall_maxium_speed = 8000.0
air_control_mult = 0.55
run_accel = 15000.0
run_reduce = 20000.0
move_speed_max = 2650.0
[node name="WallDetector" parent="LocomotionComponent" instance=ExtResource("20_air0b")]
unique_name_in_owner = true
[node name="UpRayCast2D" parent="LocomotionComponent/WallDetector" index="0"]
position = Vector2(0, -141)
target_position = Vector2(155, 0)
[node name="MidRayCast2D" parent="LocomotionComponent/WallDetector" index="1"]
position = Vector2(0, 3)
position = Vector2(0, 42)
target_position = Vector2(154, 0)
[node name="DownRayCast2D" parent="LocomotionComponent/WallDetector" index="2"]
position = Vector2(0, 151)
target_position = Vector2(155, 0)
[node name="SpawnHookComponet" type="Node" parent="."]
script = ExtResource("21_p14kj")
@ -211,8 +228,7 @@ collision_layer = 0
collision_mask = 8
[node name="CollisionShape2D" type="CollisionShape2D" parent="HitBox"]
position = Vector2(0, -2.5)
shape = SubResource("RectangleShape2D_ogl63")
shape = SubResource("CapsuleShape2D_ciuu3")
debug_color = Color(0.95815283, 0, 0.5313341, 0.41960785)
[node name="RemotePositionSetting" type="Node2D" parent="."]

View File

@ -67,11 +67,11 @@ func _draw() -> void:
var a_x: float = clampf(abs(velocity.x),1,2000) * .3 * sign(locomotion_comp._current_acceleration.x)
var a_y: float = clampf(abs(velocity.x),1,2000) * .3 * sign(locomotion_comp._current_acceleration.y)
draw_line(Vector2.ZERO,Vector2(x, 0),Color.RED,4)
draw_line(Vector2.ZERO,Vector2(0, y),Color.GREEN,4)
draw_line(Vector2.ZERO,Vector2(x, 0),Color.RED,40)
draw_line(Vector2.ZERO,Vector2(0, y),Color.GREEN,40)
draw_line(Vector2.ZERO,Vector2(a_x, 0),Color.YELLOW,2)
draw_line(Vector2.ZERO,Vector2(0, a_y),Color.PURPLE,2)
draw_line(Vector2.ZERO,Vector2(a_x, 0),Color.YELLOW,20)
draw_line(Vector2.ZERO,Vector2(0, a_y),Color.PURPLE,20)
func _process(delta: float) -> void:
queue_redraw()

View File

@ -27,6 +27,7 @@ func _setup() -> void:
func _init_handler() -> void:
self.add_event_handler(&"trigger_dash",_handler_trigger_dash) ##处理Dash输入
self.add_event_handler(&"trigger_external_dash",_handler_trigger_external_dash) ##处理外部触发的Dash
self.add_event_handler(&"trigger_climb",_handler_trigger_climb) ##处理瞬时的climb
self.add_event_handler(&"trigger_grap_hook",_handler_grap_hook) ##处理grap hook 的輸入
@ -72,6 +73,14 @@ func _handler_trigger_dash() -> bool:
self.dispatch(&"want_to_dash")
return true
##处理外部触发的Dash如道具触发
func _handler_trigger_external_dash() -> bool:
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

View File

@ -2,7 +2,7 @@
[ext_resource type="Script" uid="uid://c3lbocrolvqyg" path="res://_props/_prefabs/plateform/movable_plateform.gd" id="1_w8q55"]
[node name="MovablePlateform" type="AnimatableBody2D" groups=["GRAPABLE"]]
[node name="MovablePlateform" type="AnimatableBody2D" groups=["GRAPABLE", "ROCK_BREAK"]]
collision_layer = 4
collision_mask = 0
script = ExtResource("1_w8q55")

View File

@ -8,3 +8,4 @@ editor_description = "此类在检测到玩家时会发出signal可以与其
collision_layer = 0
collision_mask = 2
script = ExtResource("1_qrafk")
debug_print = true

View File

@ -1,16 +0,0 @@
[gd_scene load_steps=4 format=3 uid="uid://c3mievyfhx6ni"]
[ext_resource type="PackedScene" uid="uid://d20u8tfktepxg" path="res://_props/_prefabs/collection/collection_prefab.tscn" id="1_r0qyb"]
[ext_resource type="Texture2D" uid="uid://c673bap4b12fx" path="res://icon.svg" id="2_igeyo"]
[sub_resource type="CircleShape2D" id="CircleShape2D_r0qyb"]
radius = 23.0
[node name="Coin" instance=ExtResource("1_r0qyb")]
[node name="CollisionShape2D" type="CollisionShape2D" parent="." index="0"]
shape = SubResource("CircleShape2D_r0qyb")
[node name="Sprite2D" type="Sprite2D" parent="." index="1"]
scale = Vector2(0.33, 0.33)
texture = ExtResource("2_igeyo")

View File

@ -0,0 +1,70 @@
extends CharacterBody2D
@onready var player_collectable_volumn: PlayerTriggerVolumn = %PlayerCollectableVolumn
@onready var hook_attract_volumn: Area2D = %HookAttractVolumn
enum State {
IDLE,
PULLED_BY_HOOK,
COLLECTED
}
var _current_state: State = State.IDLE
## 拉回速度
@export var pull_speed: float = 800.0
## 拉回目标(玩家)
var _pull_target: Node2D
func _ready() -> void:
player_collectable_volumn.player_entered.connect(_on_player_collected)
##状态管理函数
func change_state(in_state: State) -> void:
if in_state == _current_state:
return
## 退出State的逻辑
match _current_state:
State.IDLE:
pass
State.PULLED_BY_HOOK:
pass
State.COLLECTED:
pass
_current_state = in_state
## 进入State的逻辑
match in_state:
State.IDLE:
pass
State.PULLED_BY_HOOK:
pass
State.COLLECTED:
queue_free()
## 钩爪击中时调用hit_pos 是击中点hook 是钩爪实例)
func on_hook_hit(hit_pos: Vector2, hook: Hook) -> void:
# 通过钩爪组件获取发射者(玩家)
_pull_target = hook._binded_hook_comp.owner as Node2D
if _pull_target:
change_state(State.PULLED_BY_HOOK)
func _physics_process(delta: float) -> void:
if _current_state == State.PULLED_BY_HOOK and _pull_target:
var direction := (_pull_target.global_position - global_position).normalized()
velocity = direction * pull_speed
move_and_slide()
func get_attraction_force(pos: Vector2) -> Vector2:
# 返回 (direction, strength) 格式
var dir := (global_position - pos).normalized()
var strength := 1500 # 调整这个值控制吸引力转向速度
return dir * strength
##如果玩家进入收集区域,则切换为已收集状态。
func _on_player_collected(body:CharacterBody2D) -> void:
if body is Player:
body.hsm.dispatch(&"trigger_external_dash")
change_state(State.COLLECTED)

View File

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

View File

@ -0,0 +1,45 @@
[gd_scene load_steps=7 format=3 uid="uid://degt1t2y08udg"]
[ext_resource type="Script" uid="uid://c8a7gs0h2h6vn" path="res://_props/dark_material_ball/dark_material_ball.gd" id="1_8vsnl"]
[ext_resource type="Texture2D" uid="uid://c673bap4b12fx" path="res://icon.svg" id="2_ts6gp"]
[ext_resource type="PackedScene" uid="uid://bonrls3iuhdqb" path="res://_props/_prefabs/player/player_trigger_volumn.tscn" id="3_rtv51"]
[sub_resource type="CircleShape2D" id="CircleShape2D_62vs1"]
radius = 7.0
[sub_resource type="CircleShape2D" id="CircleShape2D_j8xbm"]
radius = 10.049875
[sub_resource type="CircleShape2D" id="CircleShape2D_8vsnl"]
radius = 34.0147
[node name="DarkMaterialBall" type="CharacterBody2D" groups=["GRAPABLE"]]
collision_layer = 16
collision_mask = 2
script = ExtResource("1_8vsnl")
pull_speed = null
[node name="Sprite2D" type="Sprite2D" parent="."]
unique_name_in_owner = true
scale = Vector2(0.135, 0.135)
texture = ExtResource("2_ts6gp")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("CircleShape2D_62vs1")
[node name="PlayerCollectableVolumn" parent="." instance=ExtResource("3_rtv51")]
unique_name_in_owner = true
debug_print = false
[node name="CollisionShape2D" type="CollisionShape2D" parent="PlayerCollectableVolumn"]
shape = SubResource("CircleShape2D_j8xbm")
debug_color = Color(0.19215687, 0.6431373, 0, 0)
[node name="HookAttractVolumn" type="Area2D" parent="."]
unique_name_in_owner = true
collision_layer = 32
collision_mask = 0
[node name="CollisionShape2D" type="CollisionShape2D" parent="HookAttractVolumn"]
shape = SubResource("CircleShape2D_8vsnl")
debug_color = Color(1, 0, 0.14509805, 0)

View File

@ -0,0 +1,20 @@
extends StaticBody2D
@export var break_groups: Array[String] = ["ROCK_BREAK"]
func _ready():
$Area2D.body_entered.connect(_on_body_entered)
func _on_body_entered(body: Node):
if _can_be_broken_by(body):
break_self()
func _can_be_broken_by(node: Node) -> bool:
for group in break_groups:
if node.is_in_group(group):
return true
return false
func break_self():
# 可以在这插入动画、粒子、音效
queue_free()

View File

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

View File

@ -0,0 +1,33 @@
[gd_scene load_steps=5 format=3 uid="uid://iv8w7iisdqm0"]
[ext_resource type="Texture2D" uid="uid://c673bap4b12fx" path="res://icon.svg" id="1_i8uj5"]
[ext_resource type="Script" uid="uid://cega12j8xp7lx" path="res://_props/fragile_rock/fragile_rock.gd" id="1_tme8j"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_i8uj5"]
size = Vector2(48, 48)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_tme8j"]
size = Vector2(50, 50)
[node name="FragileRock" type="StaticBody2D" groups=["GRAPABLE"]]
collision_layer = 4
collision_mask = 6
script = ExtResource("1_tme8j")
break_groups = null
[node name="Sprite2D" type="Sprite2D" parent="."]
position = Vector2(4.7683716e-07, -4.7683716e-07)
scale = Vector2(0.37499997, 0.37499997)
texture = ExtResource("1_i8uj5")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("RectangleShape2D_i8uj5")
debug_color = Color(1, 0.24705882, 0.40784314, 0.41960785)
[node name="Area2D" type="Area2D" parent="."]
collision_layer = 0
collision_mask = 4
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
shape = SubResource("RectangleShape2D_tme8j")
debug_color = Color(0.20694017, 0.5377888, 0.9240256, 0.41960785)

View File

@ -1,6 +1,49 @@
[gd_scene load_steps=2 format=3 uid="uid://cpbaoqfc2kq80"]
[gd_scene load_steps=8 format=3 uid="uid://cpbaoqfc2kq80"]
[ext_resource type="Script" uid="uid://decr4caey82gc" path="res://_props/move_plateform/path_drive_move_plateform/path_drive_move_plateform.gd" id="1_ouylf"]
[ext_resource type="PackedScene" uid="uid://csdxpv8gefpec" path="res://_props/_prefabs/plateform/movable_plateform.tscn" id="2_yo6tx"]
[ext_resource type="Texture2D" uid="uid://c673bap4b12fx" path="res://icon.svg" id="3_l54kj"]
[ext_resource type="PackedScene" uid="uid://bonrls3iuhdqb" path="res://_props/_prefabs/player/player_trigger_volumn.tscn" id="4_ylwpt"]
[node name="PathDriveMovePlateform" type="Node2D"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_82l4y"]
size = Vector2(120, 120)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_k2ua5"]
size = Vector2(130, 130)
[sub_resource type="Curve2D" id="Curve2D_yo6tx"]
_data = {
"points": PackedVector2Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 0)
}
point_count = 2
[node name="PathDriveMovePlateform" type="Node2D" node_paths=PackedStringArray("path2d", "plateform", "player_trigger")]
script = ExtResource("1_ouylf")
path2d = NodePath("Path2D")
plateform = NodePath("MovablePlateform")
player_trigger = NodePath("MovablePlateform/PlayerTriggerVolumn")
move_speed = 1200.0
returning_speed = 300.0
acceleration = 1600.0
[node name="MovablePlateform" parent="." node_paths=PackedStringArray("shaking_target") instance=ExtResource("2_yo6tx")]
shaking_target = NodePath("Sprite2D")
shake_strength = 1.0
shake_duration = 1.0
shake_hz = 48.0
[node name="Sprite2D" type="Sprite2D" parent="MovablePlateform"]
texture = ExtResource("3_l54kj")
[node name="CollisionShape2D" type="CollisionShape2D" parent="MovablePlateform"]
shape = SubResource("RectangleShape2D_82l4y")
debug_color = Color(1.7409995, 0, 0.33381775, 0.41960785)
[node name="PlayerTriggerVolumn" parent="MovablePlateform" instance=ExtResource("4_ylwpt")]
debug_print = true
[node name="CollisionShape2D" type="CollisionShape2D" parent="MovablePlateform/PlayerTriggerVolumn"]
shape = SubResource("RectangleShape2D_k2ua5")
[node name="Path2D" type="Path2D" parent="."]
curve = SubResource("Curve2D_yo6tx")

View File

@ -51,6 +51,23 @@ func change_state(state:State) -> void:
pass
## 当玩家钩爪击中平台底部时,直接激活平台(跳过 READY 状态)
func on_hook_hit(hit_global_pos: Vector2) -> void:
# 检测击中点是否在平台底部(击中点的 Y 大于等于平台的顶部)
var platform_top := plateform.global_position.y
# 考虑到碰撞体可能有偏移,稍微放宽条件
var is_bottom_hit := hit_global_pos.y >= platform_top - 10
if not is_bottom_hit:
return
# 只有在 IDLE 或 READY 状态才能被激活
if _current_state != State.IDLE and _current_state != State.READY:
return
# 直接进入 MOVING 状态
start_move()
## 当平台被触发时,切换状态
func _on_trigger() -> void:
change_state(State.READY)
@ -137,3 +154,11 @@ func start_move() -> void:
_path_follow.progress = 0.0
_current_speed = 0.0
change_state(State.MOVING)
func scene_reset() -> void:
if not path2d or not path2d.curve or not plateform:
return
var init_pos:= path2d.curve.get_point_position(0)
plateform.position = init_pos
change_state(State.IDLE)

View File

@ -6,10 +6,10 @@
[ext_resource type="PackedScene" uid="uid://bonrls3iuhdqb" path="res://_props/_prefabs/player/player_trigger_volumn.tscn" id="4_txegh"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_vv0hj"]
size = Vector2(52, 51)
size = Vector2(52, 52)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_mvp6g"]
size = Vector2(64, 56)
size = Vector2(54, 52.5)
[node name="TriggerFallRock_Climb" type="Node2D"]
script = ExtResource("1_n6tyk")
@ -17,11 +17,11 @@ script = ExtResource("1_n6tyk")
[node name="rock" parent="." instance=ExtResource("2_ibofv")]
position = Vector2(0, -74)
falling_gravity = 600.0
max_fall_speed = 1000.0
max_fall_speed = 1500.0
[node name="Sprite2D" type="Sprite2D" parent="rock"]
position = Vector2(0, 73.99999)
scale = Vector2(0.4, 0.4)
scale = Vector2(0.405, 0.405)
texture = ExtResource("3_mb81t")
[node name="CollisionShape2D" type="CollisionShape2D" parent="rock"]
@ -33,7 +33,7 @@ debug_color = Color(0.99629647, 0, 0.19810504, 0.41960785)
debug_print = true
[node name="CollisionShape2D" type="CollisionShape2D" parent="PlayerTriggerVolumn"]
position = Vector2(0, -4)
position = Vector2(0, -0.75)
shape = SubResource("RectangleShape2D_mvp6g")
[node name="Timer" type="Timer" parent="."]

View File

@ -6,7 +6,7 @@
[ext_resource type="PackedScene" uid="uid://bonrls3iuhdqb" path="res://_props/_prefabs/player/player_trigger_volumn.tscn" id="4_s77mb"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_vv0hj"]
size = Vector2(52, 51)
size = Vector2(52, 52)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_mvp6g"]
size = Vector2(52, 108.5)
@ -20,11 +20,10 @@ falling_gravity = 600.0
max_fall_speed = 1000.0
[node name="Sprite2D" type="Sprite2D" parent="rock"]
scale = Vector2(0.4, 0.4)
scale = Vector2(0.405, 0.405)
texture = ExtResource("3_f8vfu")
[node name="CollisionShape2D" type="CollisionShape2D" parent="rock"]
position = Vector2(0, -0.5)
shape = SubResource("RectangleShape2D_vv0hj")
debug_color = Color(0.99629647, 0, 0.19810504, 0.41960785)

View File

@ -0,0 +1,11 @@
extends Node
@export var reset_targets : Array[NodePath]
const RESET_INTERFACE_NAME := "scene_reset"
func reset_all() -> void:
for i in reset_targets:
var t := get_node_or_null(i)
if t and t.has_method("scene_reset"):
t.scene_reset()

View File

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

View File

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://dwrkfo2vhummq"]
[ext_resource type="Script" uid="uid://c8qho5tujjdtm" path="res://_scene/feature/Feature_Reset.gd" id="1_oyv48"]
[node name="[Featrue]reset" type="Node"]
script = ExtResource("1_oyv48")

View File

@ -0,0 +1,7 @@
[gd_resource type="Resource" load_steps=2 format=3 uid="uid://c7gm32jjs8wop"]
[ext_resource type="Script" uid="uid://dhs40v68rpfxr" path="res://_scene/guard/Guard_ActIDChangedCheck.gd" id="1_ae5sw"]
[resource]
script = ExtResource("1_ae5sw")
to_id = 1

View File

@ -0,0 +1,26 @@
'''
ActIDChanged绑定ActManager返回的ActChanged Signal
'''
class_name SG_ActIDChangedCheck extends SceneGuard
##如果为-1则不检查from_id只检查to id
@export var from_id: int = -1
##如果为-1不检查如果不为-1则如果act manager的act changed的to act是此id此guard通过。
@export var to_id: int = -1
func check(signal_args: Array, manager: SceneManager) -> bool:
if to_id < 0:
return true
var has_from : bool = false
if from_id >= 0:
has_from = true
if has_from:
if signal_args[0] == from_id and signal_args[1] == to_id:
return true
else:
if signal_args[1] == to_id:
return true
return false

View File

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

View File

@ -0,0 +1,21 @@
'''
scene的idid和目标id匹配
'''
class_name SG_CurrentIDCheck extends SceneGuard
##在此列表里的id如果当被监听的signal触发时我们当前scene的id属于此id则会通过check否则不通过
@export var check_pass_ids: Array[int] = [-1]
func check(signal_args: Array, manager: SceneManager) -> bool:
if not manager:
return false
var am := manager._act_manager
if not am:
return false
for id in check_pass_ids:
if am._current_act_id == id and id >= 0:
return true
return false

View File

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

File diff suppressed because one or more lines are too long

243
_scene/level1/l1_s10.tscn Normal file
View File

@ -0,0 +1,243 @@
[gd_scene load_steps=43 format=4 uid="uid://dsw3o2bhc8bve"]
[ext_resource type="Script" uid="uid://5e157vdk6175" path="res://addons/reedscene/scene/ReedScene.gd" id="1_7cppx"]
[ext_resource type="Script" uid="uid://bh066o84byplh" path="res://addons/reedscene/scene/ReedSceneID.gd" id="2_4mxpo"]
[ext_resource type="Script" uid="uid://dn0ksjoswquf5" path="res://addons/reedscene/scene/SceneManager.gd" id="3_vag2i"]
[ext_resource type="Script" uid="uid://ons77en82uls" path="res://addons/reedscene/scene/scene_trigger/base/SceneTrigger.gd" id="4_uauy5"]
[ext_resource type="Resource" uid="uid://bym4pb0ellj7b" path="res://_scene/scene_trigger_resource/default_switch.tres" id="5_1sk4g"]
[ext_resource type="Script" uid="uid://dsgl7lbyjsiif" path="res://addons/reedscene/act/ActManager.gd" id="6_ajdop"]
[ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="7_vbsqb"]
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="8_p2ywg"]
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="9_1hywn"]
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_camera/CameraAnchor.tscn" id="10_1pax7"]
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="11_q0s1n"]
[ext_resource type="Script" uid="uid://di41kt2tj34c2" path="res://addons/reedscene/prop/StateManager.gd" id="12_crx1v"]
[ext_resource type="Script" uid="uid://7lml6d1t5xtq" path="res://addons/reedscene/prop/PropState.gd" id="13_hgqvd"]
[ext_resource type="Script" uid="uid://cdvgq0xqdbagk" path="res://addons/reedscene/prop/Effect/ReedPropEffect.gd" id="14_as4ql"]
[ext_resource type="Resource" uid="uid://bjjxh7g7iosla" path="res://_props/_camera/camera_anchor_disable.tres" id="15_o7vl7"]
[ext_resource type="Resource" uid="uid://458r8rf7x02p" path="res://_props/_camera/camera_anchor_enable.tres" id="16_utqfr"]
[ext_resource type="PackedScene" uid="uid://bonrls3iuhdqb" path="res://_props/_prefabs/player/player_trigger_volumn.tscn" id="17_5ludb"]
[ext_resource type="Resource" uid="uid://dd4df6yjkeifa" path="res://_props/_prefabs/player/effect/player_trigger_volumn_disable.tres" id="18_b8hra"]
[ext_resource type="Resource" uid="uid://b6iglvt36pm55" path="res://_props/_prefabs/player/effect/player_trigger_volumn_enable.tres" id="19_7kvrg"]
[ext_resource type="PackedScene" uid="uid://cxgcmdxlbwwjh" path="res://_props/_prefabs/player/player_respawn_point.tscn" id="20_a7psa"]
[ext_resource type="Script" uid="uid://bf1qlvdbf8qdp" path="res://addons/reedscene/prop/Effect/EAT_CallFunc.gd" id="21_5jjhm"]
[ext_resource type="Script" uid="uid://8cqs3i8sr8b1" path="res://addons/reedscene/prop/Effect/ETT_Owner.gd" id="22_rem5u"]
[ext_resource type="TileSet" uid="uid://doepkfp83k0lb" path="res://_tileset/test.tres" id="23_6lqui"]
[ext_resource type="PackedScene" uid="uid://bju8jr1w4d60m" path="res://_props/spring/spring.tscn" id="24_0k4x8"]
[ext_resource type="PackedScene" uid="uid://cpbaoqfc2kq80" path="res://_props/move_plateform/path_drive_move_plateform/PathDriveMovePlateform.tscn" id="25_ldp4y"]
[ext_resource type="PackedScene" uid="uid://b5nx4dntm0gyn" path="res://_props/door_manager/event_trigger_door.tscn" id="28_4mxpo"]
[sub_resource type="Resource" id="Resource_6bhoi"]
script = ExtResource("8_p2ywg")
metadata/_custom_type_script = "uid://baqgorvlumyju"
[sub_resource type="Resource" id="Resource_0dl6r"]
script = ExtResource("8_p2ywg")
state_id = 1
metadata/_custom_type_script = "uid://baqgorvlumyju"
[sub_resource type="Resource" id="Resource_pfh14"]
script = ExtResource("8_p2ywg")
metadata/_custom_type_script = "uid://baqgorvlumyju"
[sub_resource type="Resource" id="Resource_sv1n5"]
script = ExtResource("7_vbsqb")
prop_state_map = Dictionary[int, ExtResource("8_p2ywg")]({
0: SubResource("Resource_6bhoi"),
1: SubResource("Resource_0dl6r"),
2: SubResource("Resource_pfh14")
})
metadata/_custom_type_script = "uid://fxpk2ot6otfh"
[sub_resource type="Resource" id="Resource_rvnvs"]
script = ExtResource("8_p2ywg")
state_id = 1
metadata/_custom_type_script = "uid://baqgorvlumyju"
[sub_resource type="Resource" id="Resource_3jyxx"]
script = ExtResource("8_p2ywg")
metadata/_custom_type_script = "uid://baqgorvlumyju"
[sub_resource type="Resource" id="Resource_dalgl"]
script = ExtResource("8_p2ywg")
state_id = 1
metadata/_custom_type_script = "uid://baqgorvlumyju"
[sub_resource type="Resource" id="Resource_fwmv2"]
script = ExtResource("7_vbsqb")
prop_state_map = Dictionary[int, ExtResource("8_p2ywg")]({
0: SubResource("Resource_rvnvs"),
1: SubResource("Resource_3jyxx"),
2: SubResource("Resource_dalgl")
})
metadata/_custom_type_script = "uid://fxpk2ot6otfh"
[sub_resource type="RectangleShape2D" id="RectangleShape2D_nvw5u"]
size = Vector2(608, 352)
[sub_resource type="Resource" id="Resource_ctwrc"]
script = ExtResource("21_5jjhm")
func_name = &"pop_respawner"
metadata/_custom_type_script = "uid://bf1qlvdbf8qdp"
[sub_resource type="Resource" id="Resource_0u6xi"]
script = ExtResource("22_rem5u")
[sub_resource type="Resource" id="Resource_r0e2c"]
script = ExtResource("14_as4ql")
effect_target_type = SubResource("Resource_0u6xi")
effect_apply_type = SubResource("Resource_ctwrc")
metadata/_custom_type_script = "uid://cdvgq0xqdbagk"
[sub_resource type="Resource" id="Resource_hatj6"]
script = ExtResource("21_5jjhm")
func_name = &"push_respawner"
metadata/_custom_type_script = "uid://bf1qlvdbf8qdp"
[sub_resource type="Resource" id="Resource_o2v7x"]
script = ExtResource("22_rem5u")
[sub_resource type="Resource" id="Resource_ubvm0"]
script = ExtResource("14_as4ql")
effect_target_type = SubResource("Resource_o2v7x")
effect_apply_type = SubResource("Resource_hatj6")
metadata/_custom_type_script = "uid://cdvgq0xqdbagk"
[sub_resource type="Curve2D" id="Curve2D_glu07"]
_data = {
"points": PackedVector2Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 400, 0)
}
point_count = 2
[node name="L1_S10" type="Node2D"]
script = ExtResource("1_7cppx")
metadata/_custom_type_script = "uid://5e157vdk6175"
[node name="[Invalid!]" type="Node" parent="."]
script = ExtResource("2_4mxpo")
[node name="SceneManager" type="Node" parent="."]
script = ExtResource("3_vag2i")
quick_trigger = Array[ExtResource("4_uauy5")]([ExtResource("5_1sk4g")])
[node name="ActManager" type="Node" parent="."]
script = ExtResource("6_ajdop")
prop_state_map = Dictionary[int, ExtResource("7_vbsqb")]({
0: SubResource("Resource_sv1n5"),
1: SubResource("Resource_fwmv2")
})
init_act_id = 0
[node name="Props" type="Node2D" parent="."]
script = ExtResource("9_1hywn")
[node name="CameraAnchor" parent="Props" instance=ExtResource("10_1pax7")]
position = Vector2(1375, -1657)
limit_top = -185
limit_bottom = 185
limit_left = -320
limit_right = 290
[node name="[Prop_0000]" type="Node" parent="Props/CameraAnchor"]
script = ExtResource("11_q0s1n")
prop_id = 0
[node name="States" type="Node" parent="Props/CameraAnchor/[Prop_0000]"]
script = ExtResource("12_crx1v")
[node name="[ID_0] Disable" type="Node" parent="Props/CameraAnchor/[Prop_0000]/States"]
script = ExtResource("13_hgqvd")
state_id = 0
effects = Array[ExtResource("14_as4ql")]([ExtResource("15_o7vl7")])
[node name="[ID_1] Enable" type="Node" parent="Props/CameraAnchor/[Prop_0000]/States"]
script = ExtResource("13_hgqvd")
state_id = 1
effects = Array[ExtResource("14_as4ql")]([ExtResource("16_utqfr")])
[node name="PlayerTriggerVolumn" parent="Props" instance=ExtResource("17_5ludb")]
visible = false
position = Vector2(504, -1608)
[node name="CollisionShape2D" type="CollisionShape2D" parent="Props/PlayerTriggerVolumn"]
visible = false
position = Vector2(857, -56)
shape = SubResource("RectangleShape2D_nvw5u")
debug_color = Color(0.8497597, 0.2655047, 0.64659345, 0.41960785)
[node name="[Prop_0001]" type="Node" parent="Props/PlayerTriggerVolumn"]
script = ExtResource("11_q0s1n")
prop_id = 1
[node name="States" type="Node" parent="Props/PlayerTriggerVolumn/[Prop_0001]"]
script = ExtResource("12_crx1v")
[node name="[ID_0] Disable" type="Node" parent="Props/PlayerTriggerVolumn/[Prop_0001]/States"]
script = ExtResource("13_hgqvd")
state_id = 0
effects = Array[ExtResource("14_as4ql")]([ExtResource("18_b8hra")])
[node name="[ID_1] Enable" type="Node" parent="Props/PlayerTriggerVolumn/[Prop_0001]/States"]
script = ExtResource("13_hgqvd")
state_id = 1
effects = Array[ExtResource("14_as4ql")]([ExtResource("19_7kvrg")])
[node name="PlayerRespawnPoint" parent="Props" instance=ExtResource("20_a7psa")]
position = Vector2(1107, -1504)
[node name="[Prop_0002]" type="Node" parent="Props/PlayerRespawnPoint"]
script = ExtResource("11_q0s1n")
prop_id = 2
[node name="States" type="Node" parent="Props/PlayerRespawnPoint/[Prop_0002]"]
script = ExtResource("12_crx1v")
[node name="[ID_0] Disable" type="Node" parent="Props/PlayerRespawnPoint/[Prop_0002]/States"]
script = ExtResource("13_hgqvd")
state_id = 0
effects = Array[ExtResource("14_as4ql")]([SubResource("Resource_r0e2c")])
[node name="[ID_1] Enable" type="Node" parent="Props/PlayerRespawnPoint/[Prop_0002]/States"]
script = ExtResource("13_hgqvd")
state_id = 1
effects = Array[ExtResource("14_as4ql")]([SubResource("Resource_ubvm0")])
[node name="TileMapLayer" type="TileMapLayer" parent="." groups=["GRAPABLE"]]
tile_map_data = PackedByteArray("AABCAJ3/AAAAAAAAAABCAJz/AAAAAAAAAABCAJv/AAAAAAAAAABCAJr/AAAAAAAAAABCAJn/AAAAAAAAAABCAJj/AAAAAAAAAABCAJf/AAAAAAAAAABCAJb/AAAAAAAAAABCAJD/AAAAAAAAAABCAI//AAAAAAAAAABCAI7/AAAAAAAAAABCAI3/AAAAAAAAAABCAIz/AAAAAAAAAABCAIv/AAAAAAAAAABCAIr/AAAAAAAAAABCAIn/AAAAAAAAAABCAIj/AAAAAAAAAABCAIf/AAAAAAAAAABCAIb/AAAAAAAAAABCAIH/AAAAAAAAAABCAID/AAAAAAAAAABCAH//AAAAAAAAAABCAH7/AAAAAAAAAABCAH3/AAAAAAAAAABCAHz/AAAAAAAAAABCAHv/AAAAAAAAAABCAHr/AAAAAAAAAABCAHn/AAAAAAAAAABCAKP/AAAAAAAAAABnAJL/AAAAAAAAAABnAJH/AAAAAAAAAABmAJD/AAAAAAAAAABmAI//AAAAAAAAAABmAI7/AAAAAAAAAABmAI3/AAAAAAAAAABmAIz/AAAAAAAAAABmAIv/AAAAAAAAAABnAJD/AAAAAAAAAABnAI//AAAAAAAAAABnAI7/AAAAAAAAAABnAI3/AAAAAAAAAABnAIz/AAAAAAAAAABnAIv/AAAAAAAAAABnAIr/AAAAAAAAAABnAIT/AAAAAAAAAABnAIP/AAAAAAAAAABnAIL/AAAAAAAAAABnAIH/AAAAAAAAAABnAID/AAAAAAAAAABnAH//AAAAAAAAAABnAH7/AAAAAAAAAABnAH3/AAAAAAAAAABnAHz/AAAAAAAAAABnAHv/AAAAAAAAAABnAHr/AAAAAAAAAABnAHn/AAAAAAAAAABnAJP/AAAAAAAAAABDAKP/AAAAAAAAAABEAKP/AAAAAAAAAABFAKP/AAAAAAAAAABGAKP/AAAAAAAAAABHAKP/AAAAAAAAAABIAKP/AAAAAAAAAABJAKP/AAAAAAAAAABKAKP/AAAAAAAAAABLAKP/AAAAAAAAAABMAKP/AAAAAAAAAABNAKP/AAAAAAAAAABOAKP/AAAAAAAAAABPAKP/AAAAAAAAAABQAKP/AAAAAAAAAABRAKP/AAAAAAAAAABSAKP/AAAAAAAAAABTAKP/AAAAAAAAAABUAKP/AAAAAAAAAABVAKL/AAAAAAAAAABWAKL/AAAAAAAAAABXAKL/AAAAAAAAAABYAKL/AAAAAAAAAABZAKL/AAAAAAAAAABaAKL/AAAAAAAAAABbAKL/AAAAAAAAAABbAKP/AAAAAAAAAABcAKP/AAAAAAAAAABdAKP/AAAAAAAAAABeAKP/AAAAAAAAAABfAKP/AAAAAAAAAABVAKP/AAAAAAAAAABWAKP/AAAAAAAAAABXAKP/AAAAAAAAAABYAKP/AAAAAAAAAABZAKP/AAAAAAAAAABaAKP/AAAAAAAAAABgAKP/AAAAAAAAAABhAKP/AAAAAAAAAABiAKP/AAAAAAAAAABjAKP/AAAAAAAAAABkAKP/AAAAAAAAAABlAKP/AAAAAAAAAABmAKP/AAAAAAAAAABnAKP/AAAAAAAAAABCAHj/AAAAAAAAAABCAHf/AAAAAAAAAABCAHb/AAAAAAAAAABnAHb/AAAAAAAAAABCAF//AAAAAAAAAABCAGD/AAAAAAAAAABCAGH/AAAAAAAAAABCAGL/AAAAAAAAAABCAGj/AAAAAAAAAABCAGn/AAAAAAAAAABCAGr/AAAAAAAAAABCAGv/AAAAAAAAAABCAGz/AAAAAAAAAABCAG3/AAAAAAAAAABCAG7/AAAAAAAAAABCAG//AAAAAAAAAABCAHX/AAAAAAAAAABmAF//AAAAAAAAAABmAGD/AAAAAAAAAABmAGH/AAAAAAAAAABmAGL/AAAAAAAAAABmAGr/AAAAAAAAAABmAGv/AAAAAAAAAABmAGz/AAAAAAAAAABmAG3/AAAAAAAAAABmAG7/AAAAAAAAAABmAG//AAAAAAAAAABmAHD/AAAAAAAAAABmAHH/AAAAAAAAAABmAHL/AAAAAAAAAABnAF//AAAAAAAAAABnAGD/AAAAAAAAAABnAGH/AAAAAAAAAABnAGL/AAAAAAAAAABnAGP/AAAAAAAAAABnAGT/AAAAAAAAAABnAGX/AAAAAAAAAABnAGr/AAAAAAAAAABnAGv/AAAAAAAAAABnAGz/AAAAAAAAAABnAG3/AAAAAAAAAABnAG7/AAAAAAAAAABnAG//AAAAAAAAAABnAHD/AAAAAAAAAABnAHH/AAAAAAAAAABnAHL/AAAAAAAAAABnAHP/AAAAAAAAAABnAHX/AAAAAAAAAABDAF//AAAAAAAAAABEAF//AAAAAAAAAABFAF//AAAAAAAAAABGAF//AAAAAAAAAABHAF//AAAAAAAAAABIAF//AAAAAAAAAABJAF//AAAAAAAAAABKAF//AAAAAAAAAABLAF//AAAAAAAAAABMAF//AAAAAAAAAABNAF//AAAAAAAAAABOAF//AAAAAAAAAABPAF//AAAAAAAAAABQAF//AAAAAAAAAABRAF//AAAAAAAAAABZAF//AAAAAAAAAABaAF//AAAAAAAAAABbAF//AAAAAAAAAABcAF//AAAAAAAAAABdAF//AAAAAAAAAABeAF//AAAAAAAAAABfAF//AAAAAAAAAABgAF//AAAAAAAAAABhAF//AAAAAAAAAABiAF//AAAAAAAAAABjAF//AAAAAAAAAABkAF//AAAAAAAAAABlAF//AAAAAAAAAABSAF//AAAAAAAAAABYAF//AAAAAAAAAABSAGD/AAAAAAAAAABSAGH/AAAAAAAAAABSAGL/AAAAAAAAAABYAGD/AAAAAAAAAABYAGH/AAAAAAAAAABYAGL/AAAAAAAAAABTAGL/AAACAAAAAABUAGL/AAACAAAAAABVAGL/AAACAAAAAABWAGL/AAACAAAAAABXAGL/AAACAAAAAABTAF//AAAAAAAAAABXAF//AAAAAAAAAABmAJj/AAAAAAAAAABmAJn/AAAAAAAAAABmAJr/AAAAAAAAAABmAJv/AAAAAAAAAABmAJz/AAAAAAAAAABnAJj/AAAAAAAAAABnAJn/AAAAAAAAAABnAJr/AAAAAAAAAABnAJv/AAAAAAAAAABnAJz/AAAAAAAAAABnAJ3/AAAAAAAAAABmAJT/AAAAAAAAAABmAJX/AAAAAAAAAABmAJb/AAAAAAAAAABmAJf/AAAAAAAAAABnAJT/AAAAAAAAAABnAJX/AAAAAAAAAABnAJb/AAAAAAAAAABnAJf/AAAAAAAAAABnAHT/AAAAAAAAAABnAHf/AAAAAAAAAABnAHj/AAAAAAAAAAA=")
tile_set = ExtResource("23_6lqui")
[node name="spring2" parent="." instance=ExtResource("24_0k4x8")]
position = Vector2(680, -1512)
[node name="spring3" parent="." instance=ExtResource("24_0k4x8")]
position = Vector2(728, -1608)
[node name="spring4" parent="." instance=ExtResource("24_0k4x8")]
position = Vector2(600, -1640)
[node name="spring5" parent="." instance=ExtResource("24_0k4x8")]
position = Vector2(920, -1480)
[node name="spring6" parent="." instance=ExtResource("24_0k4x8")]
position = Vector2(1000, -1480)
[node name="PathDriveMovePlateform2" parent="." instance=ExtResource("25_ldp4y")]
position = Vector2(1164, -1762)
move_speed = 300.0
returning_speed = 100.0
acceleration = 1000.0
[node name="MovablePlateform" parent="PathDriveMovePlateform2" index="0"]
scale = Vector2(0.4, 0.4)
[node name="Path2D" parent="PathDriveMovePlateform2" index="1"]
curve = SubResource("Curve2D_glu07")
[node name="EventTriggerDoor" parent="." instance=ExtResource("28_4mxpo")]
position = Vector2(1367, -2553)
rotation = -1.5707964
scale = Vector2(0.64, 0.64)
[connection signal="player_entered" from="Props/PlayerTriggerVolumn" to="SceneManager" method="_on_player_trigger_volumn_player_entered"]
[editable path="PathDriveMovePlateform2"]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -124,7 +124,6 @@ limit_top = 350
limit_bottom = -255
limit_left = -430
limit_right = 415
follow_player = true
[node name="[Prop_0000]" type="Node" parent="Props/CameraAnchor"]
script = ExtResource("9_03jph")

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,13 +1,16 @@
[gd_scene load_steps=42 format=4 uid="uid://2d457ndb7toe"]
[gd_scene load_steps=48 format=4 uid="uid://2d457ndb7toe"]
[ext_resource type="Script" uid="uid://5e157vdk6175" path="res://addons/reedscene/scene/ReedScene.gd" id="1_h5hd7"]
[ext_resource type="Script" uid="uid://bh066o84byplh" path="res://addons/reedscene/scene/ReedSceneID.gd" id="2_s1dia"]
[ext_resource type="Script" uid="uid://dn0ksjoswquf5" path="res://addons/reedscene/scene/SceneManager.gd" id="3_v2x74"]
[ext_resource type="Script" uid="uid://ons77en82uls" path="res://addons/reedscene/scene/scene_trigger/base/SceneTrigger.gd" id="4_8ob7b"]
[ext_resource type="Resource" uid="uid://bym4pb0ellj7b" path="res://_scene/scene_trigger_resource/default_switch.tres" id="5_v3u1d"]
[ext_resource type="Script" uid="uid://baamspwt4rm4r" path="res://addons/reedscene/scene/guard.gd" id="6_5nchj"]
[ext_resource type="Script" uid="uid://dsgl7lbyjsiif" path="res://addons/reedscene/act/ActManager.gd" id="6_lwjpo"]
[ext_resource type="Script" uid="uid://dxj5vimigc651" path="res://addons/reedscene/scene/scene_trigger/base/SceneTriggerEffectPair.gd" id="7_3ly86"]
[ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="7_o10qt"]
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="8_nkrpp"]
[ext_resource type="Script" uid="uid://cdprpen0jyr6d" path="res://addons/reedscene/scene/scene_trigger/STR_NodePath.gd" id="8_nrwgi"]
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="9_ru3iu"]
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_camera/CameraAnchor.tscn" id="10_8v4hu"]
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="11_nkttg"]
@ -26,6 +29,16 @@
[ext_resource type="PackedScene" uid="uid://knrcnoedxvm6" path="res://_props/trigger_fall_rock_hazard/trigger_fall_rock_hazard.tscn" id="23_drx4a"]
[ext_resource type="PackedScene" uid="uid://bju8jr1w4d60m" path="res://_props/spring/spring.tscn" id="25_v3u1d"]
[ext_resource type="PackedScene" uid="uid://badmoya3nd161" path="res://_props/trigger_fall_rock_climb/trigger_fall_rock_climb.tscn" id="26_wsgut"]
[ext_resource type="PackedScene" uid="uid://rrlq7ucvgbsv" path="res://_shader/ripple.tscn" id="30_3ly86"]
[sub_resource type="Resource" id="Resource_xevr6"]
script = ExtResource("8_nrwgi")
metadata/_custom_type_script = "uid://cdprpen0jyr6d"
[sub_resource type="Resource" id="Resource_bhcjt"]
script = ExtResource("4_8ob7b")
trigger_register_conifg = SubResource("Resource_xevr6")
metadata/_custom_type_script = "uid://ons77en82uls"
[sub_resource type="Resource" id="Resource_6bhoi"]
script = ExtResource("8_nkrpp")
@ -112,7 +125,7 @@ script = ExtResource("2_s1dia")
[node name="SceneManager" type="Node" parent="."]
script = ExtResource("3_v2x74")
quick_trigger = Array[ExtResource("4_8ob7b")]([ExtResource("5_v3u1d")])
quick_trigger = Array[ExtResource("4_8ob7b")]([ExtResource("5_v3u1d"), SubResource("Resource_bhcjt")])
[node name="ActManager" type="Node" parent="."]
script = ExtResource("6_lwjpo")
@ -131,7 +144,6 @@ limit_top = -185
limit_bottom = 185
limit_left = -320
limit_right = 245
follow_player = true
[node name="[Prop_0000]" type="Node" parent="Props/CameraAnchor"]
script = ExtResource("11_nkttg")
@ -195,8 +207,29 @@ script = ExtResource("13_ot6uu")
state_id = 1
effects = Array[ExtResource("14_wesyl")]([SubResource("Resource_ubvm0")])
[node name="TriggerFallRock_Climb_1" parent="Props" instance=ExtResource("26_wsgut")]
position = Vector2(55.2, -1688)
scale = Vector2(0.95, 0.95)
[node name="[Prop_0003]" type="Node" parent="Props/TriggerFallRock_Climb_1"]
script = ExtResource("11_nkttg")
prop_id = 3
[node name="States" type="Node" parent="Props/TriggerFallRock_Climb_1/[Prop_0003]"]
script = ExtResource("12_7fah6")
[node name="[ID_0] Disable" type="Node" parent="Props/TriggerFallRock_Climb_1/[Prop_0003]/States"]
script = ExtResource("13_ot6uu")
state_id = 0
effects = Array[ExtResource("14_wesyl")]([SubResource("Resource_r0e2c")])
[node name="[ID_1] Enable" type="Node" parent="Props/TriggerFallRock_Climb_1/[Prop_0003]/States"]
script = ExtResource("13_ot6uu")
state_id = 1
effects = Array[ExtResource("14_wesyl")]([SubResource("Resource_ubvm0")])
[node name="TileMapLayer" type="TileMapLayer" parent="." groups=["GRAPABLE"]]
tile_map_data = PackedByteArray("AAD5/6X/AAAAAAAAAAD5/6T/AAAAAAAAAAD5/6P/AAAAAAAAAAD5/6L/AAAAAAAAAAD5/53/AAAAAAAAAAD5/5z/AAAAAAAAAAD5/5v/AAAAAAAAAAD5/5r/AAAAAAAAAAD5/5n/AAAAAAAAAAD5/5j/AAAAAAAAAAD5/5f/AAAAAAAAAAD5/5b/AAAAAAAAAAD5/5X/AAAAAAAAAAD5/5T/AAAAAAAAAAD5/5P/AAAAAAAAAAD5/5L/AAAAAAAAAAD5/5H/AAAAAAAAAAD5/5D/AAAAAAAAAAD5/6b/AAAAAAAAAAD6/6b/AAAAAAAAAAD7/6b/AAAAAAAAAAD8/6b/AAAAAAAAAAD9/6b/AAAAAAAAAAD+/6b/AAAAAAAAAAD//6b/AAAAAAAAAAAAAKb/AAAAAAAAAAABAKb/AAAAAAAAAAACAKb/AAAAAAAAAAADAKb/AAAAAAAAAAAEAKb/AAAAAAAAAAAFAKb/AAAAAAAAAAAGAKb/AAAAAAAAAAAHAKb/AAAAAAAAAAAIAKb/AAAAAAAAAAAJAKb/AAAAAAAAAAAKAKb/AAAAAAAAAAALAKb/AAAAAAAAAAAMAKb/AAAAAAAAAAANAKb/AAAAAAAAAAAOAKb/AAAAAAAAAAAPAKb/AAAAAAAAAAAQAKb/AAAAAAAAAAARAKb/AAAAAAAAAAASAKb/AAAAAAAAAAATAKb/AAAAAAAAAAD6/5D/AAAAAAAAAAD7/5D/AAAAAAAAAAD8/5D/AAAAAAAAAAD9/5D/AAAAAAAAAAD+/5D/AAAAAAAAAAD//5D/AAAAAAAAAAAAAJD/AAAAAAAAAAABAJD/AAAAAAAAAAACAJD/AAAAAAAAAAADAJD/AAAAAAAAAAAEAJD/AAAAAAAAAAAFAJD/AAAAAAAAAAAGAJD/AAAAAAAAAAAHAJD/AAAAAAAAAAAIAJD/AAAAAAAAAAAJAJD/AAAAAAAAAAAKAJD/AAAAAAAAAAALAJD/AAAAAAAAAAAMAJD/AAAAAAAAAAANAJD/AAAAAAAAAAAOAJD/AAAAAAAAAAAPAJD/AAAAAAAAAAAQAJD/AAAAAAAAAAARAJD/AAAAAAAAAAASAJD/AAAAAAAAAAATAJD/AAAAAAAAAAD6/6L/AAAAAAAAAAD7/6L/AAAAAAAAAAD8/6L/AAAAAAAAAAD7/6P/AAAAAAAAAAD6/6P/AAAAAAAAAAD6/6T/AAAAAAAAAAD6/6X/AAAAAAAAAAD7/6X/AAAAAAAAAAD9/6L/AAAAAAAAAAD8/6P/AAAAAAAAAAD6/5X/AAAAAAAAAAD+/5L/AAAAAAAAAAD9/5L/AAAAAAAAAAD9/5H/AAAAAAAAAAD8/5H/AAAAAAAAAAD7/5H/AAAAAAAAAAD6/5H/AAAAAAAAAAD6/5L/AAAAAAAAAAD6/5P/AAAAAAAAAAD6/5T/AAAAAAAAAAD7/5P/AAAAAAAAAAD7/5L/AAAAAAAAAAD8/5L/AAAAAAAAAAD+/5H/AAAAAAAAAAAAAJH/AAAAAAAAAAABAJH/AAAAAAAAAAACAJH/AAAAAAAAAAADAJH/AAAAAAAAAAAEAJH/AAAAAAAAAAD//5H/AAAAAAAAAAD//5L/AAAAAAAAAAAAAJL/AAAAAAAAAAAAAJP/AAAAAAAAAAAAAJT/AAAAAAAAAAAAAJX/AAAAAAAAAAABAJX/AAAAAAAAAAABAJL/AAAAAAAAAAABAJP/AAAAAAAAAAABAJT/AAAAAAAAAAAAAJb/AAAAAAAAAAAAAJf/AAAAAAAAAAAAAJj/AAAAAAAAAAACAJL/AAAAAAAAAAADAJL/AAAAAAAAAAAEAJL/AAAAAAAAAAAHAKL/AAAAAAAAAAAHAKP/AAAAAAAAAAAHAKT/AAAAAAAAAAAIAKL/AAAAAAAAAAAIAKP/AAAAAAAAAAAIAKT/AAAAAAAAAAAIAKX/AAAAAAAAAAD8/6X/AAABAAAAAAD9/6X/AAABAAAAAAD+/6X/AAABAAAAAAD//6X/AAABAAAAAAAAAKX/AAABAAAAAAABAKX/AAABAAAAAAACAKX/AAABAAAAAAADAKX/AAABAAAAAAAEAKX/AAABAAAAAAAFAKX/AAABAAAAAAAGAKX/AAABAAAAAAAHAKX/AAAAAAAAAAAGAKT/AAABAAAAAAAGAKP/AAABAAAAAAAGAKL/AAABAAAAAAAJAKL/AAABAAAAAAAJAKP/AAABAAAAAAAJAKT/AAABAAAAAAAJAKX/AAABAAAAAAAKAJf/AAAAAAAAAAAKAJj/AAAAAAAAAAAKAJn/AAAAAAAAAAAKAJr/AAAAAAAAAAAKAJv/AAAAAAAAAAALAJf/AAAAAAAAAAALAJj/AAAAAAAAAAALAJn/AAAAAAAAAAAKAJz/AAAAAAAAAAAMAJf/AAAAAAAAAAAMAJj/AAAAAAAAAAAMAJn/AAAAAAAAAAABAJb/AAAAAAAAAAABAJf/AAAAAAAAAAACAJP/AAAAAAAAAAAEAJP/AAAAAAAAAAADAJP/AAAAAAAAAAACAJT/AAAAAAAAAAADAJT/AAAAAAAAAAAEAJT/AAAAAAAAAAAKAKX/AAABAAAAAAALAKX/AAABAAAAAAAMAKX/AAABAAAAAAAOAKX/AAABAAAAAAANAKX/AAABAAAAAAAPAKX/AAABAAAAAAAQAKX/AAABAAAAAAARAKX/AAABAAAAAAASAKX/AAABAAAAAAATAKX/AAABAAAAAAALAJ7/AAAAAAAAAAANAJn/AAAAAAAAAAAOAJn/AAAAAAAAAAALAJr/AAAAAAAAAAALAJv/AAAAAAAAAAAKAJ3/AAAAAAAAAAALAJz/AAAAAAAAAAALAJ3/AAAAAAAAAAARAJ7/AAAAAAAAAAARAJ3/AAAAAAAAAAARAJz/AAAAAAAAAAARAJv/AAAAAAAAAAARAJr/AAAAAAAAAAARAJn/AAAAAAAAAAARAJj/AAAAAAAAAAARAJf/AAAAAAAAAAARAJb/AAAAAAAAAAARAJX/AAAAAAAAAAARAJT/AAAAAAAAAAARAJP/AAAAAAAAAAARAJH/AAAAAAAAAAARAJL/AAAAAAAAAAAQAJP/AAAAAAAAAAAQAJT/AAAAAAAAAAAQAJX/AAAAAAAAAAAQAJb/AAABAAAAAAAQAJf/AAABAAAAAAAQAJj/AAABAAAAAAAQAJn/AAABAAAAAAAQAJr/AAABAAAAAAAQAJv/AAABAAAAAAAQAJz/AAABAAAAAAAQAJ3/AAABAAAAAAAQAJ7/AAABAAAAAAANAJj/AAAAAAAAAAAOAJj/AAAAAAAAAAASAJ7/AAAAAAAAAAATAJ7/AAAAAAAAAAAUAJ7/AAAAAAAAAAAVAJ7/AAAAAAAAAAAWAJ7/AAAAAAAAAAAXAJ7/AAAAAAAAAAAYAJ7/AAAAAAAAAAAUAKb/AAAAAAAAAAAVAKb/AAAAAAAAAAAVAKX/AAAAAAAAAAAWAKX/AAAAAAAAAAAXAKT/AAAAAAAAAAAYAKT/AAAAAAAAAAAYAKP/AAAAAAAAAAAXAKP/AAAAAAAAAAAUAKX/AAABAAAAAAAVAKT/AAABAAAAAAAWAKP/AAABAAAAAAAWAKT/AAAAAAAAAAAYAKL/AAAAAAAAAAAXAKL/AAABAAAAAAAZAKL/AAAAAAAAAAAaAKL/AAAAAAAAAAAbAKL/AAAAAAAAAAAaAJ3/AAAAAAAAAAAbAJ3/AAAAAAAAAAAZAJ3/AAAAAAAAAAAYAJ3/AAAAAAAAAAAQAJL/AAAAAAAAAAAPAJL/AAAAAAAAAAAOAJL/AAAAAAAAAAANAJH/AAAAAAAAAAAOAJH/AAAAAAAAAAAPAJH/AAAAAAAAAAAQAJH/AAAAAAAAAAAPAJP/AAAAAAAAAAAFAJH/AAAAAAAAAAAGAJH/AAAAAAAAAAAHAJH/AAAAAAAAAAAIAJH/AAAAAAAAAAAJAJH/AAAAAAAAAAAGAJL/AAAAAAAAAAAFAJL/AAAAAAAAAAAFAJP/AAAAAAAAAAAIAJL/AAAAAAAAAAAJAJL/AAAAAAAAAAASAJ3/AAAAAAAAAAASAJz/AAAAAAAAAAASAJv/AAAAAAAAAAASAJr/AAAAAAAAAAASAJn/AAAAAAAAAAASAJj/AAAAAAAAAAASAJf/AAAAAAAAAAASAJb/AAAAAAAAAAASAJX/AAAAAAAAAAASAJT/AAAAAAAAAAATAJ3/AAAAAAAAAAAUAJ3/AAAAAAAAAAAVAJ3/AAAAAAAAAAAWAJ3/AAAAAAAAAAAXAJ3/AAAAAAAAAAAXAJz/AAAAAAAAAAAYAJz/AAAAAAAAAAAZAJz/AAAAAAAAAAAbAJz/AAAAAAAAAAAaAKP/AAAAAAAAAAAbAKP/AAAAAAAAAAAZAKT/AAAAAAAAAAD6/5v/AAAAAAAAAAD6/5r/AAAAAAAAAAA=")
tile_map_data = PackedByteArray("AAD5/6X/AAAAAAAAAAD5/6T/AAAAAAAAAAD5/6P/AAAAAAAAAAD5/6L/AAAAAAAAAAD5/53/AAAAAAAAAAD5/5z/AAAAAAAAAAD5/5v/AAAAAAAAAAD5/5r/AAAAAAAAAAD5/5n/AAAAAAAAAAD5/5j/AAAAAAAAAAD5/5f/AAAAAAAAAAD5/5b/AAAAAAAAAAD5/5X/AAAAAAAAAAD5/5T/AAAAAAAAAAD5/5P/AAAAAAAAAAD5/5L/AAAAAAAAAAD5/5H/AAAAAAAAAAD5/5D/AAAAAAAAAAD5/6b/AAAAAAAAAAD6/6b/AAAAAAAAAAD7/6b/AAAAAAAAAAD8/6b/AAAAAAAAAAD9/6b/AAAAAAAAAAD+/6b/AAAAAAAAAAD//6b/AAAAAAAAAAAAAKb/AAAAAAAAAAABAKb/AAAAAAAAAAACAKb/AAAAAAAAAAADAKb/AAAAAAAAAAAEAKb/AAAAAAAAAAAFAKb/AAAAAAAAAAAGAKb/AAAAAAAAAAAHAKb/AAAAAAAAAAAIAKb/AAAAAAAAAAAJAKb/AAAAAAAAAAAKAKb/AAAAAAAAAAALAKb/AAAAAAAAAAAMAKb/AAAAAAAAAAANAKb/AAAAAAAAAAAOAKb/AAAAAAAAAAAPAKb/AAAAAAAAAAAQAKb/AAAAAAAAAAARAKb/AAAAAAAAAAASAKb/AAAAAAAAAAATAKb/AAAAAAAAAAD6/5D/AAAAAAAAAAD7/5D/AAAAAAAAAAD8/5D/AAAAAAAAAAD9/5D/AAAAAAAAAAD+/5D/AAAAAAAAAAD//5D/AAAAAAAAAAAAAJD/AAAAAAAAAAABAJD/AAAAAAAAAAACAJD/AAAAAAAAAAADAJD/AAAAAAAAAAAEAJD/AAAAAAAAAAAFAJD/AAAAAAAAAAAGAJD/AAAAAAAAAAAHAJD/AAAAAAAAAAAIAJD/AAAAAAAAAAAJAJD/AAAAAAAAAAAKAJD/AAAAAAAAAAALAJD/AAAAAAAAAAAMAJD/AAAAAAAAAAANAJD/AAAAAAAAAAAOAJD/AAAAAAAAAAAPAJD/AAAAAAAAAAAQAJD/AAAAAAAAAAARAJD/AAAAAAAAAAASAJD/AAAAAAAAAAATAJD/AAAAAAAAAAD6/6L/AAAAAAAAAAD7/6L/AAAAAAAAAAD8/6L/AAAAAAAAAAD7/6P/AAAAAAAAAAD6/6P/AAAAAAAAAAD6/6T/AAAAAAAAAAD6/6X/AAAAAAAAAAD7/6X/AAAAAAAAAAD9/6L/AAAAAAAAAAD8/6P/AAAAAAAAAAD6/5X/AAAAAAAAAAD+/5L/AAAAAAAAAAD9/5L/AAAAAAAAAAD9/5H/AAAAAAAAAAD8/5H/AAAAAAAAAAD7/5H/AAAAAAAAAAD6/5H/AAAAAAAAAAD6/5L/AAAAAAAAAAD6/5P/AAAAAAAAAAD6/5T/AAAAAAAAAAD7/5P/AAAAAAAAAAD7/5L/AAAAAAAAAAD8/5L/AAAAAAAAAAD+/5H/AAAAAAAAAAAAAJH/AAAAAAAAAAABAJH/AAAAAAAAAAACAJH/AAAAAAAAAAADAJH/AAAAAAAAAAAEAJH/AAAAAAAAAAD//5H/AAAAAAAAAAD//5L/AAAAAAAAAAAAAJL/AAAAAAAAAAAAAJP/AAAAAAAAAAAAAJT/AAAAAAAAAAAAAJX/AAAAAAAAAAABAJX/AAAAAAAAAAABAJL/AAAAAAAAAAABAJP/AAAAAAAAAAABAJT/AAAAAAAAAAAAAJb/AAAAAAAAAAAAAJf/AAAAAAAAAAAAAJj/AAAAAAAAAAACAJL/AAAAAAAAAAADAJL/AAAAAAAAAAAEAJL/AAAAAAAAAAAHAKL/AAAAAAAAAAAIAKL/AAAAAAAAAAAIAKT/AAAAAAAAAAAIAKX/AAAAAAAAAAD8/6X/AAABAAAAAAD9/6X/AAABAAAAAAD+/6X/AAABAAAAAAD//6X/AAABAAAAAAAAAKX/AAABAAAAAAABAKX/AAABAAAAAAACAKX/AAABAAAAAAADAKX/AAABAAAAAAAEAKX/AAABAAAAAAAFAKX/AAABAAAAAAAGAKX/AAAAAAAAAAAGAKT/AAAAAAAAAAAGAKL/AAAAAAAAAAAJAKL/AAABAAAAAAAJAKP/AAABAAAAAAAJAKT/AAABAAAAAAAJAKX/AAABAAAAAAAKAJf/AAAAAAAAAAAKAJj/AAAAAAAAAAAKAJn/AAAAAAAAAAAKAJr/AAAAAAAAAAAKAJv/AAAAAAAAAAALAJf/AAAAAAAAAAALAJj/AAAAAAAAAAALAJn/AAAAAAAAAAAKAJz/AAAAAAAAAAAMAJf/AAAAAAAAAAAMAJj/AAAAAAAAAAAMAJn/AAAAAAAAAAABAJb/AAAAAAAAAAABAJf/AAAAAAAAAAACAJP/AAAAAAAAAAAEAJP/AAAAAAAAAAADAJP/AAAAAAAAAAACAJT/AAAAAAAAAAADAJT/AAAAAAAAAAAEAJT/AAAAAAAAAAAKAKX/AAABAAAAAAAOAKX/AAABAAAAAAAPAKX/AAABAAAAAAAQAKX/AAABAAAAAAARAKX/AAABAAAAAAASAKX/AAABAAAAAAATAKX/AAABAAAAAAALAJ7/AAAAAAAAAAANAJn/AAAAAAAAAAAOAJn/AAAAAAAAAAALAJr/AAAAAAAAAAALAJv/AAAAAAAAAAAKAJ3/AAAAAAAAAAALAJz/AAAAAAAAAAALAJ3/AAAAAAAAAAARAJ7/AAAAAAAAAAARAJ3/AAAAAAAAAAARAJz/AAAAAAAAAAARAJv/AAAAAAAAAAARAJr/AAAAAAAAAAARAJn/AAAAAAAAAAARAJj/AAAAAAAAAAARAJf/AAAAAAAAAAARAJb/AAAAAAAAAAARAJX/AAAAAAAAAAARAJT/AAAAAAAAAAARAJP/AAAAAAAAAAARAJH/AAAAAAAAAAARAJL/AAAAAAAAAAAQAJP/AAAAAAAAAAAQAJT/AAAAAAAAAAAQAJX/AAAAAAAAAAAQAJb/AAABAAAAAAAQAJf/AAABAAAAAAAQAJj/AAABAAAAAAAQAJn/AAABAAAAAAAQAJr/AAABAAAAAAAQAJv/AAABAAAAAAAQAJz/AAABAAAAAAAQAJ3/AAABAAAAAAAQAJ7/AAABAAAAAAANAJj/AAAAAAAAAAAOAJj/AAAAAAAAAAASAJ7/AAAAAAAAAAATAJ7/AAAAAAAAAAAUAJ7/AAAAAAAAAAAVAJ7/AAAAAAAAAAAWAJ7/AAAAAAAAAAAXAJ7/AAAAAAAAAAAYAJ7/AAAAAAAAAAAUAKb/AAAAAAAAAAAVAKb/AAAAAAAAAAAVAKX/AAAAAAAAAAAWAKX/AAAAAAAAAAAXAKT/AAAAAAAAAAAYAKT/AAAAAAAAAAAYAKP/AAAAAAAAAAAXAKP/AAAAAAAAAAAUAKX/AAABAAAAAAAVAKT/AAABAAAAAAAWAKP/AAABAAAAAAAWAKT/AAAAAAAAAAAYAKL/AAAAAAAAAAAXAKL/AAABAAAAAAAZAKL/AAAAAAAAAAAaAKL/AAAAAAAAAAAbAKL/AAAAAAAAAAAaAJ3/AAAAAAAAAAAbAJ3/AAAAAAAAAAAZAJ3/AAAAAAAAAAAYAJ3/AAAAAAAAAAAQAJL/AAAAAAAAAAAPAJL/AAAAAAAAAAAOAJL/AAAAAAAAAAANAJH/AAAAAAAAAAAOAJH/AAAAAAAAAAAPAJH/AAAAAAAAAAAQAJH/AAAAAAAAAAAPAJP/AAAAAAAAAAAFAJH/AAAAAAAAAAAGAJH/AAAAAAAAAAAHAJH/AAAAAAAAAAAIAJH/AAAAAAAAAAAJAJH/AAAAAAAAAAAGAJL/AAAAAAAAAAAFAJL/AAAAAAAAAAAFAJP/AAAAAAAAAAAIAJL/AAAAAAAAAAASAJ3/AAAAAAAAAAASAJz/AAAAAAAAAAASAJv/AAAAAAAAAAASAJr/AAAAAAAAAAASAJn/AAAAAAAAAAASAJj/AAAAAAAAAAASAJf/AAAAAAAAAAASAJb/AAAAAAAAAAASAJX/AAAAAAAAAAASAJT/AAAAAAAAAAATAJ3/AAAAAAAAAAAUAJ3/AAAAAAAAAAAVAJ3/AAAAAAAAAAAWAJ3/AAAAAAAAAAAXAJ3/AAAAAAAAAAAXAJz/AAAAAAAAAAAYAJz/AAAAAAAAAAAZAJz/AAAAAAAAAAAbAJz/AAAAAAAAAAAaAKP/AAAAAAAAAAAbAKP/AAAAAAAAAAAZAKT/AAAAAAAAAAD6/5v/AAAAAAAAAAD6/5r/AAAAAAAAAAAFAKL/AAABAAAAAAAFAKP/AAABAAAAAAAFAKT/AAABAAAAAAAHAKT/AAAAAAAAAAAIAKP/AAAAAAAAAAAGAKP/AAAAAAAAAAALAKX/AAABAAAAAAAMAKX/AAABAAAAAAANAKX/AAABAAAAAAA=")
tile_set = ExtResource("23_70cor")
[node name="TriggerFallRock_Hazard" parent="." instance=ExtResource("23_drx4a")]
@ -204,15 +237,14 @@ position = Vector2(184, -1679)
scale = Vector2(0.9, 0.9)
metadata/_edit_group_ = true
[node name="TriggerFallRock_Climb_1" parent="." instance=ExtResource("26_wsgut")]
position = Vector2(56.000004, -1688)
scale = Vector2(0.95, 0.95)
[node name="TriggerFallRock_Climb" parent="." instance=ExtResource("26_wsgut")]
position = Vector2(217.00002, -1608)
scale = Vector2(0.95, 0.95)
[node name="TriggerFallRock_Climb_2" parent="." instance=ExtResource("26_wsgut")]
position = Vector2(215.5, -1608)
scale = Vector2(0.94, 0.94)
[node name="spring" parent="." instance=ExtResource("25_v3u1d")]
position = Vector2(-40, -1512)
[node name="Ripple" parent="." instance=ExtResource("30_3ly86")]
position = Vector2(-9, -1598)
[connection signal="player_entered" from="Props/PlayerTriggerVolumn" to="SceneManager" method="_on_player_trigger_volumn_player_entered"]

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,5 @@
[gd_resource type="Resource" script_class="SceneTrigger" load_steps=20 format=3 uid="uid://bym4pb0ellj7b"]
[gd_resource type="Resource" script_class="SceneTrigger" load_steps=19 format=3 uid="uid://bym4pb0ellj7b"]
[ext_resource type="Script" uid="uid://baamspwt4rm4r" path="res://addons/reedscene/scene/guard.gd" id="1_ebfhi"]
[ext_resource type="Script" uid="uid://ons77en82uls" path="res://addons/reedscene/scene/scene_trigger/base/SceneTrigger.gd" id="2_cq8o1"]
[ext_resource type="Script" uid="uid://dxj5vimigc651" path="res://addons/reedscene/scene/scene_trigger/base/SceneTriggerEffectPair.gd" id="3_m0qh3"]
[ext_resource type="Script" uid="uid://b1bgmb71bapws" path="res://addons/reedscene/scene/scene_trigger/base/SceneTriggerEffect.gd" id="4_g7ixm"]

141
_shader/ripple.gdshader Normal file
View File

@ -0,0 +1,141 @@
shader_type canvas_item;
// =============================
// original: https://www.shadertoy.com/view/wtcSzN
// adaptation: GerardoLCDF
// =============================
uniform bool u_debug_mode = false;
uniform sampler2D noise_texture : filter_nearest;
uniform sampler2D logo_texture : filter_linear;
uniform vec2 logo_aspect_ratio = vec2(2.0, 0.85);
#define PI 3.14159265359
float vmin(vec2 v) { return min(v.x, v.y); }
float vmax(vec2 v) { return max(v.x, v.y); }
float ellip(vec2 p, vec2 s) { float m = vmin(s); return (length(p / s) * m) - m; }
float halfEllip(vec2 p, vec2 s) { p.x = max(0.0, p.x); float m = vmin(s); return (length(p / s) * m) - m; }
float fBox(vec2 p, vec2 b) { return vmax(abs(p) - b); }
float dvd_d(vec2 p) { float d = halfEllip(p, vec2(.8, .5)); d = max(d, -p.x - .5); float d2 = halfEllip(p, vec2(.45, .3)); d2 = max(d2, min(-p.y + .2, -p.x - .15)); d = max(d, -d2); return d; }
float dvd_v(vec2 p) { vec2 pp = p; p.y += .7; p.x = abs(p.x); vec2 a = normalize(vec2(1.0, -.55)); float d = dot(p, a); float d2 = d + .3; p = pp; d = min(d, -p.y + .3); d2 = min(d2, -p.y + .5); d = max(d, -d2); d = max(d, abs(p.x + .3) - 1.1); return d; }
float dvd_c(vec2 p) { p.y += .95; float d = ellip(p, vec2(1.8, .25)); float d2 = ellip(p, vec2(.45, .09)); d = max(d, -d2); return d; }
float dvd(vec2 p) { p.y -= .345; p.x -= .035; p *= mat2(vec2(1.0, 0.0), vec2(-0.2, 1.0)); float d = dvd_v(p); d = min(d, dvd_c(p)); p.x += 1.3; d = min(d, dvd_d(p)); p.x -= 2.4; d = min(d, dvd_d(p)); return d; }
float range(float vmin, float vmax, float value) { return (value - vmin) / (vmax - vmin); }
float rangec(float a, float b, float t) { return clamp(range(a, b, t), 0.0, 1.0); }
vec3 pal( in float t, in vec3 a, in vec3 b, in vec3 c, in vec3 d ) { return a + b*cos( 6.28318*(c*t+d) ); }
vec3 spectrum(float n) { return pal( n, vec3(0.5, 0.5, 0.5), vec3(0.5, 0.5, 0.5), vec3(1.0, 1.0, 1.0), vec3(0.0, 0.33, 0.67) ); }
void drawHit(inout vec4 col, vec2 p, vec2 hitPos, float hitDist) { float d = length(p - hitPos); if (u_debug_mode) { col = mix(col, vec4(0.0, 1.0, 1.0, 0.0), step(d, .1)); return; } float wavefront = d - hitDist * 1.5; float freq = 2.0; vec3 spec = (1.0 - spectrum(-wavefront * freq + hitDist * freq)); float ripple = sin((wavefront * freq) * PI*2.0 - PI/2.0); float blend = smoothstep(3.0, 0.0, hitDist); blend *= smoothstep(.2, -.5, wavefront); blend *= rangec(-4.0, .0, wavefront); col.rgb *= mix(vec3(1.0), spec, pow(blend, 4.0)); float height = (ripple * blend); col.a -= height * 1.9 / freq; }
vec2 ref(vec2 p, vec2 planeNormal, float offset) { float t = dot(p, planeNormal) + offset; p -= (2.0 * t) * planeNormal; return p; }
void drawReflectedHit(inout vec4 col, vec2 p, vec2 hitPos, float hitDist, vec2 screenSize) { col.a += length(p) * .0001; drawHit(col, p, hitPos, hitDist); }
void flip(inout vec2 pos) { vec2 flip_val = mod(floor(pos), 2.0); pos = abs(flip_val - mod(pos, 1.0)); }
float stepSign(float a) { return step(0.0, a) * 2.0 - 1.0; }
vec2 compassDir(vec2 p) { vec2 a = vec2(stepSign(p.x), 0.0); vec2 b = vec2(0.0, stepSign(p.y)); float s = stepSign(p.x - p.y) * stepSign(-p.x - p.y); return mix(a, b, s * .5 + .5); }
vec2 calcHitPos(vec2 move, vec2 dir, vec2 size) { vec2 hitPos = mod(move, 1.0); vec2 xCross = hitPos - hitPos.x / (size / size.x) * (dir / dir.x); vec2 yCross = hitPos - hitPos.y / (size / size.y) * (dir / dir.y); hitPos = max(xCross, yCross); hitPos += floor(move); return hitPos; }
void fragment()
{
// 取 sprite 像素尺寸(用 TEXTURE_SIZE 是最标准的)
vec2 screenSize = vec2(textureSize(TEXTURE, 0));
// 把 UV(0~1) 映射到类似你原来 p 的坐标系:
// 中心为 0按高度归一化
vec2 p = (-screenSize + 2.0 * (UV * screenSize)) / screenSize.y;
if (u_debug_mode) { p *= 2.0; }
vec2 screen_aspect = vec2(screenSize.x/screenSize.y, 1.0) * 2.0;
float t = TIME;
vec2 dir = normalize(vec2(9.0, 16.0) * screen_aspect);
vec2 move = dir * t / 1.5;
float logoScale = .1;
vec2 logoSize = logo_aspect_ratio * logoScale;
vec2 size = screen_aspect - logoSize * 2.0;
move = move / size + .5;
// 单点发射:固定在中间(你也可以改成其他位置)
vec2 hitPos = vec2(0.0, 0.0);
// col / colFx / colFy 保留,用来算法线高光
vec4 col = vec4(1.0, 1.0, 1.0, 0.0);
vec4 colFx = vec4(1.0, 1.0, 1.0, 0.0);
vec4 colFy = vec4(1.0, 1.0, 1.0, 0.0);
vec2 e = vec2(.8, 0.0) / screenSize.y;
float period = 2.0; // 每次发射间隔(秒)
float hitDist = mod(TIME, period); // 循环计时0~period
// 直接画一次,不要反射链
drawReflectedHit(col, p, hitPos, hitDist, screen_aspect);
drawReflectedHit(colFx, p + e, hitPos, hitDist, screen_aspect);
drawReflectedHit(colFy, p + e.yx, hitPos, hitDist, screen_aspect);
flip(move);
move = (move - .5) * size;
float bf = .1;
float fx = (col.a - colFx.a) * 2.0;
float fy = (col.a - colFy.a) * 2.0;
vec3 nor = normalize(vec3(fx, fy, e.x/bf));
float ff = length(vec2(fx, fy));
float ee = rangec(0.0, 10.0/screenSize.y, ff);
nor = normalize(vec3(vec2(fx, fy)*ee, ff));
col.rgb = clamp(1.0 - col.rgb, vec3(0.0), vec3(1.0));
col.rgb /= 3.0;
if (!u_debug_mode) {
vec3 lig = normalize(vec3(1.0, 2.0, 2.0));
vec3 rd = normalize(vec3(p, -10.0));
vec3 hal = normalize( lig - rd );
float dif = clamp(dot(lig, nor), 0.0, 1.0);
float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ), 16.0) * dif * (0.04 + 0.96 * pow( clamp(1.0 + dot(hal, rd), 0.0, 1.0), 5.0 ));
vec3 lin = vec3(0.0);
lin += 5.0 * dif;
lin += .2;
col.rgb = col.rgb * lin;
col.rgb += 5.0 * spe;
}
if (u_debug_mode) {
float b = vmin(abs(fract(p / screen_aspect) - .5) * 2.0);
b /= fwidth(b) * 2.0;
b = clamp(b, 0.0, 1.0);
b = 1.0 - b;
col.rgb = mix(col.rgb, vec3(0.0), b);
}
vec2 logo_size = logo_aspect_ratio * logoScale;
vec2 local_pos = p - move;
vec2 logo_uv = (local_pos / logo_size) + 0.5;
vec4 logo_sample = texture(logo_texture, logo_uv);
float uv_valid = step(0.0, logo_uv.x) * step(logo_uv.x, 1.0) * step(0.0, logo_uv.y) * step(logo_uv.y, 1.0);
float logo_mask = logo_sample.a * uv_valid;
//col.rgb = mix(col.rgb, logo_sample.rgb, logo_mask);
vec4 noise_sample = texture(noise_texture, FRAGCOORD.xy / screenSize);
col.rgb += (noise_sample.rgb * 2.0 - 1.0) * .005;
col.rgb = pow(col.rgb, vec3(1.0/1.5));
col.a = col.a * .5 + .5;
col.a *= .3;
COLOR = col;
}

View File

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

17
_shader/ripple.tscn Normal file
View File

@ -0,0 +1,17 @@
[gd_scene load_steps=4 format=3 uid="uid://rrlq7ucvgbsv"]
[ext_resource type="Shader" uid="uid://b14j7g5tolgq" path="res://_shader/new_shader.gdshader" id="1_kkjpc"]
[ext_resource type="Texture2D" uid="uid://cfjprjiin3dnk" path="res://_asset/ksw/normal.png" id="2_kkjpc"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_iixbh"]
shader = ExtResource("1_kkjpc")
shader_parameter/amount = 20.0
shader_parameter/move = 1.0
shader_parameter/bandsize = 0.1
shader_parameter/speed = 1.0
[node name="Ripple" type="Node2D"]
[node name="Sprite2D" type="Sprite2D" parent="."]
material = SubResource("ShaderMaterial_iixbh")
texture = ExtResource("2_kkjpc")

149
_shader/ripple2.gdshader Normal file
View File

@ -0,0 +1,149 @@
shader_type canvas_item;
// ✅ Godot 4必须这样拿屏幕纹理不能用 SCREEN_TEXTURE
uniform sampler2D screen_tex : hint_screen_texture, filter_linear_mipmap;
// 可视化调试R=通道G=边缘脊B=尾迹
uniform bool debug_show = false;
// 由脚本每帧传入屏幕UV 0~1
uniform vec2 obj_uv = vec2(0.5, 0.5);
uniform vec2 obj_dir = vec2(1.0, 0.0);
uniform float obj_speed = 1.0;
// 可选噪声:建议给一张灰度噪声(Perlin/BlueNoise)
// 没有也能跑,只是边缘会更规整
uniform sampler2D noise_tex : filter_linear, repeat_enable;
// -------- 形状(开槽+水脊)--------
uniform float lane_half_width = 0.085; // 通道半宽(越大拨开越宽)
uniform float edge_width = 0.040; // 水脊宽度(卷起那条边)
uniform float trail_length = 0.55; // 尾迹长度
// -------- 位移强度(核心)--------
uniform float push_strength = 0.075; // 两侧推开(主要折射)
uniform float drag_strength = 0.045; // 沿方向拖拽(带走水)
uniform float suck_strength = 0.030; // 中心下陷(通道更像被挖开)
uniform float curl_strength = 0.070; // 卷边强度(更像拨水卷起)
// -------- 泡沫/细节 --------
uniform float foam_strength = 0.45; // 水脊亮边强度
uniform float noise_scale = 3.5; // 噪声缩放
uniform float noise_advect = 0.50; // 噪声随时间沿方向流动速度
uniform float chroma_shift = 0.60; // 色散强度0=无)
float sat(float x) { return clamp(x, 0.0, 1.0); }
vec2 safe_norm(vec2 v) {
float l = length(v);
return (l > 1e-5) ? (v / l) : vec2(1.0, 0.0);
}
float n2(vec2 uv) {
// 如果你没设置 noise_tex这里通常会是 0效果依旧能跑
return texture(noise_tex, uv).r;
}
// 用噪声梯度构造“卷动方向”(让边缘像被拨起来)
vec2 curl_dir(vec2 uv) {
float e = 0.002;
float nL = n2(uv - vec2(e, 0.0));
float nR = n2(uv + vec2(e, 0.0));
float nD = n2(uv - vec2(0.0, e));
float nU = n2(uv + vec2(0.0, e));
vec2 g = vec2(nR - nL, nU - nD);
return safe_norm(vec2(-g.y, g.x));
}
void fragment() {
vec2 uv = SCREEN_UV;
vec2 dir = safe_norm(obj_dir);
vec2 perp = vec2(-dir.y, dir.x);
// 局部坐标(相对玩家)
vec2 v = uv - obj_uv;
float forward = dot(v, dir); // 沿前进方向(身后为正)
float side = dot(v, perp); // 左右偏移
// 只在“身后”生效(像船头拨水/尾迹)
float behind = step(0.0, forward);
// 更像粘稠的尾迹衰减(指数衰减)
float trail = exp(-forward / max(trail_length, 1e-4)) * behind;
// 通道(中间被拨开的区域)
float lane = 1.0 - smoothstep(lane_half_width, lane_half_width * 1.35, abs(side));
// 水脊(在通道边缘一圈)
float edge = 1.0 - smoothstep(edge_width, 0.0, abs(abs(side) - lane_half_width));
// 噪声坐标:沿运动方向流动
vec2 flow_uv = uv * noise_scale + dir * (TIME * noise_advect);
float nn = n2(flow_uv);
float wobble = (nn * 2.0 - 1.0);
// 速度缩放(慢就弱)
float spd = sat(obj_speed);
// 推开方向(左右分开)
float sgn = sign(side + 1e-6);
vec2 push = perp * sgn;
// “抽走”方向(让中间更凹/更干净)
vec2 suck = -push;
// 卷边:用 curl_dir + push 混合,让边缘有翻卷感
vec2 cdir = curl_dir(flow_uv);
vec2 curl = (cdir + push * 0.6) * (edge * trail);
// 组装位移场(折射偏移)
vec2 offset = vec2(0.0);
// 1) 中央通道推开
offset += push * (lane * trail) * (push_strength * spd);
// 2) 沿方向拖拽(把水带走)
offset += dir * (lane * trail) * (drag_strength * spd);
// 3) 中心下陷/抽走(更像被拨开挖出槽)
offset += suck * (lane * trail) * (suck_strength * spd);
// 4) 边缘卷动(水脊翻起)
offset += curl * (curl_strength * spd);
// 5) 边缘破碎(泡沫感)
offset += push * wobble * (edge * trail) * (0.02 * spd);
// 先准备输出颜色变量(避免 return
vec3 col;
if (debug_show) {
// debugR=通道G=边缘B=尾迹
col = vec3(lane, edge, trail);
} else {
// ===== 折射采样(带一点色散)=====
vec2 o = offset;
if (chroma_shift > 0.001) {
float cs = chroma_shift * 0.002; // 色散很容易过头,保持小
float r = texture(screen_tex, uv + o * (1.0 + cs)).r;
float g = texture(screen_tex, uv + o).g;
float b = texture(screen_tex, uv + o * (1.0 - cs)).b;
col = vec3(r, g, b);
} else {
col = texture(screen_tex, uv + o).rgb;
}
// ===== 泡沫亮边 =====
float foam = edge * trail * spd;
foam *= (0.55 + 0.45 * wobble); // 破碎感
foam = sat(foam);
col += foam * foam_strength;
}
COLOR = vec4(col, 1.0);
}

View File

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

View File

@ -35,26 +35,21 @@ func get_player_controller() -> PlayerController:
return _cached_player_controller
func player_follow_camera() -> void:
if not _cached_player:return
var cam := ReedCameraSystem.get_current_camera_pointer() as CameraPointer
if not cam:return
var follower := cam.get_tool_by_type(CameraPointer.ToolType.FOLLOWER)
if not follower:return
follower.register_follower(_cached_player)
_camera_follower = follower
if not _cached_player:return
follower.register_follower(_cached_player)
func player_unfollow_camera() -> void:
var cam := ReedCameraSystem.get_current_camera_pointer() as CameraPointer
if not cam:return
var follower := cam.get_tool_by_type(CameraPointer.ToolType.FOLLOWER)
if not follower:return
follower.unregister_follower()
_camera_follower = null
if _camera_follower:
_camera_follower.unregister_follower()
_camera_follower = null
## 外部用于监听Player死亡
func boradcast_player_dead_event(player:Player) -> void:

372
_tileset/level1.tres Normal file
View File

@ -0,0 +1,372 @@
[gd_resource type="TileSet" load_steps=9 format=3 uid="uid://cup1q1upvp18h"]
[ext_resource type="Texture2D" uid="uid://dnrvktjrinxon" path="res://_asset/tile/pure_color_tile.png" id="1_u6jqb"]
[ext_resource type="Texture2D" uid="uid://dd622t4mw5vva" path="res://_asset/ksw/basicTile01.png" id="2_mucy5"]
[ext_resource type="Texture2D" uid="uid://dufe0liirugbw" path="res://_asset/ksw/basicTile02.png" id="3_u6jqb"]
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_h7jxu"]
texture = ExtResource("1_u6jqb")
texture_region_size = Vector2i(128, 128)
1:1/0 = 0
2:1/0 = 0
3:1/0 = 0
4:1/0 = 0
5:1/0 = 0
6:1/0 = 0
7:1/0 = 0
8:1/0 = 0
9:1/0 = 0
10:1/0 = 0
12:1/0 = 0
13:1/0 = 0
16:1/0 = 0
17:1/0 = 0
18:1/0 = 0
1:2/0 = 0
2:2/0 = 0
3:2/0 = 0
4:2/0 = 0
5:2/0 = 0
6:2/0 = 0
7:2/0 = 0
8:2/0 = 0
9:2/0 = 0
10:2/0 = 0
16:2/0 = 0
17:2/0 = 0
18:2/0 = 0
1:3/0 = 0
2:3/0 = 0
4:3/0 = 0
5:3/0 = 0
6:3/0 = 0
7:3/0 = 0
8:3/0 = 0
9:3/0 = 0
10:3/0 = 0
1:4/0 = 0
2:4/0 = 0
3:4/0 = 0
4:4/0 = 0
5:4/0 = 0
6:4/0 = 0
7:4/0 = 0
8:4/0 = 0
9:4/0 = 0
10:4/0 = 0
12:4/0 = 0
13:4/0 = 0
1:5/0 = 0
2:5/0 = 0
3:5/0 = 0
4:5/0 = 0
5:5/0 = 0
6:5/0 = 0
7:5/0 = 0
8:5/0 = 0
9:5/0 = 0
10:5/0 = 0
12:5/0 = 0
13:5/0 = 0
12:6/0 = 0
13:6/0 = 0
12:7/0 = 0
13:7/0 = 0
6:9/0 = 0
7:9/0 = 0
8:9/0 = 0
9:9/0 = 0
10:9/0 = 0
11:9/0 = 0
12:9/0 = 0
13:9/0 = 0
6:10/0 = 0
7:10/0 = 0
8:10/0 = 0
9:10/0 = 0
10:10/0 = 0
11:10/0 = 0
12:10/0 = 0
13:10/0 = 0
6:11/0 = 0
7:11/0 = 0
9:11/0 = 0
10:11/0 = 0
12:11/0 = 0
13:11/0 = 0
8:12/0 = 0
9:12/0 = 0
10:12/0 = 0
11:12/0 = 0
6:13/0 = 0
7:13/0 = 0
8:13/0 = 0
9:13/0 = 0
10:13/0 = 0
11:13/0 = 0
12:13/0 = 0
13:13/0 = 0
6:14/0 = 0
7:14/0 = 0
8:14/0 = 0
9:14/0 = 0
10:14/0 = 0
11:14/0 = 0
12:14/0 = 0
13:14/0 = 0
6:15/0 = 0
7:15/0 = 0
8:15/0 = 0
9:15/0 = 0
10:15/0 = 0
11:15/0 = 0
12:15/0 = 0
13:15/0 = 0
11:1/0 = 0
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_u6jqb"]
texture = ExtResource("2_mucy5")
texture_region_size = Vector2i(96, 96)
3:1/0 = 0
3:2/0 = 0
2:2/0 = 0
5:1/0 = 0
5:2/0 = 0
6:2/0 = 0
8:1/0 = 0
8:2/0 = 0
9:1/0 = 0
11:1/0 = 0
12:1/0 = 0
12:2/0 = 0
12:4/0 = 0
12:5/0 = 0
12:6/0 = 0
10:6/0 = 0
10:5/0 = 0
9:5/0 = 0
9:6/0 = 0
7:5/0 = 0
6:5/0 = 0
6:6/0 = 0
7:6/0 = 0
4:6/0 = 0
4:5/0 = 0
3:5/0 = 0
2:5/0 = 0
2:6/0 = 0
3:6/0 = 0
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_wtljp"]
texture = ExtResource("3_u6jqb")
texture_region_size = Vector2i(96, 96)
10:6/0 = 0
6:1/0 = 0
6:2/0 = 0
6:3/0 = 0
6:4/0 = 0
7:2/0 = 0
7:3/0 = 0
11:1/0 = 0
12:1/0 = 0
12:2/0 = 0
12:3/0 = 0
12:4/0 = 0
11:4/0 = 0
9:6/0 = 0
8:6/0 = 0
5:8/0 = 0
5:9/0 = 0
5:10/0 = 0
6:10/0 = 0
7:10/0 = 0
7:9/0 = 0
7:8/0 = 0
6:8/0 = 0
10:8/0 = 0
11:8/0 = 0
12:8/0 = 0
12:9/0 = 0
12:10/0 = 0
11:10/0 = 0
10:10/0 = 0
10:9/0 = 0
11:9/0 = 0
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_evanm"]
texture = ExtResource("1_u6jqb")
texture_region_size = Vector2i(128, 128)
1:1/0 = 0
1:2/0 = 0
1:3/0 = 0
2:1/0 = 0
3:1/0 = 0
3:2/0 = 0
3:3/0 = 0
2:3/0 = 0
5:1/0 = 0
5:2/0 = 0
5:3/0 = 0
6:1/0 = 0
6:2/0 = 0
6:3/0 = 0
7:1/0 = 0
7:2/0 = 0
7:3/0 = 0
9:1/0 = 0
9:3/0 = 0
9:4/0 = 0
11:1/0 = 0
12:1/0 = 0
13:1/0 = 0
9:5/0 = 0
6:7/0 = 0
5:7/0 = 0
5:8/0 = 0
7:8/0 = 0
7:9/0 = 0
6:9/0 = 0
8:9/0 = 0
7:10/0 = 0
5:10/0 = 0
5:11/0 = 0
6:11/0 = 0
8:11/0 = 0
9:11/0 = 0
9:10/0 = 0
9:8/0 = 0
9:7/0 = 0
8:7/0 = 0
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_nsnhs"]
texture = ExtResource("1_u6jqb")
texture_region_size = Vector2i(96, 96)
1:1/0 = 0
2:1/0 = 0
3:1/0 = 0
4:1/0 = 0
5:1/0 = 0
6:1/0 = 0
7:1/0 = 0
8:1/0 = 0
9:1/0 = 0
10:1/0 = 0
12:1/0 = 0
13:1/0 = 0
14:1/0 = 0
15:1/0 = 0
16:1/0 = 0
17:1/0 = 0
18:1/0 = 0
1:2/0 = 0
2:2/0 = 0
3:2/0 = 0
4:2/0 = 0
5:2/0 = 0
6:2/0 = 0
7:2/0 = 0
8:2/0 = 0
9:2/0 = 0
10:2/0 = 0
12:2/0 = 0
13:2/0 = 0
14:2/0 = 0
15:2/0 = 0
16:2/0 = 0
17:2/0 = 0
18:2/0 = 0
1:3/0 = 0
2:3/0 = 0
4:3/0 = 0
5:3/0 = 0
6:3/0 = 0
7:3/0 = 0
8:3/0 = 0
9:3/0 = 0
10:3/0 = 0
1:4/0 = 0
2:4/0 = 0
3:4/0 = 0
4:4/0 = 0
5:4/0 = 0
6:4/0 = 0
7:4/0 = 0
8:4/0 = 0
9:4/0 = 0
10:4/0 = 0
12:4/0 = 0
13:4/0 = 0
1:5/0 = 0
2:5/0 = 0
3:5/0 = 0
4:5/0 = 0
5:5/0 = 0
6:5/0 = 0
7:5/0 = 0
8:5/0 = 0
9:5/0 = 0
10:5/0 = 0
12:5/0 = 0
13:5/0 = 0
12:6/0 = 0
13:6/0 = 0
12:7/0 = 0
13:7/0 = 0
6:9/0 = 0
7:9/0 = 0
8:9/0 = 0
9:9/0 = 0
10:9/0 = 0
11:9/0 = 0
12:9/0 = 0
13:9/0 = 0
6:10/0 = 0
7:10/0 = 0
8:10/0 = 0
9:10/0 = 0
10:10/0 = 0
11:10/0 = 0
12:10/0 = 0
13:10/0 = 0
6:11/0 = 0
7:11/0 = 0
9:11/0 = 0
10:11/0 = 0
12:11/0 = 0
13:11/0 = 0
8:12/0 = 0
9:12/0 = 0
10:12/0 = 0
11:12/0 = 0
6:13/0 = 0
7:13/0 = 0
8:13/0 = 0
9:13/0 = 0
10:13/0 = 0
11:13/0 = 0
12:13/0 = 0
13:13/0 = 0
6:14/0 = 0
7:14/0 = 0
8:14/0 = 0
9:14/0 = 0
10:14/0 = 0
11:14/0 = 0
12:14/0 = 0
13:14/0 = 0
6:15/0 = 0
7:15/0 = 0
8:15/0 = 0
9:15/0 = 0
10:15/0 = 0
11:15/0 = 0
12:15/0 = 0
13:15/0 = 0
[resource]
tile_size = Vector2i(96, 96)
sources/1 = SubResource("TileSetAtlasSource_u6jqb")
sources/2 = SubResource("TileSetAtlasSource_wtljp")
sources/0 = SubResource("TileSetAtlasSource_h7jxu")
sources/3 = SubResource("TileSetAtlasSource_evanm")
sources/4 = SubResource("TileSetAtlasSource_nsnhs")

245
_tileset/pure_tile_set.tres Normal file
View File

@ -0,0 +1,245 @@
[gd_resource type="TileSet" load_steps=5 format=3 uid="uid://bt25n4i5s2bkj"]
[ext_resource type="Texture2D" uid="uid://ntm66vo10u2q" path="res://_asset/ksw/tile/tile.png" id="1_jwfln"]
[ext_resource type="Texture2D" uid="uid://cchtbbig85jcm" path="res://_asset/ksw/tile/tile02.png" id="2_5i20m"]
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_i03by"]
texture = ExtResource("1_jwfln")
texture_region_size = Vector2i(128, 128)
1:1/0 = 0
1:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, -48, 64, -48, 64, 48, 48, 48, 48, 64, -48, 64)
2:1/0 = 0
2:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, -48, 64, -48, 64, 48, -64, 48)
3:1/0 = 0
3:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, -48, 48, -48, 48, 64, -48, 64, -48, 48, -64, 48)
3:2/0 = 0
3:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, -64, 48, -64, 48, 64, -48, 64)
3:3/0 = 0
3:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, -64, 48, -64, 48, 48, -64, 48, -64, -48, -48, -48)
2:3/0 = 0
2:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(64, -48, 64, 48, -64, 48, -64, -48)
1:3/0 = 0
1:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(64, -48, 64, 48, -48, 48, -48, -64, 48, -64, 48, -48)
1:2/0 = 0
1:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 64, -48, -64, 48, -64, 48, 64)
6:1/0 = 0
6:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, -48, 64, -48, 64, 64, -64, 64)
5:2/0 = 0
5:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, -64, 64, -64, 64, 64, -48, 64)
5:1/0 = 0
5:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, -48, 64, -48, 64, 64, -48, 64)
6:2/0 = 0
6:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, -64, 64, -64, 64, 64, -64, 64)
6:3/0 = 0
6:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, -64, 64, -64, 64, 48, -64, 48)
5:3/0 = 0
5:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, -64, 64, -64, 64, 48, -48, 48)
7:3/0 = 0
7:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, -64, 48, -64, 48, 48, -64, 48)
7:2/0 = 0
7:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, -64, 48, -64, 48, 64, -64, 64)
7:1/0 = 0
7:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, -48, 48, -48, 48, 64, -64, 64)
9:1/0 = 0
9:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, -48, 48, -48, 48, 48, -48, 48)
11:1/0 = 0
11:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, -48, 64, -48, 64, 48, -48, 48)
12:1/0 = 0
12:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, -48, 64, -48, 64, 48, -64, 48)
13:1/0 = 0
13:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, -48, 48, -48, 48, 48, -64, 48)
9:3/0 = 0
9:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 64, -48, -48, 48, -48, 48, 64)
9:4/0 = 0
9:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 64, -48, -64, 48, -64, 48, 64)
9:5/0 = 0
9:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 48, -48, -64, 48, -64, 48, 48)
1:4/0 = 0
1:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 48, -48, -48, 64, -48, 64, 48)
2:4/0 = 0
2:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 48, -64, 48, -64, -48, 64, -48, 64, 48, 48, 48, 48, 64, -48, 64)
3:4/0 = 0
3:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, 48, -64, -48, 48, -48, 48, 48)
2:5/0 = 0
2:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 48, -48, -64, 48, -64, 48, 48)
2:6/0 = 0
2:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 64, -48, -48, 48, -48, 48, 64)
2:7/0 = 0
2:7/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, 48, -64, -48, -48, -48, -48, -64, 48, -64, 48, -48, 64, -48, 64, 48)
1:7/0 = 0
1:7/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 48, -48, -48, 64, -48, 64, 48)
3:7/0 = 0
3:7/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, 48, -64, -48, 48, -48, 48, 48)
1:8/0 = 0
1:8/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 64, -48, -48, 48, -48, 48, 64)
1:9/0 = 0
1:9/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 64, -48, -64, 48, -64, 48, -48, 64, -48, 64, 48, 48, 48, 48, 64)
1:10/0 = 0
1:10/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 48, -48, -64, 48, -64, 48, 48)
2:9/0 = 0
2:9/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, 48, -64, -48, 48, -48, 48, 48)
3:9/0 = 0
3:9/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 48, -48, -48, 64, -48, 64, 48)
4:8/0 = 0
4:8/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 64, -48, -48, 48, -48, 48, 64)
4:9/0 = 0
4:9/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 64, -48, 48, -64, 48, -64, -48, -48, -48, -48, -64, 48, -64, 48, 64)
4:10/0 = 0
4:10/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 48, -48, -64, 48, -64, 48, 48)
5:8/0 = 0
5:8/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 48, -48, -64, 48, -64, 48, 48)
5:7/0 = 0
5:7/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 64, -48, -48, 64, -48, 64, 48, 48, 48, 48, 64)
6:7/0 = 0
6:7/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, 48, -64, -48, 48, -48, 48, 48)
8:7/0 = 0
8:7/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 48, -48, -48, 64, -48, 64, 48)
9:7/0 = 0
9:7/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 48, -64, 48, -64, -48, 48, -48, 48, 64, -48, 64)
9:8/0 = 0
9:8/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, -64, 48, -64, 48, 48, -48, 48)
7:8/0 = 0
7:8/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, -48, 48, -48, 48, 64, -48, 64)
7:9/0 = 0
7:9/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, -48, -48, -64, 48, -64, 48, -48, 64, -48, 64, 48, 47.33333, 48, 48, 64, -48, 64, -48, 48, -64, 48, -64, -48)
6:9/0 = 0
6:9/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, -48, 64, -48, 64, 48, -48, 48)
8:9/0 = 0
8:9/0/physics_layer_0/polygon_0/points = PackedVector2Array(48, -48, 47.33333, 48, -64, 48, -64, -48)
7:10/0 = 0
7:10/0/physics_layer_0/polygon_0/points = PackedVector2Array(48, -64, 47.33333, 48, -48, 48, -48, -64)
5:10/0 = 0
5:10/0/physics_layer_0/polygon_0/points = PackedVector2Array(48, -48, 48, 64, -48, 64, -48, -48)
6:11/0 = 0
6:11/0/physics_layer_0/polygon_0/points = PackedVector2Array(48, 48, -64, 48, -64, -48, 48, -48)
8:11/0 = 0
8:11/0/physics_layer_0/polygon_0/points = PackedVector2Array(64, 48, -48, 48, -48, -48, 64, -48)
5:11/0 = 0
5:11/0/physics_layer_0/polygon_0/points = PackedVector2Array(48, -48, 64, -48, 64, 48, -48, 48, -48, -64, 48, -64)
9:11/0 = 0
9:11/0/physics_layer_0/polygon_0/points = PackedVector2Array(48, 48, -64, 48, -64, -48, -48, -48, -48, -64, 48, -64)
9:10/0 = 0
9:10/0/physics_layer_0/polygon_0/points = PackedVector2Array(48, 64, -48, 64, -48, -48, 48, -48)
11:9/0 = 0
11:9/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 64, -48, -64, 64, -64, 64, 64)
11:8/0 = 0
11:8/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 64, -48, -48, 64, -48, 64, 64)
11:10/0 = 0
11:10/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 48, -48, -64, 64, -64, 64, 48)
12:9/0 = 0
12:9/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, 64, -64, -64, 64, -64, 64, 64)
12:8/0 = 0
12:8/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, 64, -64, -48, -48, -48, -48, -64, 64, -64, 64, 64)
12:7/0 = 0
12:7/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 64, -48, -48, 64, -48, 64, 64)
13:7/0 = 0
13:7/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, 64, -64, -48, 64, -48, 64, 64)
14:7/0 = 0
14:7/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, 64, -64, -48, 48, -48, 48, 64)
13:8/0 = 0
13:8/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, 64, -64, -64, 64, -64, 64, 64)
13:9/0 = 0
13:9/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, 64, -64, -64, 64, -64, 64, 64)
13:10/0 = 0
13:10/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, 64, -64, -64, 64, -64, 64, 64)
13:11/0 = 0
13:11/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, -64, 64, -64, 64, 48, -64, 48)
12:10/0 = 0
12:10/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 48, -64, 48, -64, -64, 64, -64, 64, 64, -48, 64)
12:11/0 = 0
12:11/0/physics_layer_0/polygon_0/points = PackedVector2Array(-48, 48, -48, -64, 64, -64, 64, 48)
14:8/0 = 0
14:8/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, 64, -64, -64, 48, -64, 48, -48, 64, -48, 64, 64)
14:9/0 = 0
14:9/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, 64, -64, -64, 64, -64, 64, 64)
14:10/0 = 0
14:10/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, -64, 64, -64, 64, 48, 48, 48, 48, 64, -64, 64)
14:11/0 = 0
14:11/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, -64, 48, -64, 48, 48, -64, 48)
15:9/0 = 0
15:9/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, 64, -64, -64, 48, -64, 48, 64)
15:10/0 = 0
15:10/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, -64, 48, -64, 48, 48, -64, 48)
15:8/0 = 0
15:8/0/physics_layer_0/polygon_0/points = PackedVector2Array(-64, 64, -64, -48, 48, -48, 48, 64)
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_ekrk0"]
texture = ExtResource("2_5i20m")
texture_region_size = Vector2i(128, 128)
1:1/0 = 0
2:1/0 = 0
3:1/0 = 0
4:1/0 = 0
2:2/0 = 0
3:2/0 = 0
2:3/0 = 0
3:3/0 = 0
3:4/0 = 0
3:5/0 = 0
3:6/0 = 0
3:7/0 = 0
3:8/0 = 0
2:8/0 = 0
2:7/0 = 0
2:6/0 = 0
2:5/0 = 0
2:4/0 = 0
1:4/0 = 0
4:4/0 = 0
1:7/0 = 0
4:7/0 = 0
5:7/0 = 0
6:7/0 = 0
7:7/0 = 0
8:7/0 = 0
6:6/0 = 0
7:6/0 = 0
7:8/0 = 0
6:8/0 = 0
6:0/0 = 0
6:1/0 = 0
6:2/0 = 0
6:3/0 = 0
7:2/0 = 0
8:2/0 = 0
9:2/0 = 0
9:3/0 = 0
8:1/0 = 0
9:0/0 = 0
9:1/0 = 0
7:1/0 = 0
11:1/0 = 0
12:1/0 = 0
12:2/0 = 0
11:2/0 = 0
10:2/0 = 0
13:2/0 = 0
11:3/0 = 0
10:4/0 = 0
11:4/0 = 0
12:4/0 = 0
10:5/0 = 0
11:5/0 = 0
12:5/0 = 0
12:6/0 = 0
11:6/0 = 0
10:6/0 = 0
11:7/0 = 0
13:4/0 = 0
14:4/0 = 0
15:4/0 = 0
15:5/0 = 0
15:6/0 = 0
14:6/0 = 0
13:6/0 = 0
13:5/0 = 0
14:5/0 = 0
14:3/0 = 0
14:7/0 = 0
[resource]
tile_size = Vector2i(128, 128)
physics_layer_0/collision_layer = 4
physics_layer_0/collision_mask = 0
sources/3 = SubResource("TileSetAtlasSource_ekrk0")
sources/2 = SubResource("TileSetAtlasSource_i03by")

View File

@ -0,0 +1,3 @@
extends Control
@onready var b_setting: Button = %B_Setting

View File

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

View File

@ -1,5 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://b4ojkr2fq8xjm"]
[gd_scene load_steps=3 format=3 uid="uid://b4ojkr2fq8xjm"]
[ext_resource type="Script" uid="uid://d1gf5wcjkwong" path="res://_ui/main_menu/main_menu.gd" id="1_102h7"]
[ext_resource type="Texture2D" uid="uid://c673bap4b12fx" path="res://icon.svg" id="1_j8fyu"]
[node name="MainMenu" type="Control"]
@ -9,6 +10,7 @@ anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_102h7")
[node name="TextureRect" type="TextureRect" parent="."]
layout_mode = 1
@ -51,6 +53,12 @@ layout_mode = 2
text = "Continue
"
[node name="B_Setting" type="Button" parent="MC_Options/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
text = "Setting
"
[node name="B_Option" type="Button" parent="MC_Options/VBoxContainer"]
layout_mode = 2
text = "Option"

View File

@ -0,0 +1,13 @@
[gd_scene format=3 uid="uid://dlxtqk6hbqu1"]
[node name="AudioSettingPanel" type="MarginContainer"]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="VBoxContainer" type="VBoxContainer" parent="."]
custom_minimum_size = Vector2(400, 0)
layout_mode = 2
size_flags_horizontal = 4

View File

@ -11,6 +11,10 @@ const _DEBUG_TOOL := preload("res://addons/reedcamera/scripts/camera_tools/DeadZ
@export var enabled_follow: bool = true
@export var follow_speed: float = 600.0 # 世界单位 / 秒
@export var follow_lerp := 0.12 # 0~1越大越“跟手”越小越“蔚蓝感”的滞后
@export_subgroup("Follow Dynamic Speed")
@export var min_speed_scale := 0.4 # 贴近死区时
@export var max_speed_scale := 2.0 # 远离死区时
@export var max_offset_ratio := 1.0 # offset 达到 1 个 dead_zone 时为最大速率
##TODO:后续添加一下Runtime的修改逻辑
@export_group("Debug")
@ -110,9 +114,20 @@ func update_follow(delta: float) -> void:
_current_state = State.CHASING
#var move_dir := offset.normalized()
#var world_velocity := (move_dir * follow_speed) / cam.zoom
var offset_len := offset.length()
var dead_len := dead_half.length()
# 0~1 的距离比例
var t := clamp(offset_len / (dead_len * max_offset_ratio), 0.0, 1.0)
# 距离越远,速度越快
var speed_scale := lerp(min_speed_scale, max_speed_scale, t)
var move_dir := offset.normalized()
var world_velocity := (move_dir * follow_speed) / cam.zoom
##如果存在move_dir则我们认为相机需要chasing player
var world_velocity : Vector2 = (move_dir * follow_speed * speed_scale) / cam.zoom
var desired_pos := _final_position + world_velocity * delta

View File

@ -1,17 +1,42 @@
[gd_scene load_steps=2 format=3 uid="uid://ddwoxlqluxiq5"]
[gd_scene load_steps=4 format=3 uid="uid://ddwoxlqluxiq5"]
[ext_resource type="Script" uid="uid://bvxgviq7l64ck" path="res://addons/reedcomponent/grap_hook/garpping_hook_v_2.gd" id="1_jrg4x"]
[sub_resource type="CircleShape2D" id="CircleShape2D_2bmkq"]
[sub_resource type="CircleShape2D" id="CircleShape2D_jrg4x"]
radius = 5.0990195
[node name="GarppingHookV2" type="Node2D"]
script = ExtResource("1_jrg4x")
min_length = 900.0
max_length = 1200.0
stretching_speed = 5000.0
max_speed = 5600.0
retract_speed = 7000.0
[node name="Line2D" type="Line2D" parent="."]
unique_name_in_owner = true
points = PackedVector2Array(0, 0, 80, 0)
width = 8.0
width = 50.0
[node name="ShapeCast2D" type="ShapeCast2D" parent="."]
unique_name_in_owner = true
shape = SubResource("CircleShape2D_2bmkq")
target_position = Vector2(80, 0)
collision_mask = 20
[node name="RayCast2D" type="RayCast2D" parent="."]
unique_name_in_owner = true
target_position = Vector2(80, 0)
collision_mask = 36
collision_mask = 20
collide_with_areas = true
[node name="TipDetector" type="Area2D" parent="."]
position = Vector2(80, 0)
collision_layer = 0
collision_mask = 32
[node name="CollisionShape2D" type="CollisionShape2D" parent="TipDetector"]
shape = SubResource("CircleShape2D_jrg4x")
debug_color = Color(0, 0.6, 0.69803923, 0)

View File

@ -1,24 +1,34 @@
class_name Hook
extends Node2D
@onready var line_2d: Line2D = %Line2D
@onready var shape_cast_2d: ShapeCast2D = %ShapeCast2D
@onready var tip_detector: Area2D = $TipDetector
## ================
## Export Field
## ================
##钩爪最短长度
@export var min_length := 140.0
##钩爪最大长度
@export var max_length := 200.0
##钩爪伸出速度
@export var stretching_speed: float = 1400.0
## 最大速度上限
@export var max_speed: float = 800.0
@export_category("Hook Retract")
@export var retract_speed: float = 1800.0
@onready var line_2d: Line2D = %Line2D
@onready var ray: RayCast2D = %RayCast2D
## 钩爪当前速度
var _current_velocity: Vector2 = Vector2.ZERO
var _tween: Tween
const GRAPABLE_GROUP = &"GRAPABLE"
signal stretching_finished(reach_limit: bool, anchor_node: Node2D)
## 钩爪击中物体信号target 是被击中的物体hit_pos 是击中点世界坐标hook 是钩爪实例
signal hook_hit(target: Node2D, hit_pos: Vector2, hook: Hook)
## ================
## Private Field
@ -37,8 +47,8 @@ var _dir_id: int = -1
# =================
func _ready() -> void:
ray.enabled = true
ray.target_position = Vector2.ZERO
shape_cast_2d.enabled = true
shape_cast_2d.target_position = Vector2.ZERO
## 初始化
func init(hook_comp: SpawnHookComponet, reset_to_target: bool) -> void:
@ -55,6 +65,7 @@ func start_stretching(direction: Vector2) -> void:
_cached_cancel = false
_stretching_dir = direction.normalized()
_current_length = 0.0
_current_velocity = Vector2.ZERO # 重置速度
_dir_id = _get_direction_id(direction,8)
@ -66,11 +77,21 @@ func end_stretching(force_end: bool = false) -> bool:
_is_stretching = false
_stretching_dir = Vector2.ZERO
_current_velocity = Vector2.ZERO # 重置速度
return true
func is_stretching() -> bool:
return _is_stretching
## 获取当前飞行方向(可被外部复写)
func get_stretching_dir() -> Vector2:
return _stretching_dir.normalized()
## 设置飞行方向(供外部物体修改)
func set_stretching_dir(dir: Vector2) -> void:
_stretching_dir = dir.normalized()
_dir_id = _get_direction_id(_stretching_dir, 8)
# =================
# Update
# =================
@ -86,27 +107,51 @@ func _process(_delta: float) -> void:
# Core Logic
# =================
func _update_stretching(delta: float) -> void:
# 先嘗試推進
var next_length := _current_length + stretching_speed * delta
# 检测前端点的吸引力 (direction, strength)
var attract_config := _get_attraction_at(global_position + _current_velocity.normalized() * _current_length)
# 初始速度(沿当前方向持续向前)
if _current_velocity == Vector2.ZERO:
_current_velocity = get_stretching_dir() * stretching_speed
# 应用吸引力作为加速度
if attract_config.strength > 0:
var acceleration : Vector2 = attract_config.dir * attract_config.strength
_current_velocity += acceleration * delta
# 限制最大速度
if _current_velocity.length() > max_speed:
_current_velocity = _current_velocity.normalized() * max_speed
# 基于更新后的速度预测“下一帧累计长度”
var velocity_dir := _current_velocity.normalized()
var velocity_mag := _current_velocity.length()
var next_length := _current_length + velocity_mag * delta
next_length = min(next_length, max_length)
# 先用「下一幀長度」做 Ray
ray.target_position = _stretching_dir * next_length
ray.force_raycast_update()
# 预测末端位置:起点 + 方向 * 累计长度
var predicted_pos := global_position + velocity_dir * next_length
tip_detector.global_position = predicted_pos
# ShapeCast2D 也应该射到"累计长度"
shape_cast_2d.target_position = velocity_dir * next_length
shape_cast_2d.force_shapecast_update()
# ===== 命中檢測(最高優先)=====
if ray.is_colliding():
var collider := ray.get_collider()
if shape_cast_2d.is_colliding():
var collider := shape_cast_2d.get_collider(0)
if collider is Node2D and collider.is_in_group(GRAPABLE_GROUP):
var hit_pos := ray.get_collision_point()
var hit_pos := shape_cast_2d.get_collision_point(0)
_current_length = global_position.distance_to(hit_pos)
ray.target_position = _stretching_dir * _current_length
shape_cast_2d.target_position = velocity_dir * _current_length
_handle_hit(collider as Node2D, hit_pos)
return
# ===== 沒命中,才正式推進 =====
# ===== 命中,才正式推進 =====
_current_length = next_length
# 取消邏輯
@ -120,22 +165,52 @@ func _update_stretching(delta: float) -> void:
stretching_finished.emit(true, null)
end_stretching(true)
## 在指定位置检测吸引力,返回 {"dir": Vector2, "strength": float}
func _get_attraction_at(pos: Vector2) -> Dictionary:
var total_force := Vector2.ZERO
# 检测 Areas
for area in tip_detector.get_overlapping_areas():
if area is Node2D and area.has_method("get_attraction_force"):
total_force += area.get_attraction_force(pos)
elif area.owner is Node2D and area.owner.has_method("get_attraction_force"):
total_force += area.owner.get_attraction_force(pos)
# 检测 Bodies
for body in tip_detector.get_overlapping_bodies():
if body is Node2D and body.has_method("get_attraction_force"):
total_force += body.get_attraction_force(pos)
elif body.owner is Node2D and body.owner.has_method("get_attraction_force"):
total_force += body.owner.get_attraction_force(pos)
# 返回 {"dir": direction, "strength": magnitude}
if total_force != Vector2.ZERO:
return {"dir": total_force.normalized(), "strength": total_force.length()}
return {"dir": Vector2.ZERO, "strength": 0.0}
func _handle_hit(target: Node2D, hit_pos: Vector2) -> void:
_is_stretching = false
_stretching_dir = Vector2.ZERO
_current_velocity = Vector2.ZERO # 重置速度
ray.target_position = to_local(hit_pos)
shape_cast_2d.target_position = to_local(hit_pos)
# 如果 target 有 on_hook_hit 方法,调用它(传入钩爪实例)
if target.has_method(&"on_hook_hit"):
target.on_hook_hit(hit_pos, self)
var reach_max := is_equal_approx(_current_length, max_length)
var anchor := _create_anchor_on_node(target, hit_pos)
stretching_finished.emit(reach_max, anchor)
hook_hit.emit(target, hit_pos, self)
## 釋放鉤爪(清理 Anchor 與狀態)
func _release_hook() -> void:
# 1. 停止拉伸(保險)
_is_stretching = false
_stretching_dir = Vector2.ZERO
_current_velocity = Vector2.ZERO # 重置速度
_cached_cancel = false
_current_length = 0.0
@ -146,8 +221,8 @@ func _release_hook() -> void:
_anchor.queue_free()
_anchor = null
# 3. 重置 Ray 與 Line視覺清乾淨
ray.target_position = Vector2.ZERO
# 3. 重置 ShapeCast2D 與 Line視覺清乾淨
shape_cast_2d.target_position = Vector2.ZERO
_update_line()
func release_hook_with_transition(has_trans: bool) -> void:
@ -170,7 +245,7 @@ func release_hook_with_transition(has_trans: bool) -> void:
_anchor = null
# 当前末端位置(本地坐标)
var start_pos: Vector2 = ray.target_position
var start_pos: Vector2 = shape_cast_2d.target_position
var distance := start_pos.length()
if distance <= 0.001:
@ -188,7 +263,7 @@ func release_hook_with_transition(has_trans: bool) -> void:
_tween.set_ease(Tween.EASE_IN)
_tween.tween_property(
ray,
shape_cast_2d,
"target_position",
Vector2.ZERO,
duration
@ -201,9 +276,9 @@ func release_hook_with_transition(has_trans: bool) -> void:
func _update_line() -> void:
if _anchor and is_instance_valid(_anchor):
# 关键:锚点是世界坐标固定的,把它换算到 Hook 的本地坐标
ray.target_position = to_local(_anchor.global_position)
shape_cast_2d.target_position = to_local(_anchor.global_position)
line_2d.set_point_position(1, ray.target_position)
line_2d.set_point_position(1, shape_cast_2d.target_position)
func _create_anchor_on_node(target: Node2D, hit_global_pos: Vector2) -> Node2D:
if _anchor and is_instance_valid(_anchor):

View File

@ -29,12 +29,14 @@ class_name LocomotionComponent extends ComponentBase
##空中控制乘量,在空中移动时修改
@export var air_control_mult : float = .65
#基础的乘量对所有Character相同
const GRAVITY_BASIC_MULT_FACTOR : float = 1.8
const GRAVITY_BASIC_MULT_FACTOR : float = 18
#下坠速度和最大下坠速度的阈值,超过了这个阈值会开启下坠速度修正,主要取决于设备的刷新率固写死。
const FALL_SPEED_EXCEED_TOLERANCE_THRESHOLD = 40
@export_category("Locomotion Properties")
@export_subgroup("Move")
##如果为true则使用加速度逐渐达到目标速度如果为false则直接设置速度
@export var use_acceleration: bool = true
##存在輸入時,向最大移動輸入運動的加速度
@export var run_accel : float = 1200
##不存在輸入時向Vector.ZERO運動的加速度
@ -125,11 +127,15 @@ func _update_movement(delta : float) -> void:
var applyed_air_control = 1 if characterbody.is_on_floor() else air_control_mult
var target_move_speed = move_speed_max * input_dir
characterbody.velocity.x = speed_approach(
characterbody.velocity.x,
target_move_speed,
applyed_air_control * accel * delta
)
if use_acceleration:
characterbody.velocity.x = speed_approach(
characterbody.velocity.x,
target_move_speed,
applyed_air_control * accel * delta
)
else:
# 直接设置速度,无加速度
characterbody.velocity.x = target_move_speed
#检测是否这帧开始了移动
_check_is_start_move()

View File

@ -54,52 +54,10 @@ func _bind_quick_trigger() -> void:
func(...args):
_on_trigger_fired(st, args)
)
#if qt is PropIDSceneTrigger:
#_bind_prop_id_trigger(qt)
#elif qt is NodePathSceneTrigger:
#_bind_node_path_trigger(qt)
### 通过Prop id来绑定signal
#func _bind_prop_id_trigger(trigger: PropIDSceneTrigger) -> void:
#var prop : Node = _props.get(trigger.prop_id).get_parent()
#if prop == null:
#return
#
#var s: StringName = trigger.monitor_signal
#if not prop.has_signal(s):
#push_error("Prop has no signal: %s" % trigger.monitor_signal)
#return
#
#prop.connect(
#trigger.monitor_signal,
#func(...args):
#_on_trigger_fired(trigger, args)
#)
#
### 通过NodePath来绑定signal
#func _bind_node_path_trigger(trigger: NodePathSceneTrigger) -> void:
#if trigger.path.is_empty():
#return
#
#var n : Node = self.get_node_or_null(trigger.path)
#
#if n == null:
#return
#
#var s: StringName = trigger.monitor_signal
#if not n.has_signal(s):
#push_error("Prop has no signal: %s" % trigger.monitor_signal)
#return
#
#n.connect(
#trigger.monitor_signal,
#func(...args):
#_on_trigger_fired(trigger, args)
#)
## 当信号触发
func _on_trigger_fired(trigger: SceneTrigger, signal_args: Array) -> void:
if not trigger.can_trigger(signal_args):
if not trigger.can_trigger(signal_args,self):
return
for i in trigger.trigger_effect_pairs:
@ -115,13 +73,21 @@ func _on_trigger_fired(trigger: SceneTrigger, signal_args: Array) -> void:
for j in exs:
var ex := j as SceneTriggerEffect
ex.apply_effect(t)
#var target_act_id: int = trigger.target_act_id
#var trans_overwrite: int = trigger.trans_overwrite
#
#if target_act_id < 0:
#return
#
#_act_manager.switch_act_with_id(target_act_id,trans_overwrite)
## =============================
## External API
## =============================
func switch_act_with_id(id: int,trans_overwrite:int = 0) -> void:
_act_manager.switch_act_with_id(id,trans_overwrite)
## 外部快速获取Act Manager
func get_act_manager() -> ActManager:
return _act_manager
## 外部快速获取scene root
func get_scene_root() -> ReedScene:
return _scene if _scene else get_parent()
## 外部快速获取获取props映射
func get_props() -> Dictionary:
return _props

View File

@ -6,4 +6,4 @@ class_name SceneGuard
extends Resource
@abstract
func check(signal_args: Array) -> bool
func check(signal_args: Array, manager: SceneManager) -> bool

View File

@ -0,0 +1,6 @@
class_name STR_Autoload extends SceneTriggerRegister
@export var autoload_name: StringName
func get_register(owner: Object) -> Node:
return owner.get_tree().root.get_node_or_null("/root/%s" % autoload_name)

View File

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

View File

@ -0,0 +1,8 @@
class_name STT_NodePath extends SceneTriggerTarget
@export var node_path : NodePath
func get_effect_target(owner: Node) -> Object:
if owner:
return owner.get_node_or_null(node_path)
return null

View File

@ -0,0 +1 @@
uid://5jmi0wcn1634

View File

@ -3,15 +3,16 @@ class_name SceneTrigger extends Resource
##绑定哪个Node的哪个函数作为此Trigger的Register。
@export var trigger_register_conifg: SceneTriggerRegister
##Guard是一个保护项如果某个Trigger触发后但因为某些条件并不想被执行可以使用guard进行保护
@export var guards: Array[SceneGuard]
@export var guard: SceneGuard
##当某个Trigger被激活时可以应用任意多个EffectEffect会按序执行列
@export var trigger_effect_pairs: Array[SceneTriggerEffectPair]
var _owner: Node
func can_trigger(args: Array) -> bool:
for g in guards:
if not g.check(args):
return false
func can_trigger(args: Array,scene_manager: SceneManager) -> bool:
if not guard:
return true
if not guard.check(args, scene_manager):
return false
return true

View File

@ -11,7 +11,7 @@ config_version=5
[application]
config/name="godot-plateformer"
run/main_scene="uid://3vc8ojbiyy5w"
run/main_scene="uid://x041oerqe1iu"
config/features=PackedStringArray("4.5", "Forward Plus")
config/icon="res://icon.svg"
@ -24,10 +24,8 @@ ReedCameraSystem="*res://addons/reedcamera/scripts/ReedCameraGlobal.gd"
[display]
window/size/viewport_width=640
window/size/viewport_height=360
window/size/window_width_override=1920
window/size/window_height_override=1080
window/size/viewport_width=1920
window/size/viewport_height=1080
window/stretch/mode="canvas_items"
[editor_plugins]
@ -37,7 +35,9 @@ enabled=PackedStringArray("res://addons/reedcamera/plugin.cfg", "res://addons/re
[file_customization]
folder_colors={
"res://_shared/": "pink"
"res://__settings/": "red",
"res://_shared/": "pink",
"res://_tileset/": "green"
}
[global_group]
@ -45,6 +45,7 @@ folder_colors={
PLAYER="玩家分组,其下只存在玩家控制器"
GRAPABLE="進入該分組的Collision視爲可以被玩家抓握"
PLAYER_RESPAWN="所有的PlayerRespawnPoint的绑定Group"
ROCK_BREAK="Can break fragile rock."
[input]
@ -95,4 +96,4 @@ grap_hook={
2d_physics/layer_3="Environment"
2d_physics/layer_4="Damage"
2d_physics/layer_5="Collectable"
2d_physics/layer_6="OneWayPlateform"
2d_physics/layer_6="Hook_Attract"