forked from team-sg/hero-mark-2
92 lines
2.6 KiB
GDScript
92 lines
2.6 KiB
GDScript
tool
|
|
extends Node2D
|
|
|
|
|
|
const DEBUG_COLOR := Color(0.4, 0.2, 0.6, 0.75)
|
|
|
|
export var size: float = 8.0 setget _set_size
|
|
export var speed: float = 20.0
|
|
export var point_a := Vector2.ZERO setget _set_point_a
|
|
export var point_b := Vector2.ZERO setget _set_point_b
|
|
export (float, 0.0, 1.0, 0.1) var start_position: float = 0.0 setget _set_start_position
|
|
export var start_reversed: bool = false
|
|
|
|
onready var body: KinematicBody2D = $Body
|
|
onready var sprite: Sprite = $"%Sprite"
|
|
|
|
var _previous_position: Vector2
|
|
|
|
|
|
func _ready() -> void:
|
|
if Engine.editor_hint:
|
|
return
|
|
|
|
var distance := point_a.distance_to(point_b)
|
|
var start_target := point_a if start_reversed else point_b
|
|
var end_target := point_b if start_reversed else point_a
|
|
var start_weight := start_position if start_reversed else 1.0 - start_position
|
|
|
|
var tween := create_tween()
|
|
tween.stop()
|
|
tween.set_process_mode(Tween.TWEEN_PROCESS_PHYSICS)
|
|
tween.set_loops()
|
|
tween.tween_property(body, "position", end_target, distance / speed)
|
|
tween.tween_property(body, "position", start_target, distance / speed)
|
|
var start_tween := create_tween()
|
|
start_tween.set_process_mode(Tween.TWEEN_PROCESS_PHYSICS)
|
|
start_tween.tween_property(body, "position", start_target, start_weight * distance / speed)
|
|
start_tween.tween_callback(tween, "play")
|
|
|
|
_previous_position = body.global_position
|
|
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
if Engine.editor_hint:
|
|
return
|
|
|
|
if (body.global_position.y - _previous_position.y) < 0.0 and speed >= 40.0:
|
|
sprite.position.y = -1.0
|
|
else:
|
|
sprite.position.y = 0.0
|
|
_previous_position = body.global_position
|
|
|
|
|
|
func _set_size(value: float) -> void:
|
|
size = value
|
|
get_node("%Sprite").region_rect.size.x = size
|
|
var segment = get_node("%CollisionShape").shape as SegmentShape2D
|
|
segment.a.x = size * -0.5
|
|
segment.b.x = size * 0.5
|
|
|
|
|
|
func _set_start_position(value: float) -> void:
|
|
start_position = value
|
|
if Engine.editor_hint:
|
|
get_node("Body").position = lerp(point_a, point_b, start_position)
|
|
|
|
|
|
func _set_point_a(value: Vector2) -> void:
|
|
point_a = value
|
|
if Engine.editor_hint:
|
|
_update_positions()
|
|
|
|
|
|
func _set_point_b(value: Vector2) -> void:
|
|
point_b = value
|
|
if Engine.editor_hint:
|
|
_update_positions()
|
|
|
|
|
|
func _update_positions() -> void:
|
|
if point_a == point_b:
|
|
_set_start_position(0.0)
|
|
else:
|
|
var closest_point := Geometry.get_closest_point_to_segment_2d(get_node("Body").position, point_a, point_b)
|
|
_set_start_position(point_a.distance_to(closest_point) / point_a.distance_to(point_b))
|
|
property_list_changed_notify()
|
|
update()
|
|
|
|
|
|
func _draw() -> void:
|
|
if Engine.editor_hint:
|
|
draw_line(point_a, point_b, DEBUG_COLOR, 1.01)
|