servicepoint-tanks/TanksServer/GameLogic/MoveTanks.cs

77 lines
2.3 KiB
C#
Raw Normal View History

2024-04-10 19:25:45 +02:00
namespace TanksServer.GameLogic;
2024-04-07 19:52:16 +02:00
internal sealed class MoveTanks(
2024-04-12 19:49:24 +02:00
TankManager tanks,
2024-04-10 19:25:45 +02:00
IOptions<TanksConfiguration> options,
MapService map
2024-04-07 19:52:16 +02:00
) : ITickStep
{
private readonly TanksConfiguration _config = options.Value;
public Task TickAsync()
{
foreach (var tank in tanks)
tank.Moved = TryMoveTank(tank);
return Task.CompletedTask;
}
private bool TryMoveTank(Tank tank)
{
var player = tank.Owner;
double speed;
switch (player.Controls)
{
case { Forward: false, Backward: false }:
case { Forward: true, Backward: true }:
return false;
case { Forward: true }:
speed = +_config.MoveSpeed;
break;
case { Backward: true }:
speed = -_config.MoveSpeed;
break;
default:
return false;
}
2024-04-13 18:35:36 +02:00
var angle = tank.Orientation / 16d * 2d * Math.PI;
2024-04-07 19:52:16 +02:00
var newX = tank.Position.X + Math.Sin(angle) * speed;
var newY = tank.Position.Y - Math.Cos(angle) * speed;
return TryMoveTankTo(tank, new FloatPosition(newX, newY))
2024-04-12 18:32:10 +02:00
|| TryMoveTankTo(tank, new FloatPosition(newX, tank.Position.Y))
|| TryMoveTankTo(tank, new FloatPosition(tank.Position.X, newY));
2024-04-07 19:52:16 +02:00
}
private bool TryMoveTankTo(Tank tank, FloatPosition newPosition)
{
if (HitsWall(newPosition))
2024-04-12 19:49:24 +02:00
return false;
if (HitsTank(tank, newPosition))
2024-04-07 19:52:16 +02:00
return false;
tank.Position = newPosition;
return true;
}
2024-04-12 19:49:24 +02:00
private bool HitsTank(Tank tank, FloatPosition newPosition) =>
tanks
.Where(otherTank => otherTank != tank)
.Any(otherTank => newPosition.Distance(otherTank.Position) < MapService.TileSize);
private bool HitsWall(FloatPosition newPosition)
2024-04-12 19:49:24 +02:00
{
var (topLeft, bottomRight) = Tank.GetBoundsForCenter(newPosition);
2024-04-12 19:49:24 +02:00
TilePosition[] positions =
[
topLeft.ToTilePosition(),
new PixelPosition(bottomRight.X, topLeft.Y).ToTilePosition(),
new PixelPosition(topLeft.X, bottomRight.Y).ToTilePosition(),
bottomRight.ToTilePosition()
2024-04-12 19:49:24 +02:00
];
return positions.Any(map.IsCurrentlyWall);
}
}