diff --git a/TanksServer/GameLogic/MapService.cs b/TanksServer/GameLogic/MapService.cs index 0666cdd..bbdf204 100644 --- a/TanksServer/GameLogic/MapService.cs +++ b/TanksServer/GameLogic/MapService.cs @@ -10,26 +10,26 @@ internal sealed class MapService private readonly string _map = """ - #############..###################.######### + #######.##########################.######### #...................##.....................# #...................##.....................# #.....####......................####.......# #..........................................# #............###...........###.............# #............#...............#.............# - #...##.......#...............#......##.....# + #...##.......#....#....#.....#......##.....# #....#..............................#......# - #....#..##......................##..#......# - #....#..##......................##..#......# + .....#...#......................#...#....... + .....#...#......................#...#....... #....#..............................#......# - #...##.......#...............#......##.....# + #...##.......#....#....#.....#......##.....# #............#...............#.............# #............###...........###.............# #..........................................# #.....####......................####.......# #...................##.....................# #...................##.....................# - #############..###################.######### + #######.##########################.######### """ .ReplaceLineEndings(string.Empty); diff --git a/TanksServer/GameLogic/MoveTanks.cs b/TanksServer/GameLogic/MoveTanks.cs index 3c241f9..d10cd3b 100644 --- a/TanksServer/GameLogic/MoveTanks.cs +++ b/TanksServer/GameLogic/MoveTanks.cs @@ -1,7 +1,7 @@ namespace TanksServer.GameLogic; internal sealed class MoveTanks( - TankManager tanks, + TankManager tanks, IOptions options, MapService map ) : ITickStep @@ -48,19 +48,30 @@ internal sealed class MoveTanks( private bool TryMoveTankTo(Tank tank, FloatPosition newPosition) { var (topLeft, bottomRight) = TankManager.GetTankBounds(newPosition.ToPixelPosition()); - TilePosition[] positions = [ - topLeft.ToTilePosition(), - new PixelPosition(bottomRight.X, topLeft.Y).ToTilePosition(), - new PixelPosition(topLeft.X, bottomRight.Y).ToTilePosition(), - bottomRight.ToTilePosition(), - ]; - - if (positions.Any(map.IsCurrentlyWall)) + + if (HitsWall(topLeft, bottomRight)) + return false; + if (HitsTank(tank, newPosition)) return false; - // TODO: check tanks - tank.Position = newPosition; return true; } -} + + private bool HitsTank(Tank tank, FloatPosition newPosition) => + tanks + .Where(otherTank => otherTank != tank) + .Any(otherTank => newPosition.Distance(otherTank.Position) < MapService.TileSize); + + private bool HitsWall(PixelPosition topLeft, PixelPosition bottomRight) + { + TilePosition[] positions = + [ + topLeft.ToTilePosition(), + new PixelPosition(bottomRight.X, topLeft.Y).ToTilePosition(), + new PixelPosition(topLeft.X, bottomRight.Y).ToTilePosition(), + bottomRight.ToTilePosition(), + ]; + return positions.Any(map.IsCurrentlyWall); + } +} \ No newline at end of file diff --git a/TanksServer/GameLogic/SpawnNewTanks.cs b/TanksServer/GameLogic/SpawnNewTanks.cs index b54a725..42d0dc1 100644 --- a/TanksServer/GameLogic/SpawnNewTanks.cs +++ b/TanksServer/GameLogic/SpawnNewTanks.cs @@ -24,24 +24,22 @@ internal sealed class SpawnNewTanks( { Dictionary candidates = []; - for (ushort x = 0; x < MapService.TilesPerRow; x++) - for (ushort y = 0; y < MapService.TilesPerColumn; y++) + for (ushort x = 1; x < MapService.TilesPerRow - 1; x++) + for (ushort y = 1; y < MapService.TilesPerColumn - 1; y++) { var tile = new TilePosition(x, y); if (map.IsCurrentlyWall(tile)) continue; - var tilePixelCenter = tile.GetPixelRelative(4, 4); + var tilePixelCenter = tile.GetPixelRelative(4, 4).ToFloatPosition(); var minDistance = bullets.GetAll() .Cast() .Concat(tanks) - .Select(entity => Math.Sqrt( - Math.Pow(entity.Position.X - tilePixelCenter.X, 2) + - Math.Pow(entity.Position.Y - tilePixelCenter.Y, 2))) + .Select(entity => entity.Position.Distance(tilePixelCenter)) .Aggregate(double.MaxValue, Math.Min); - + candidates.Add(tile, minDistance); } diff --git a/TanksServer/Graphics/DrawStateToFrame.cs b/TanksServer/Graphics/DrawStateToFrame.cs index ce0054e..d633b63 100644 --- a/TanksServer/Graphics/DrawStateToFrame.cs +++ b/TanksServer/Graphics/DrawStateToFrame.cs @@ -8,15 +8,13 @@ internal sealed class DrawStateToFrame( ) : ITickStep { private readonly List _drawSteps = drawSteps.ToList(); - private readonly PixelGrid _drawGrid = new(MapService.PixelsPerRow, MapService.PixelsPerColumn); public Task TickAsync() { - // TODO: fix race condition with shared buffer access - _drawGrid.Clear(); + var drawGrid = new PixelGrid(MapService.PixelsPerRow, MapService.PixelsPerColumn); foreach (var step in _drawSteps) - step.Draw(_drawGrid); - lastFrameProvider.LastFrame = _drawGrid; + step.Draw(drawGrid); + lastFrameProvider.LastFrame = drawGrid; return Task.CompletedTask; } } diff --git a/TanksServer/Models/PositionHelpers.cs b/TanksServer/Models/PositionHelpers.cs index 71c5231..be4459d 100644 --- a/TanksServer/Models/PositionHelpers.cs +++ b/TanksServer/Models/PositionHelpers.cs @@ -31,4 +31,13 @@ internal static class PositionHelpers x: (ushort)(position.X / MapService.TileSize), y: (ushort)(position.Y / MapService.TileSize) ); + + public static FloatPosition ToFloatPosition(this PixelPosition position) => new(position.X, position.Y); + + + public static double Distance(this FloatPosition p1, FloatPosition p2) + => Math.Sqrt( + Math.Pow(p1.X - p2.X, 2) + + Math.Pow(p1.Y - p2.Y, 2) + ); } \ No newline at end of file