tanks collide with each other
This commit is contained in:
parent
461a9139c2
commit
89494ef495
|
@ -10,26 +10,26 @@ internal sealed class MapService
|
||||||
|
|
||||||
private readonly string _map =
|
private readonly string _map =
|
||||||
"""
|
"""
|
||||||
#############..###################.#########
|
#######.##########################.#########
|
||||||
#...................##.....................#
|
#...................##.....................#
|
||||||
#...................##.....................#
|
#...................##.....................#
|
||||||
#.....####......................####.......#
|
#.....####......................####.......#
|
||||||
#..........................................#
|
#..........................................#
|
||||||
#............###...........###.............#
|
#............###...........###.............#
|
||||||
#............#...............#.............#
|
#............#...............#.............#
|
||||||
#...##.......#...............#......##.....#
|
#...##.......#....#....#.....#......##.....#
|
||||||
#....#..............................#......#
|
#....#..............................#......#
|
||||||
#....#..##......................##..#......#
|
.....#...#......................#...#.......
|
||||||
#....#..##......................##..#......#
|
.....#...#......................#...#.......
|
||||||
#....#..............................#......#
|
#....#..............................#......#
|
||||||
#...##.......#...............#......##.....#
|
#...##.......#....#....#.....#......##.....#
|
||||||
#............#...............#.............#
|
#............#...............#.............#
|
||||||
#............###...........###.............#
|
#............###...........###.............#
|
||||||
#..........................................#
|
#..........................................#
|
||||||
#.....####......................####.......#
|
#.....####......................####.......#
|
||||||
#...................##.....................#
|
#...................##.....................#
|
||||||
#...................##.....................#
|
#...................##.....................#
|
||||||
#############..###################.#########
|
#######.##########################.#########
|
||||||
"""
|
"""
|
||||||
.ReplaceLineEndings(string.Empty);
|
.ReplaceLineEndings(string.Empty);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
);
|
||||||
}
|
}
|
Loading…
Reference in a new issue