xiandie/scene/entity/ux/swing_2d.gd

48 lines
1.6 KiB
GDScript

class_name Swing2D
extends Marker2D
@export_range(0.1, 2.0) var angular_affection_ratio := 0.5
@export var target: Node2D
var player: MainPlayer
var distance_to_target := 0.0
var _angular_velocity := 0.0
var _rotation := 0.0
func _ready() -> void:
await SceneManager.ground_ready
player = SceneManager.get_player()
if player and target:
distance_to_target = global_position.distance_to(target.global_position)
# 刷新一帧
_physics_process(0.01)
func _physics_process(delta: float) -> void:
if distance_to_target <= 0.0:
return
var x_distance = abs(global_position.x - player.global_position.x)
# gravity
var _impluse = -_rotation * delta * 980.0
if x_distance < 50.0:
# angular impulse
_impluse -= smoothstep(30, 0, x_distance) * player.velocity.x * delta * angular_affection_ratio
if _impluse != 0.0:
_angular_velocity += _impluse * delta
if _angular_velocity != 0.0:
_rotation += _angular_velocity * delta
_rotation = clampf(_rotation, -0.5, 0.5)
# damping
_rotation = move_toward(_rotation, 0, max(abs(_rotation), 0.25) * delta * 0.25)
target.rotation = _rotation
# from global_position with distance_squared_to_target & _rotation
target.global_position = Vector2(
global_position.x - sin(_rotation) * distance_to_target,
global_position.y + cos(_rotation) * distance_to_target
)
# if GlobalConfig.DEBUG and Engine.get_frames_drawn() % 100 == 0:
# prints("Swing2D: ", "distance_to_target=", distance_to_target,
# "angular_velocity=", _angular_velocity, "rotation=", _rotation,
# "target.global_position=", target.global_position)