PokemonLike/Library/Characters/CharacterMovement.cs

88 lines
2.4 KiB
C#

using Godot;
using System;
using PokemonLike.Library.Support;
namespace PokemonLike.Library.Characters;
[GlobalClass]
public partial class CharacterMovement : Node
{
[Signal]
public delegate void AnimationEventHandler(string animationType);
[ExportCategory("Nodes")]
[Export] public CharacterBody2D Character;
[Export] public CharacterInput CharacterInput;
[Export] public CharacterCollisionRayCast CharacterCollisionRayCast;
[ExportCategory("Movement")]
[Export] public Vector2 TargetPosition = Vector2.Zero;
[Export] public bool IsWalking = false;
[Export] public bool CollisionDetected = false;
public override void _Ready()
{
CharacterInput.Walk += StartWalking;
CharacterInput.Turn += Turn;
CharacterCollisionRayCast.Collision += (value) => CollisionDetected = value;
Logger.Info("Loading character movement component ...");
}
public override void _Process(double delta)
{
Walk(delta);
}
public bool IsMoving() => IsWalking;
public bool IsColliding() => CollisionDetected;
public void StartWalking()
{
if (!IsMoving() && !IsColliding())
{
EmitSignal(SignalName.Animation, "walk");
TargetPosition = Character.Position + CharacterInput.Direction * Globals.Instance.GRID_SIZE;
Logger.Debug($"Moving from {Character.Position} to {TargetPosition}");
IsWalking = true;
}
}
public void Walk(double delta)
{
if (IsWalking)
{
Character.Position =
Character.Position.MoveToward(TargetPosition, (float)delta * Globals.Instance.GRID_SIZE * 4);
if (Character.Position.DistanceTo(TargetPosition) < 1f)
{
StopWalking();
}
}
else
{
EmitSignal(SignalName.Animation, "idle");
}
}
public void StopWalking()
{
IsWalking = false;
SnapPositionToGrid();
}
public void Turn()
{
EmitSignal(SignalName.Animation, "turn");
}
public void SnapPositionToGrid()
{
Character.Position = new Vector2(
Mathf.Round(Character.Position.X / Globals.Instance.GRID_SIZE) * Globals.Instance.GRID_SIZE,
Mathf.Round(Character.Position.Y / Globals.Instance.GRID_SIZE) * Globals.Instance.GRID_SIZE
);
}
}