Files
CultManor/game/platform/moving_platform.gd
T

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()