Better free movement

This commit is contained in:
Marco 2025-02-18 18:18:13 +01:00
commit 388747ccb3
7 changed files with 108 additions and 15 deletions

View file

@ -0,0 +1,23 @@
using Godot;
namespace Cirno.Scripts.Components.Actors;
public abstract partial class ActorAimingProvider : Node2D
{
protected Actor _parent;
public abstract Vector2 FacingDirection { get; set; }
public virtual void Init(Actor parent)
{
_parent = parent;
var children = GetChildren();
foreach (var child in children) {
if (child is InputProvider inputProvider)
{
//_inputProviders.Add(inputProvider);
}
}
}
}

View file

@ -27,7 +27,19 @@ public partial class ActorFreeMovement : MovementHandler
public override void Move(double delta)
{
MovementDirection = AggregateInputProviders();
MovementDirection = AggregateInputProviders().Normalized();
var aimingDirection = GetAimingDirection().Normalized();
var isStrafing = GetStrafing();
if (!isStrafing && aimingDirection.Length() > 0.1f)
{
FacingDirection = aimingDirection;
}
else if (MovementDirection != Vector2.Zero)
{
FacingDirection = MovementDirection;
}
_parent.Velocity = MovementDirection * _parent.MovementSpeed;

View file

@ -1,4 +1,5 @@
using Godot;
using System.Collections.Generic;
using Godot;
namespace Cirno.Scripts.Components.Actors;
@ -46,15 +47,39 @@ public partial class AnimationHandler : Node2D
var angle = Mathf.RadToDeg(direction.Angle());
angle = Mathf.PosMod(angle, 360);
if (angle >= 337.5 || angle < 22.5) return "right";
if (angle >= 22.5 && angle < 67.5) return "up_right";
if (angle >= 67.5 && angle < 112.5) return "up";
if (angle >= 112.5 && angle < 157.5) return "up_left";
if (angle >= 157.5 && angle < 202.5) return "left";
if (angle >= 202.5 && angle < 247.5) return "down_left";
if (angle >= 247.5 && angle < 292.5) return "down";
if (angle >= 292.5 && angle < 337.5) return "down_right";
if (angle >= 337.5 || angle < 22.5) return _directionsTable[FacingDirection.Right];
if (angle >= 22.5 && angle < 67.5) return _directionsTable[FacingDirection.DownRight];
if (angle >= 67.5 && angle < 112.5) return _directionsTable[FacingDirection.Down];
if (angle >= 112.5 && angle < 157.5) return _directionsTable[FacingDirection.DownLeft];
if (angle >= 157.5 && angle < 202.5) return _directionsTable[FacingDirection.Left];
if (angle >= 202.5 && angle < 247.5) return _directionsTable[FacingDirection.UpLeft];
if (angle >= 247.5 && angle < 292.5) return _directionsTable[FacingDirection.Up];
if (angle >= 292.5 && angle < 337.5) return _directionsTable[FacingDirection.UpRight];
return "up";
return _directionsTable[FacingDirection.Up];
}
private readonly Dictionary<FacingDirection, string> _directionsTable = new()
{
{ FacingDirection.Right, "right" },
{ FacingDirection.Left, "left" },
{ FacingDirection.Up, "up" },
{ FacingDirection.Down, "down" },
{ FacingDirection.UpLeft, "up_left" },
{ FacingDirection.UpRight, "up_right" },
{ FacingDirection.DownLeft, "down_left" },
{ FacingDirection.DownRight, "down_right" }
};
private enum FacingDirection
{
Up,
Down,
Left,
Right,
UpRight,
UpLeft,
DownRight,
DownLeft
}
}

View file

@ -5,4 +5,7 @@ namespace Cirno.Scripts.Components.Actors;
public abstract partial class InputProvider : Node2D
{
public abstract Vector2 GetMovementInput();
public abstract Vector2 GetAimInput();
public abstract bool GetStrafing();
}

View file

@ -8,4 +8,24 @@ public partial class KeyboardInputProvider : InputProvider
{
return Input.GetVector("left", "right", "up", "down");
}
public override Vector2 GetAimInput()
{
var rightStickInput = GetRightStickInput();
return GetRightStickInput();
}
private Vector2 GetRightStickInput()
{
return new Vector2(
Input.GetAxis("aim_left","aim_right"),
Input.GetAxis("aim_up", "aim_down")
);
}
public override bool GetStrafing()
{
return Input.IsActionPressed("strafe");
}
}

View file

@ -28,7 +28,17 @@ public abstract partial class MovementHandler : Node2D
public virtual Vector2 AggregateInputProviders()
{
return _inputProviders.Aggregate(Vector2.Zero, (current, inputProvider) => current + inputProvider.GetMovementInput().Normalized());
return _inputProviders.Aggregate(Vector2.Zero, (current, inputProvider) => current + inputProvider.GetMovementInput());
}
public virtual Vector2 GetAimingDirection()
{
return _inputProviders.Aggregate(Vector2.Zero, (current, inputProvider) => current + inputProvider.GetAimInput());
}
public virtual bool GetStrafing()
{
return _inputProviders.Aggregate(false, (current, inputProvider) => current && inputProvider.GetStrafing());
}
public abstract void Move(double delta);