暗物质球版本2
This commit is contained in:
parent
c17031e029
commit
4e632582cf
Binary file not shown.
|
After Width: | Height: | Size: 85 KiB |
|
|
@ -0,0 +1,40 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cw1lcd672mq87"
|
||||||
|
path="res://.godot/imported/未命名作品(3).png-5152e47ab8192492e0d911592bc8c8f5.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://_asset/ksw/未命名作品(3).png"
|
||||||
|
dest_files=["res://.godot/imported/未命名作品(3).png-5152e47ab8192492e0d911592bc8c8f5.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
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
[gd_scene load_steps=18 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="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"]
|
[ext_resource type="PackedScene" uid="uid://cvqehvdjpoar4" path="res://_player/player_controller.tscn" id="2_x2i0j"]
|
||||||
|
|
@ -14,26 +14,6 @@
|
||||||
[ext_resource type="PackedScene" uid="uid://2d457ndb7toe" path="res://_scene/level1/l1_s8.tscn" id="11_ktxjv"]
|
[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://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"]
|
[ext_resource type="PackedScene" uid="uid://dsw3o2bhc8bve" path="res://_scene/level1/l1_s10.tscn" id="13_53pmm"]
|
||||||
[ext_resource type="Script" uid="uid://c5in610cunjn2" path="res://_game/water_warp_controller.gd" id="15_jibn5"]
|
|
||||||
[ext_resource type="Shader" uid="uid://ccpo4346to8ka" path="res://_shader/ripple2.gdshader" id="16_ef7py"]
|
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_5vsgs"]
|
|
||||||
shader = ExtResource("16_ef7py")
|
|
||||||
shader_parameter/debug_show = false
|
|
||||||
shader_parameter/obj_uv = Vector2(0.5, 0.5)
|
|
||||||
shader_parameter/obj_dir = Vector2(1, 0)
|
|
||||||
shader_parameter/obj_speed = 1.0
|
|
||||||
shader_parameter/lane_half_width = 0.085
|
|
||||||
shader_parameter/edge_width = 0.04
|
|
||||||
shader_parameter/trail_length = 0.55
|
|
||||||
shader_parameter/push_strength = 0.075
|
|
||||||
shader_parameter/drag_strength = 0.045
|
|
||||||
shader_parameter/suck_strength = 0.03
|
|
||||||
shader_parameter/curl_strength = 0.07
|
|
||||||
shader_parameter/foam_strength = 0.45
|
|
||||||
shader_parameter/noise_scale = 3.5
|
|
||||||
shader_parameter/noise_advect = 0.5
|
|
||||||
shader_parameter/chroma_shift = 0.6
|
|
||||||
|
|
||||||
[node name="Game" type="Node2D" groups=["PLAYER_RESPAWN"]]
|
[node name="Game" type="Node2D" groups=["PLAYER_RESPAWN"]]
|
||||||
script = ExtResource("1_yksyv")
|
script = ExtResource("1_yksyv")
|
||||||
|
|
@ -63,15 +43,3 @@ script = ExtResource("1_yksyv")
|
||||||
[node name="L1_S9" parent="." instance=ExtResource("12_enubi")]
|
[node name="L1_S9" parent="." instance=ExtResource("12_enubi")]
|
||||||
|
|
||||||
[node name="L1_S10" parent="." instance=ExtResource("13_53pmm")]
|
[node name="L1_S10" parent="." instance=ExtResource("13_53pmm")]
|
||||||
|
|
||||||
[node name="WaterWarp" type="CanvasLayer" parent="." node_paths=PackedStringArray("target")]
|
|
||||||
script = ExtResource("15_jibn5")
|
|
||||||
target = NodePath("../PlayerController")
|
|
||||||
|
|
||||||
[node name="ColorRect" type="ColorRect" parent="WaterWarp"]
|
|
||||||
material = SubResource("ShaderMaterial_5vsgs")
|
|
||||||
anchors_preset = 15
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,12 @@ func _physics_process(delta: float) -> void:
|
||||||
velocity = direction * pull_speed
|
velocity = direction * pull_speed
|
||||||
move_and_slide()
|
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:
|
func _on_player_collected(body:CharacterBody2D) -> void:
|
||||||
if body is Player:
|
if body is Player:
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ radius = 34.0147
|
||||||
collision_layer = 16
|
collision_layer = 16
|
||||||
collision_mask = 2
|
collision_mask = 2
|
||||||
script = ExtResource("1_8vsnl")
|
script = ExtResource("1_8vsnl")
|
||||||
|
pull_speed = null
|
||||||
|
|
||||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
|
|
@ -36,7 +37,7 @@ debug_color = Color(0.19215687, 0.6431373, 0, 0)
|
||||||
|
|
||||||
[node name="HookAttractVolumn" type="Area2D" parent="."]
|
[node name="HookAttractVolumn" type="Area2D" parent="."]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
collision_layer = 16
|
collision_layer = 32
|
||||||
collision_mask = 0
|
collision_mask = 0
|
||||||
|
|
||||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="HookAttractVolumn"]
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="HookAttractVolumn"]
|
||||||
|
|
|
||||||
|
|
@ -225,12 +225,16 @@ tile_set = ExtResource("24_uiy5k")
|
||||||
|
|
||||||
[node name="DarkMaterialBall" parent="." instance=ExtResource("30_mu7ca")]
|
[node name="DarkMaterialBall" parent="." instance=ExtResource("30_mu7ca")]
|
||||||
position = Vector2(-164, 1283)
|
position = Vector2(-164, 1283)
|
||||||
|
pull_speed = 800.0
|
||||||
|
|
||||||
[node name="DarkMaterialBall2" parent="." instance=ExtResource("30_mu7ca")]
|
[node name="DarkMaterialBall2" parent="." instance=ExtResource("30_mu7ca")]
|
||||||
position = Vector2(116, 1076)
|
position = Vector2(116, 1076)
|
||||||
|
pull_speed = 800.0
|
||||||
|
|
||||||
[node name="DarkMaterialBall3" parent="." instance=ExtResource("30_mu7ca")]
|
[node name="DarkMaterialBall3" parent="." instance=ExtResource("30_mu7ca")]
|
||||||
position = Vector2(33, 1188)
|
position = Vector2(33, 1188)
|
||||||
|
pull_speed = 800.0
|
||||||
|
|
||||||
[node name="DarkMaterialBall4" parent="." instance=ExtResource("30_mu7ca")]
|
[node name="DarkMaterialBall4" parent="." instance=ExtResource("30_mu7ca")]
|
||||||
position = Vector2(-78, 1192)
|
position = Vector2(-78, 1192)
|
||||||
|
pull_speed = 800.0
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,92 +1,78 @@
|
||||||
[gd_resource type="TileSet" load_steps=7 format=3 uid="uid://cup1q1upvp18h"]
|
[gd_resource type="TileSet" load_steps=5 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://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"]
|
[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")
|
|
||||||
texture_region_size = Vector2i(96, 96)
|
|
||||||
1:1/0 = 0
|
|
||||||
2:1/0 = 0
|
|
||||||
2:2/0 = 0
|
|
||||||
3:2/0 = 0
|
|
||||||
3:3/0 = 0
|
|
||||||
3:1/0 = 0
|
|
||||||
1:2/0 = 0
|
|
||||||
1:3/0 = 0
|
|
||||||
2:3/0 = 0
|
|
||||||
6:1/0 = 0
|
|
||||||
7:1/0 = 0
|
|
||||||
8:1/0 = 0
|
|
||||||
8:2/0 = 0
|
|
||||||
8:3/0 = 0
|
|
||||||
7:3/0 = 0
|
|
||||||
6:3/0 = 0
|
|
||||||
6:2/0 = 0
|
|
||||||
7:2/0 = 0
|
|
||||||
10:1/0 = 0
|
|
||||||
11:1/0 = 0
|
|
||||||
12:1/0 = 0
|
|
||||||
9:5/0 = 0
|
|
||||||
10:6/0 = 0
|
|
||||||
11:5/0 = 0
|
|
||||||
10:5/0 = 0
|
|
||||||
9:6/0 = 0
|
|
||||||
11:6/0 = 0
|
|
||||||
7:5/0 = 0
|
|
||||||
7:6/0 = 0
|
|
||||||
6:6/0 = 0
|
|
||||||
6:5/0 = 0
|
|
||||||
3:5/0 = 0
|
|
||||||
3:6/0 = 0
|
|
||||||
4:6/0 = 0
|
|
||||||
4:5/0 = 0
|
|
||||||
1:5/0 = 0
|
|
||||||
1:6/0 = 0
|
|
||||||
1:7/0 = 0
|
|
||||||
1:9/0 = 0
|
|
||||||
1:10/0 = 0
|
|
||||||
2:10/0 = 0
|
|
||||||
2:9/0 = 0
|
|
||||||
1:8/0 = 0
|
|
||||||
4:9/0 = 0
|
|
||||||
4:10/0 = 0
|
|
||||||
5:10/0 = 0
|
|
||||||
5:9/0 = 0
|
|
||||||
5:8/0 = 0
|
|
||||||
7:8/0 = 0
|
|
||||||
8:8/0 = 0
|
|
||||||
8:9/0 = 0
|
|
||||||
8:10/0 = 0
|
|
||||||
7:9/0 = 0
|
|
||||||
6:9/0 = 0
|
|
||||||
10:9/0 = 0
|
|
||||||
11:9/0 = 0
|
|
||||||
11:10/0 = 0
|
|
||||||
10:10/0 = 0
|
|
||||||
9:9/0 = 0
|
|
||||||
9:10/0 = 0
|
|
||||||
10:8/0 = 0
|
|
||||||
11:8/0 = 0
|
|
||||||
8:5/0 = 0
|
|
||||||
9:4/0 = 0
|
|
||||||
11:4/0 = 0
|
|
||||||
7:4/0 = 0
|
|
||||||
3:4/0 = 0
|
|
||||||
1:4/0 = 0
|
|
||||||
|
|
||||||
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_u6jqb"]
|
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_u6jqb"]
|
||||||
texture = ExtResource("2_mucy5")
|
texture = ExtResource("2_mucy5")
|
||||||
texture_region_size = Vector2i(96, 96)
|
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"]
|
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_wtljp"]
|
||||||
texture = ExtResource("3_u6jqb")
|
texture = ExtResource("3_u6jqb")
|
||||||
texture_region_size = Vector2i(96, 96)
|
texture_region_size = Vector2i(96, 96)
|
||||||
10:6/0 = 0
|
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
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
tile_size = Vector2i(96, 96)
|
tile_size = Vector2i(96, 96)
|
||||||
sources/0 = SubResource("TileSetAtlasSource_ln1fl")
|
|
||||||
sources/1 = SubResource("TileSetAtlasSource_u6jqb")
|
sources/1 = SubResource("TileSetAtlasSource_u6jqb")
|
||||||
sources/2 = SubResource("TileSetAtlasSource_wtljp")
|
sources/2 = SubResource("TileSetAtlasSource_wtljp")
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
[gd_scene load_steps=2 format=3 uid="uid://ddwoxlqluxiq5"]
|
[gd_scene load_steps=3 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"]
|
[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_jrg4x"]
|
||||||
|
radius = 5.0990195
|
||||||
|
|
||||||
[node name="GarppingHookV2" type="Node2D"]
|
[node name="GarppingHookV2" type="Node2D"]
|
||||||
script = ExtResource("1_jrg4x")
|
script = ExtResource("1_jrg4x")
|
||||||
|
|
||||||
|
|
@ -15,3 +18,12 @@ unique_name_in_owner = true
|
||||||
target_position = Vector2(80, 0)
|
target_position = Vector2(80, 0)
|
||||||
collision_mask = 20
|
collision_mask = 20
|
||||||
collide_with_areas = true
|
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)
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ extends Node2D
|
||||||
|
|
||||||
@onready var line_2d: Line2D = %Line2D
|
@onready var line_2d: Line2D = %Line2D
|
||||||
@onready var ray: RayCast2D = %RayCast2D
|
@onready var ray: RayCast2D = %RayCast2D
|
||||||
|
@onready var tip_detector: Area2D = $TipDetector
|
||||||
|
|
||||||
var _tween: Tween
|
var _tween: Tween
|
||||||
|
|
||||||
|
|
@ -57,7 +58,8 @@ func start_stretching(direction: Vector2) -> void:
|
||||||
_cached_cancel = false
|
_cached_cancel = false
|
||||||
_stretching_dir = direction.normalized()
|
_stretching_dir = direction.normalized()
|
||||||
_current_length = 0.0
|
_current_length = 0.0
|
||||||
|
_current_velocity = Vector2.ZERO # 重置速度
|
||||||
|
|
||||||
_dir_id = _get_direction_id(direction,8)
|
_dir_id = _get_direction_id(direction,8)
|
||||||
|
|
||||||
func end_stretching(force_end: bool = false) -> bool:
|
func end_stretching(force_end: bool = false) -> bool:
|
||||||
|
|
@ -68,6 +70,7 @@ func end_stretching(force_end: bool = false) -> bool:
|
||||||
|
|
||||||
_is_stretching = false
|
_is_stretching = false
|
||||||
_stretching_dir = Vector2.ZERO
|
_stretching_dir = Vector2.ZERO
|
||||||
|
_current_velocity = Vector2.ZERO # 重置速度
|
||||||
return true
|
return true
|
||||||
|
|
||||||
func is_stretching() -> bool:
|
func is_stretching() -> bool:
|
||||||
|
|
@ -97,16 +100,42 @@ func _process(_delta: float) -> void:
|
||||||
# Core Logic
|
# Core Logic
|
||||||
# =================
|
# =================
|
||||||
|
|
||||||
|
## 钩爪当前速度
|
||||||
|
var _current_velocity: Vector2 = Vector2.ZERO
|
||||||
|
## 最大速度上限
|
||||||
|
@export var max_speed: float = 800.0
|
||||||
|
|
||||||
func _update_stretching(delta: float) -> void:
|
func _update_stretching(delta: float) -> void:
|
||||||
# 先嘗試推進
|
# 检测前端点的吸引力 (direction, strength)
|
||||||
var next_length := _current_length + stretching_speed * delta
|
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)
|
next_length = min(next_length, max_length)
|
||||||
|
|
||||||
# 使用 getter 获取当前方向(允许外部复写)
|
# 预测末端位置:起点 + 方向 * 累计长度
|
||||||
var current_dir := get_stretching_dir()
|
var predicted_pos := global_position + velocity_dir * next_length
|
||||||
|
|
||||||
# 先用「下一幀長度」做 Ray
|
tip_detector.global_position = predicted_pos
|
||||||
ray.target_position = current_dir * next_length
|
|
||||||
|
# RayCast 也应该射到“累计长度”
|
||||||
|
ray.target_position = velocity_dir * next_length
|
||||||
ray.force_raycast_update()
|
ray.force_raycast_update()
|
||||||
|
|
||||||
# ===== 命中檢測(最高優先)=====
|
# ===== 命中檢測(最高優先)=====
|
||||||
|
|
@ -114,13 +143,12 @@ func _update_stretching(delta: float) -> void:
|
||||||
var collider := ray.get_collider()
|
var collider := ray.get_collider()
|
||||||
if collider is Node2D and collider.is_in_group(GRAPABLE_GROUP):
|
if collider is Node2D and collider.is_in_group(GRAPABLE_GROUP):
|
||||||
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 = current_dir * _current_length
|
ray.target_position = velocity_dir * _current_length
|
||||||
_handle_hit(collider as Node2D, hit_pos)
|
_handle_hit(collider as Node2D, hit_pos)
|
||||||
return
|
return
|
||||||
|
|
||||||
# ===== 沒命中,才正式推進 =====
|
# ===== 没命中,才正式推進 =====
|
||||||
_current_length = next_length
|
_current_length = next_length
|
||||||
|
|
||||||
# 取消邏輯
|
# 取消邏輯
|
||||||
|
|
@ -134,9 +162,33 @@ func _update_stretching(delta: float) -> void:
|
||||||
stretching_finished.emit(true, null)
|
stretching_finished.emit(true, null)
|
||||||
end_stretching(true)
|
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:
|
func _handle_hit(target: Node2D, hit_pos: Vector2) -> void:
|
||||||
_is_stretching = false
|
_is_stretching = false
|
||||||
_stretching_dir = Vector2.ZERO
|
_stretching_dir = Vector2.ZERO
|
||||||
|
_current_velocity = Vector2.ZERO # 重置速度
|
||||||
|
|
||||||
ray.target_position = to_local(hit_pos)
|
ray.target_position = to_local(hit_pos)
|
||||||
|
|
||||||
|
|
@ -155,6 +207,7 @@ func _release_hook() -> void:
|
||||||
# 1. 停止拉伸(保險)
|
# 1. 停止拉伸(保險)
|
||||||
_is_stretching = false
|
_is_stretching = false
|
||||||
_stretching_dir = Vector2.ZERO
|
_stretching_dir = Vector2.ZERO
|
||||||
|
_current_velocity = Vector2.ZERO # 重置速度
|
||||||
_cached_cancel = false
|
_cached_cancel = false
|
||||||
_current_length = 0.0
|
_current_length = 0.0
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -97,3 +97,4 @@ 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="Hook_Attract"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue