using Godot; namespace Cirno.Scripts.Components.Actors; public partial class ActorTankMovement : MovementHandler { public override Vector2 FacingDirection { get => _parent.FacingDirection; set => _parent.FacingDirection = value; } public override Vector2 MovementDirection { get => _parent.MovementDirection; set => _parent.MovementDirection = value; } [Export] public float TurnSpeed = 4.0f; // Speed of turning [Export] public float Acceleration = 30f; [Export] public float Deceleration = 50f; private float _currentTurnProgress = 0; private Vector2 _targetFacingDirection = Vector2.Up; private float _currentSpeed = 0; private AnimatedSprite2D _animatedSprite; public override void Init(Actor parent) { base.Init(parent); MovementDirection = Vector2.Zero; FacingDirection = Vector2.Down; } public override void Update(double delta) { } public override void PhysicsUpdate(double delta) { var inputDirection = AggregateInputProviders(); // Handle Turning HandleTurning(_parent, inputDirection, delta); // Handle Movement (forward/backward) HandleMovement(_parent, inputDirection, delta); // Set Animation //UpdateAnimation(actor); } private void HandleTurning(Actor actor, Vector2 input, double delta) { // Only rotate if there is input and not currently turning if (input.Length() > 0.1f && _currentTurnProgress <= 0) { // Snap to the closest 8-direction vector _targetFacingDirection = GetSnappedDirection(input); _currentTurnProgress = 1.0f; // Start turn animation } // Simulate turning delay if (_currentTurnProgress > 0) { _currentTurnProgress -= (float)(TurnSpeed * delta); if (_currentTurnProgress <= 0) { actor.FacingDirection = _targetFacingDirection; } } } private Vector2 GetSnappedDirection(Vector2 input) { // Get angle and snap to 45-degree increments float angle = input.Angle(); float snappedAngle = Mathf.Round(angle / (Mathf.Pi / 4)) * (Mathf.Pi / 4); // 45° increments return Vector2.Right.Rotated(snappedAngle).Normalized(); } private void HandleMovement(Actor actor, Vector2 input, double delta) { // If turning, no movement if (_currentTurnProgress > 0) { actor.Velocity = Vector2.Zero; return; } // Move forward/backward based on facing direction if (input.Y < 0) // Forward { _currentSpeed = Mathf.MoveToward(_currentSpeed, actor.MovementSpeed, Acceleration * (float)delta); } else if (input.Y > 0) // Backward { _currentSpeed = Mathf.MoveToward(_currentSpeed, -actor.MovementSpeed / 2, Acceleration * (float)delta); } else { _currentSpeed = Mathf.MoveToward(_currentSpeed, 0, Deceleration * (float)delta); } // Set velocity actor.Velocity = actor.FacingDirection * _currentSpeed; actor.MoveAndSlide(); } }