Merge branch 'main' of http://47.99.99.211:3000/ReedZhu/godot-plateformer
This commit is contained in:
commit
7d4dc68196
|
|
@ -1,11 +1,11 @@
|
||||||
extends Node2D
|
extends Node2D
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
#$L0_S0.switch_act_by_id(1)
|
$L0_S0.switch_act_by_id(1)
|
||||||
#$L1_S1.switch_act_by_id(1)
|
#$L1_S1.switch_act_by_id(1)
|
||||||
#$L1_S2.switch_act_by_id(1)
|
#$L1_S2.switch_act_by_id(1)
|
||||||
#$L1_S3.switch_act_by_id(1)
|
#$L1_S3.switch_act_by_id(1)
|
||||||
$L1_S4.switch_act_by_id(1)
|
#$L1_S4.switch_act_by_id(1)
|
||||||
#$L1_S5.switch_act_by_id(1)
|
#$L1_S5.switch_act_by_id(1)
|
||||||
#$L1_S6.switch_act_by_id(1)
|
#$L1_S6.switch_act_by_id(1)
|
||||||
#$L1_S7.switch_act_by_id(1)
|
#$L1_S7.switch_act_by_id(1)
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,7 @@ release_distance = 20.0
|
||||||
[node name="Dash" type="LimboState" parent="PlayerHSM/Normal"]
|
[node name="Dash" type="LimboState" parent="PlayerHSM/Normal"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
script = ExtResource("12_8nsdm")
|
script = ExtResource("12_8nsdm")
|
||||||
|
dash_time = 1.0
|
||||||
|
|
||||||
[node name="Dead" type="LimboState" parent="PlayerHSM"]
|
[node name="Dead" type="LimboState" parent="PlayerHSM"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ func _setup() -> void:
|
||||||
|
|
||||||
func _init_handler() -> void:
|
func _init_handler() -> void:
|
||||||
self.add_event_handler(&"trigger_dash",_handler_trigger_dash) ##处理Dash输入
|
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_climb",_handler_trigger_climb) ##处理瞬时的climb
|
||||||
self.add_event_handler(&"trigger_grap_hook",_handler_grap_hook) ##处理grap hook 的輸入
|
self.add_event_handler(&"trigger_grap_hook",_handler_grap_hook) ##处理grap hook 的輸入
|
||||||
|
|
||||||
|
|
@ -65,10 +66,18 @@ func _handler_trigger_dash() -> bool:
|
||||||
#如果当前无法Dash,则返回
|
#如果当前无法Dash,则返回
|
||||||
if not agent.locomotion_comp.get_can_dash():
|
if not agent.locomotion_comp.get_can_dash():
|
||||||
return false
|
return false
|
||||||
|
|
||||||
if get_root().blackboard.get_var(&"is_dashing",false):
|
if get_root().blackboard.get_var(&"is_dashing",false):
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
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")
|
self.dispatch(&"want_to_dash")
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,3 +8,4 @@ editor_description = "此类在检测到玩家时会发出signal,可以与其
|
||||||
collision_layer = 0
|
collision_layer = 0
|
||||||
collision_mask = 2
|
collision_mask = 2
|
||||||
script = ExtResource("1_qrafk")
|
script = ExtResource("1_qrafk")
|
||||||
|
debug_print = true
|
||||||
|
|
|
||||||
|
|
@ -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")
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
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 _on_player_collected(body:CharacterBody2D) -> void:
|
||||||
|
if body is Player:
|
||||||
|
body.hsm.dispatch(&"trigger_external_dash")
|
||||||
|
change_state(State.COLLECTED)
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://c8a7gs0h2h6vn
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
[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")
|
||||||
|
|
||||||
|
[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 = 16
|
||||||
|
collision_mask = 0
|
||||||
|
|
||||||
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="HookAttractVolumn"]
|
||||||
|
shape = SubResource("CircleShape2D_8vsnl")
|
||||||
|
debug_color = Color(1, 0, 0.14509805, 0)
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,6 +1,8 @@
|
||||||
[gd_resource type="TileSet" load_steps=3 format=3 uid="uid://cup1q1upvp18h"]
|
[gd_resource type="TileSet" load_steps=7 format=3 uid="uid://cup1q1upvp18h"]
|
||||||
|
|
||||||
[ext_resource type="Texture2D" uid="uid://7psxuet3jk1p" path="res://_asset/ksw/basicTile.png" id="1_ln1fl"]
|
[ext_resource type="Texture2D" uid="uid://7psxuet3jk1p" path="res://_asset/ksw/basicTile.png" id="1_ln1fl"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://dd622t4mw5vva" path="res://_asset/ksw/basicTile01.png" id="2_mucy5"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://cwet2kw1mngmf" path="res://_asset/ksw/basicTile02.png" id="3_u6jqb"]
|
||||||
|
|
||||||
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_ln1fl"]
|
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_ln1fl"]
|
||||||
texture = ExtResource("1_ln1fl")
|
texture = ExtResource("1_ln1fl")
|
||||||
|
|
@ -74,6 +76,17 @@ texture_region_size = Vector2i(96, 96)
|
||||||
3:4/0 = 0
|
3:4/0 = 0
|
||||||
1:4/0 = 0
|
1:4/0 = 0
|
||||||
|
|
||||||
|
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_u6jqb"]
|
||||||
|
texture = ExtResource("2_mucy5")
|
||||||
|
texture_region_size = Vector2i(96, 96)
|
||||||
|
|
||||||
|
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_wtljp"]
|
||||||
|
texture = ExtResource("3_u6jqb")
|
||||||
|
texture_region_size = Vector2i(96, 96)
|
||||||
|
10:6/0 = 0
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
tile_size = Vector2i(96, 96)
|
tile_size = Vector2i(96, 96)
|
||||||
sources/0 = SubResource("TileSetAtlasSource_ln1fl")
|
sources/0 = SubResource("TileSetAtlasSource_ln1fl")
|
||||||
|
sources/1 = SubResource("TileSetAtlasSource_u6jqb")
|
||||||
|
sources/2 = SubResource("TileSetAtlasSource_wtljp")
|
||||||
|
|
|
||||||
|
|
@ -13,5 +13,5 @@ width = 8.0
|
||||||
[node name="RayCast2D" type="RayCast2D" parent="."]
|
[node name="RayCast2D" type="RayCast2D" parent="."]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
target_position = Vector2(80, 0)
|
target_position = Vector2(80, 0)
|
||||||
collision_mask = 36
|
collision_mask = 20
|
||||||
collide_with_areas = true
|
collide_with_areas = true
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@ var _tween: Tween
|
||||||
const GRAPABLE_GROUP = &"GRAPABLE"
|
const GRAPABLE_GROUP = &"GRAPABLE"
|
||||||
|
|
||||||
signal stretching_finished(reach_limit: bool, anchor_node: Node2D)
|
signal stretching_finished(reach_limit: bool, anchor_node: Node2D)
|
||||||
## 钩爪击中物体信号,target 是被击中的物体,hit_pos 是击中点世界坐标
|
## 钩爪击中物体信号,target 是被击中的物体,hit_pos 是击中点世界坐标,hook 是钩爪实例
|
||||||
signal hook_hit(target: Node2D, hit_pos: Vector2)
|
signal hook_hit(target: Node2D, hit_pos: Vector2, hook: Hook)
|
||||||
|
|
||||||
## ================
|
## ================
|
||||||
## Private Field
|
## Private Field
|
||||||
|
|
@ -73,6 +73,15 @@ func end_stretching(force_end: bool = false) -> bool:
|
||||||
func is_stretching() -> bool:
|
func is_stretching() -> bool:
|
||||||
return _is_stretching
|
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
|
# Update
|
||||||
# =================
|
# =================
|
||||||
|
|
@ -93,8 +102,11 @@ func _update_stretching(delta: float) -> void:
|
||||||
var next_length := _current_length + stretching_speed * delta
|
var next_length := _current_length + stretching_speed * delta
|
||||||
next_length = min(next_length, max_length)
|
next_length = min(next_length, max_length)
|
||||||
|
|
||||||
|
# 使用 getter 获取当前方向(允许外部复写)
|
||||||
|
var current_dir := get_stretching_dir()
|
||||||
|
|
||||||
# 先用「下一幀長度」做 Ray
|
# 先用「下一幀長度」做 Ray
|
||||||
ray.target_position = _stretching_dir * next_length
|
ray.target_position = current_dir * next_length
|
||||||
ray.force_raycast_update()
|
ray.force_raycast_update()
|
||||||
|
|
||||||
# ===== 命中檢測(最高優先)=====
|
# ===== 命中檢測(最高優先)=====
|
||||||
|
|
@ -104,7 +116,7 @@ func _update_stretching(delta: float) -> void:
|
||||||
var hit_pos := ray.get_collision_point()
|
var hit_pos := ray.get_collision_point()
|
||||||
|
|
||||||
_current_length = global_position.distance_to(hit_pos)
|
_current_length = global_position.distance_to(hit_pos)
|
||||||
ray.target_position = _stretching_dir * _current_length
|
ray.target_position = current_dir * _current_length
|
||||||
_handle_hit(collider as Node2D, hit_pos)
|
_handle_hit(collider as Node2D, hit_pos)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -128,17 +140,15 @@ func _handle_hit(target: Node2D, hit_pos: Vector2) -> void:
|
||||||
|
|
||||||
ray.target_position = to_local(hit_pos)
|
ray.target_position = to_local(hit_pos)
|
||||||
|
|
||||||
# 如果 target 有 on_hook_hit 方法,调用它
|
# 如果 target 有 on_hook_hit 方法,调用它(传入钩爪实例)
|
||||||
if target.has_method(&"on_hook_hit"):
|
if target.has_method(&"on_hook_hit"):
|
||||||
target.on_hook_hit(hit_pos)
|
target.on_hook_hit(hit_pos, self)
|
||||||
|
|
||||||
if target.owner.has_method(&"on_hook_hit"):
|
|
||||||
target.owner.on_hook_hit(hit_pos)
|
|
||||||
|
|
||||||
var reach_max := is_equal_approx(_current_length, max_length)
|
var reach_max := is_equal_approx(_current_length, max_length)
|
||||||
var anchor := _create_anchor_on_node(target, hit_pos)
|
var anchor := _create_anchor_on_node(target, hit_pos)
|
||||||
|
|
||||||
stretching_finished.emit(reach_max, anchor)
|
stretching_finished.emit(reach_max, anchor)
|
||||||
|
hook_hit.emit(target, hit_pos, self)
|
||||||
|
|
||||||
## 釋放鉤爪(清理 Anchor 與狀態)
|
## 釋放鉤爪(清理 Anchor 與狀態)
|
||||||
func _release_hook() -> void:
|
func _release_hook() -> void:
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,8 @@ enabled=PackedStringArray("res://addons/reedcamera/plugin.cfg", "res://addons/re
|
||||||
[file_customization]
|
[file_customization]
|
||||||
|
|
||||||
folder_colors={
|
folder_colors={
|
||||||
"res://_shared/": "pink"
|
"res://_shared/": "pink",
|
||||||
|
"res://_tileset/": "green"
|
||||||
}
|
}
|
||||||
|
|
||||||
[global_group]
|
[global_group]
|
||||||
|
|
@ -96,4 +97,3 @@ grap_hook={
|
||||||
2d_physics/layer_3="Environment"
|
2d_physics/layer_3="Environment"
|
||||||
2d_physics/layer_4="Damage"
|
2d_physics/layer_4="Damage"
|
||||||
2d_physics/layer_5="Collectable"
|
2d_physics/layer_5="Collectable"
|
||||||
2d_physics/layer_6="OneWayPlateform"
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue