107 lines
2.4 KiB
GDScript
107 lines
2.4 KiB
GDScript
@tool
|
|
class_name MovingPlatform
|
|
extends AbstractPlatform
|
|
|
|
|
|
enum Type {
|
|
SelfMoving,
|
|
LeftRight,
|
|
RightLeft,
|
|
UpDown,
|
|
DownUp,
|
|
}
|
|
|
|
|
|
const ANIMATION_MAP : Dictionary[Type, Dictionary] = {
|
|
Type.LeftRight: { false: ANIMATION_MOVING_LEFT, true: ANIMATION_MOVING_RIGHT },
|
|
Type.RightLeft: { false: ANIMATION_MOVING_RIGHT, true: ANIMATION_MOVING_LEFT },
|
|
Type.UpDown: { false: ANIMATION_MOVING_UP, true: ANIMATION_MOVING_DOWN },
|
|
Type.DownUp: { false: ANIMATION_MOVING_DOWN, true: ANIMATION_MOVING_UP },
|
|
}
|
|
|
|
|
|
@export var is_loop := false
|
|
@export var path : Path2D
|
|
@export var path_follow : PathFollow2D
|
|
@export_range(0, 25, 0.1) var speed : float = 10.0
|
|
@export var type := Type.SelfMoving:
|
|
set(value):
|
|
type = value
|
|
if is_node_ready():
|
|
_initialize_platform()
|
|
|
|
|
|
var is_moving := false
|
|
var is_reverse := false
|
|
var tween: Tween
|
|
|
|
|
|
@onready var invert_timer : Timer = $InvertTimer
|
|
|
|
|
|
func _ready() -> void:
|
|
super._ready()
|
|
_initialize_platform()
|
|
|
|
|
|
func toggle() -> void:
|
|
if type == Type.SelfMoving: return
|
|
|
|
if is_moving:
|
|
_stop_movement()
|
|
else:
|
|
_start_movement()
|
|
|
|
|
|
func _initialize_platform() -> void:
|
|
if not Engine.is_editor_hint() and type == Type.SelfMoving:
|
|
_start_movement()
|
|
else:
|
|
_select_animation()
|
|
|
|
|
|
func _select_animation() -> void:
|
|
if type == Type.SelfMoving:
|
|
if not icon_sprite.is_playing():
|
|
icon_sprite.play(ANIMATION_SELF_MOVING)
|
|
return
|
|
|
|
var direction : String = ANIMATION_MAP[type][is_reverse]
|
|
var suffix := ANIMATION_ACTIVE_SUFFIX if is_moving else ANIMATION_STATIC_SUFFIX
|
|
icon_sprite.play(ANIMATION_MOVING_PREFIX + direction + suffix)
|
|
|
|
|
|
func _start_movement() -> void:
|
|
is_moving = true
|
|
if tween and tween.is_running():
|
|
tween.kill()
|
|
_select_animation()
|
|
|
|
var target_progress := 0.0 if is_reverse else path.curve.get_baked_length()
|
|
var distance := absf(target_progress - path_follow.progress)
|
|
var duration := distance / speed
|
|
|
|
tween = create_tween()
|
|
var target_ratio := 0.0 if is_reverse else 1.0
|
|
tween.tween_property(path_follow, "progress_ratio", target_ratio, duration)
|
|
tween.finished.connect(_invert_movement)
|
|
|
|
|
|
func _stop_movement() -> void:
|
|
is_moving = false
|
|
if tween and tween.is_running():
|
|
tween.kill()
|
|
if not invert_timer.is_stopped():
|
|
invert_timer.stop()
|
|
_select_animation()
|
|
|
|
|
|
func _invert_movement() -> void:
|
|
if is_loop:
|
|
path_follow.progress_ratio = 0
|
|
else:
|
|
is_reverse = not is_reverse
|
|
|
|
_select_animation()
|
|
invert_timer.start()
|