暗物质球版本1
This commit is contained in:
parent
0c4300d2ec
commit
c17031e029
|
|
@ -1,11 +1,11 @@
|
|||
extends Node2D
|
||||
|
||||
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_S2.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_S6.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"]
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -8,3 +8,4 @@ editor_description = "此类在检测到玩家时会发出signal,可以与其
|
|||
collision_layer = 0
|
||||
collision_mask = 2
|
||||
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://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"]
|
||||
texture = ExtResource("1_ln1fl")
|
||||
|
|
@ -74,6 +76,17 @@ texture_region_size = Vector2i(96, 96)
|
|||
3: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]
|
||||
tile_size = Vector2i(96, 96)
|
||||
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="."]
|
||||
unique_name_in_owner = true
|
||||
target_position = Vector2(80, 0)
|
||||
collision_mask = 36
|
||||
collision_mask = 20
|
||||
collide_with_areas = true
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ var _tween: Tween
|
|||
const GRAPABLE_GROUP = &"GRAPABLE"
|
||||
|
||||
signal stretching_finished(reach_limit: bool, anchor_node: Node2D)
|
||||
## 钩爪击中物体信号,target 是被击中的物体,hit_pos 是击中点世界坐标
|
||||
signal hook_hit(target: Node2D, hit_pos: Vector2)
|
||||
## 钩爪击中物体信号,target 是被击中的物体,hit_pos 是击中点世界坐标,hook 是钩爪实例
|
||||
signal hook_hit(target: Node2D, hit_pos: Vector2, hook: Hook)
|
||||
|
||||
## ================
|
||||
## Private Field
|
||||
|
|
@ -73,6 +73,15 @@ func end_stretching(force_end: bool = false) -> bool:
|
|||
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
|
||||
# =================
|
||||
|
|
@ -93,8 +102,11 @@ func _update_stretching(delta: float) -> void:
|
|||
var next_length := _current_length + stretching_speed * delta
|
||||
next_length = min(next_length, max_length)
|
||||
|
||||
# 使用 getter 获取当前方向(允许外部复写)
|
||||
var current_dir := get_stretching_dir()
|
||||
|
||||
# 先用「下一幀長度」做 Ray
|
||||
ray.target_position = _stretching_dir * next_length
|
||||
ray.target_position = current_dir * next_length
|
||||
ray.force_raycast_update()
|
||||
|
||||
# ===== 命中檢測(最高優先)=====
|
||||
|
|
@ -104,7 +116,7 @@ func _update_stretching(delta: float) -> void:
|
|||
var hit_pos := ray.get_collision_point()
|
||||
|
||||
_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)
|
||||
return
|
||||
|
||||
|
|
@ -128,17 +140,15 @@ func _handle_hit(target: Node2D, hit_pos: Vector2) -> void:
|
|||
|
||||
ray.target_position = to_local(hit_pos)
|
||||
|
||||
# 如果 target 有 on_hook_hit 方法,调用它
|
||||
# 如果 target 有 on_hook_hit 方法,调用它(传入钩爪实例)
|
||||
if target.has_method(&"on_hook_hit"):
|
||||
target.on_hook_hit(hit_pos)
|
||||
|
||||
if target.owner.has_method(&"on_hook_hit"):
|
||||
target.owner.on_hook_hit(hit_pos)
|
||||
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:
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@ enabled=PackedStringArray("res://addons/reedcamera/plugin.cfg", "res://addons/re
|
|||
[file_customization]
|
||||
|
||||
folder_colors={
|
||||
"res://_shared/": "pink"
|
||||
"res://_shared/": "pink",
|
||||
"res://_tileset/": "green"
|
||||
}
|
||||
|
||||
[global_group]
|
||||
|
|
@ -96,4 +97,3 @@ grap_hook={
|
|||
2d_physics/layer_3="Environment"
|
||||
2d_physics/layer_4="Damage"
|
||||
2d_physics/layer_5="Collectable"
|
||||
2d_physics/layer_6="OneWayPlateform"
|
||||
|
|
|
|||
Loading…
Reference in New Issue