224 lines
6.8 KiB
C#
224 lines
6.8 KiB
C#
namespace Marro.PacManUdon
|
|
{
|
|
using System;
|
|
using UnityEngine;
|
|
|
|
public enum Direction
|
|
{
|
|
Zero = 0, Up = 1, Down = 2, Left = 4, Right = 8, UpLeft = 5, UpRight = 9, DownLeft = 6, DownRight = 10
|
|
}
|
|
|
|
public enum DirectionAxis
|
|
{
|
|
Horizontal = 0,
|
|
Vertical = 1,
|
|
Both = 2
|
|
}
|
|
|
|
public abstract class GridMover : SyncedObject
|
|
{
|
|
protected Direction direction;
|
|
|
|
// Cannot be static, much to my annoyance
|
|
public readonly Vector2[] directionVectors =
|
|
{
|
|
Vector2.zero, // 0
|
|
Vector2.down, // 1
|
|
Vector2.up, // 2
|
|
Vector2.zero, // 3
|
|
Vector2.left, // 4
|
|
Vector2.down + Vector2.left, // 5
|
|
Vector2.up + Vector2.left, // 6
|
|
Vector2.left, // 7
|
|
Vector2.right, // 8
|
|
Vector2.down + Vector2.right, // 9
|
|
Vector2.up + Vector2.right, // 10
|
|
Vector2.right, // 11
|
|
Vector2.zero, // 12
|
|
Vector2.down, // 13
|
|
Vector2.up, // 14
|
|
Vector2.zero, // 15
|
|
};
|
|
|
|
public virtual Vector2 GetPosition()
|
|
{
|
|
return (Vector2)transform.localPosition;
|
|
}
|
|
|
|
public virtual void SetPosition(Vector2 position)
|
|
{
|
|
transform.localPosition = new Vector3(position.x, position.y, transform.localPosition.z);
|
|
}
|
|
|
|
public Vector2 GetVector(Direction direction)
|
|
{
|
|
return directionVectors[(int)direction];
|
|
}
|
|
|
|
public Direction GetDirection()
|
|
{
|
|
return direction;
|
|
}
|
|
|
|
public void SetDirection(Direction direction)
|
|
{
|
|
this.direction = direction;
|
|
UpdateAnimator();
|
|
}
|
|
|
|
protected static Direction VectorToDirection(Vector2 vector)
|
|
{
|
|
var directionId = 0;
|
|
|
|
if (vector.x < 0)
|
|
{
|
|
directionId = 4;
|
|
}
|
|
else if (vector.x > 0)
|
|
{
|
|
directionId = 8;
|
|
}
|
|
|
|
if (vector.y < 0)
|
|
{
|
|
directionId += 1;
|
|
}
|
|
else if (vector.y > 0)
|
|
{
|
|
directionId += 2;
|
|
}
|
|
|
|
return (Direction)directionId;
|
|
}
|
|
|
|
protected static Direction HorizontalToDirection(float horizontal)
|
|
{
|
|
if (horizontal < 0)
|
|
{
|
|
return Direction.Left;
|
|
}
|
|
if (horizontal > 0)
|
|
{
|
|
return Direction.Right;
|
|
}
|
|
return Direction.Zero;
|
|
}
|
|
|
|
protected static Direction VerticalToDirection(float vertical)
|
|
{
|
|
if (vertical < 0)
|
|
{
|
|
return Direction.Up;
|
|
}
|
|
if (vertical > 0)
|
|
{
|
|
return Direction.Down;
|
|
}
|
|
return Direction.Zero;
|
|
}
|
|
|
|
protected abstract void UpdateAnimator();
|
|
|
|
public override void CollectSyncedData(byte[] data, ref int index, NetworkEventType eventType)
|
|
{
|
|
data.Append(GetPosition(), ref index);
|
|
data.AppendAsByte((int)direction, ref index);
|
|
}
|
|
|
|
public void PadSyncedData(byte[] data, ref int index, NetworkEventType eventType)
|
|
{
|
|
index += 9;
|
|
}
|
|
|
|
public override bool WriteSyncedData(byte[] data, ref int index, NetworkEventType eventType)
|
|
{
|
|
SetPosition(data.ReadVector2(ref index));
|
|
SetDirection((Direction)data.ReadByte(ref index));
|
|
|
|
return true;
|
|
}
|
|
|
|
public bool ConsumeSyncedData(byte[] data, ref int index, NetworkEventType eventType)
|
|
{
|
|
index += 9;
|
|
|
|
return true;
|
|
}
|
|
|
|
#region Utils
|
|
public static Direction GetInverseDirection(Direction direction)
|
|
{
|
|
switch (direction)
|
|
{
|
|
case Direction.Up:
|
|
return Direction.Down;
|
|
case Direction.Down:
|
|
return Direction.Up;
|
|
case Direction.Left:
|
|
return Direction.Right;
|
|
case Direction.Right:
|
|
return Direction.Left;
|
|
case Direction.UpLeft:
|
|
return Direction.DownRight;
|
|
case Direction.UpRight:
|
|
return Direction.DownLeft;
|
|
case Direction.DownLeft:
|
|
return Direction.UpRight;
|
|
case Direction.DownRight:
|
|
return Direction.UpLeft;
|
|
default:
|
|
return Direction.Zero;
|
|
}
|
|
}
|
|
|
|
public static bool IsVertical(Direction direction) => ((int)direction & 0b0011) != 0;
|
|
public static bool IsHorizontal(Direction direction) => ((int)direction & 0b1100) != 0;
|
|
|
|
public static Direction VerticalComponent(Direction direction) => (Direction)((int)direction & 0b0011);
|
|
public static Direction HorizontalComponent(Direction direction) => (Direction)((int)direction & 0b1100);
|
|
|
|
public static Vector2 GetNextPosition(Vector2 currentPosition, Vector2 directionVector, float speed, float deltaTime)
|
|
{
|
|
var nextPosition = currentPosition + deltaTime * speed * directionVector;
|
|
nextPosition = new Vector2((nextPosition.x + 32) % 32, (nextPosition.y + 32) % 32);
|
|
return nextPosition;
|
|
}
|
|
|
|
public static Vector2 PositionToGrid(Vector2 position)
|
|
{
|
|
return new Vector2((int)position.x + 0.5f, (int)position.y + 0.5f);
|
|
}
|
|
|
|
public static bool CrossesTileBorder(Vector2 currentPosition, Vector2 nextPosition, Direction direction)
|
|
{
|
|
bool result = false;
|
|
|
|
if (IsHorizontal(direction))
|
|
{
|
|
result = Math.Floor(currentPosition.x) != Math.Floor(nextPosition.x);
|
|
}
|
|
if (!result && IsVertical(direction))
|
|
{
|
|
result = Math.Floor(currentPosition.y) != Math.Floor(nextPosition.y);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public static bool CrossesTileCenter(Vector2 currentPosition, Vector2 nextPosition, Direction direction)
|
|
{
|
|
bool result = false;
|
|
|
|
if (IsHorizontal(direction))
|
|
{
|
|
result = Math.Round(currentPosition.x) != Math.Round(nextPosition.x);
|
|
}
|
|
if (!result && IsVertical(direction))
|
|
{
|
|
result = Math.Round(currentPosition.y) != Math.Round(nextPosition.y);
|
|
}
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
} |