tanks collide with each other

This commit is contained in:
Vinzenz Schroeter 2024-04-12 19:49:24 +02:00
parent 461a9139c2
commit 89494ef495
5 changed files with 46 additions and 30 deletions

View file

@ -10,26 +10,26 @@ internal sealed class MapService
private readonly string _map = private readonly string _map =
""" """
#############..###################.######### #######.##########################.#########
#...................##.....................# #...................##.....................#
#...................##.....................# #...................##.....................#
#.....####......................####.......# #.....####......................####.......#
#..........................................# #..........................................#
#............###...........###.............# #............###...........###.............#
#............#...............#.............# #............#...............#.............#
#...##.......#...............#......##.....# #...##.......#....#....#.....#......##.....#
#....#..............................#......# #....#..............................#......#
#....#..##......................##..#......# .....#...#......................#...#.......
#....#..##......................##..#......# .....#...#......................#...#.......
#....#..............................#......# #....#..............................#......#
#...##.......#...............#......##.....# #...##.......#....#....#.....#......##.....#
#............#...............#.............# #............#...............#.............#
#............###...........###.............# #............###...........###.............#
#..........................................# #..........................................#
#.....####......................####.......# #.....####......................####.......#
#...................##.....................# #...................##.....................#
#...................##.....................# #...................##.....................#
#############..###################.######### #######.##########################.#########
""" """
.ReplaceLineEndings(string.Empty); .ReplaceLineEndings(string.Empty);

View file

@ -1,7 +1,7 @@
namespace TanksServer.GameLogic; namespace TanksServer.GameLogic;
internal sealed class MoveTanks( internal sealed class MoveTanks(
TankManager tanks, TankManager tanks,
IOptions<TanksConfiguration> options, IOptions<TanksConfiguration> options,
MapService map MapService map
) : ITickStep ) : ITickStep
@ -48,19 +48,30 @@ internal sealed class MoveTanks(
private bool TryMoveTankTo(Tank tank, FloatPosition newPosition) private bool TryMoveTankTo(Tank tank, FloatPosition newPosition)
{ {
var (topLeft, bottomRight) = TankManager.GetTankBounds(newPosition.ToPixelPosition()); var (topLeft, bottomRight) = TankManager.GetTankBounds(newPosition.ToPixelPosition());
TilePosition[] positions = [
topLeft.ToTilePosition(), if (HitsWall(topLeft, bottomRight))
new PixelPosition(bottomRight.X, topLeft.Y).ToTilePosition(), return false;
new PixelPosition(topLeft.X, bottomRight.Y).ToTilePosition(), if (HitsTank(tank, newPosition))
bottomRight.ToTilePosition(),
];
if (positions.Any(map.IsCurrentlyWall))
return false; return false;
// TODO: check tanks
tank.Position = newPosition; tank.Position = newPosition;
return true; 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);
}
}

View file

@ -24,24 +24,22 @@ internal sealed class SpawnNewTanks(
{ {
Dictionary<TilePosition, double> candidates = []; Dictionary<TilePosition, double> candidates = [];
for (ushort x = 0; x < MapService.TilesPerRow; x++) for (ushort x = 1; x < MapService.TilesPerRow - 1; x++)
for (ushort y = 0; y < MapService.TilesPerColumn; y++) for (ushort y = 1; y < MapService.TilesPerColumn - 1; y++)
{ {
var tile = new TilePosition(x, y); var tile = new TilePosition(x, y);
if (map.IsCurrentlyWall(tile)) if (map.IsCurrentlyWall(tile))
continue; continue;
var tilePixelCenter = tile.GetPixelRelative(4, 4); var tilePixelCenter = tile.GetPixelRelative(4, 4).ToFloatPosition();
var minDistance = bullets.GetAll() var minDistance = bullets.GetAll()
.Cast<IMapEntity>() .Cast<IMapEntity>()
.Concat(tanks) .Concat(tanks)
.Select(entity => Math.Sqrt( .Select(entity => entity.Position.Distance(tilePixelCenter))
Math.Pow(entity.Position.X - tilePixelCenter.X, 2) +
Math.Pow(entity.Position.Y - tilePixelCenter.Y, 2)))
.Aggregate(double.MaxValue, Math.Min); .Aggregate(double.MaxValue, Math.Min);
candidates.Add(tile, minDistance); candidates.Add(tile, minDistance);
} }

View file

@ -8,15 +8,13 @@ internal sealed class DrawStateToFrame(
) : ITickStep ) : ITickStep
{ {
private readonly List<IDrawStep> _drawSteps = drawSteps.ToList(); private readonly List<IDrawStep> _drawSteps = drawSteps.ToList();
private readonly PixelGrid _drawGrid = new(MapService.PixelsPerRow, MapService.PixelsPerColumn);
public Task TickAsync() public Task TickAsync()
{ {
// TODO: fix race condition with shared buffer access var drawGrid = new PixelGrid(MapService.PixelsPerRow, MapService.PixelsPerColumn);
_drawGrid.Clear();
foreach (var step in _drawSteps) foreach (var step in _drawSteps)
step.Draw(_drawGrid); step.Draw(drawGrid);
lastFrameProvider.LastFrame = _drawGrid; lastFrameProvider.LastFrame = drawGrid;
return Task.CompletedTask; return Task.CompletedTask;
} }
} }

View file

@ -31,4 +31,13 @@ internal static class PositionHelpers
x: (ushort)(position.X / MapService.TileSize), x: (ushort)(position.X / MapService.TileSize),
y: (ushort)(position.Y / 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)
);
} }