From 359e0235f9f44e51e6dba1f4565f9854b65e99a6 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sun, 14 Apr 2024 22:45:51 +0200 Subject: [PATCH] check walls for spawn --- .../GameLogic/CollideBulletsWithMap.cs | 2 +- TanksServer/GameLogic/MapService.cs | 46 ++++++++++++------- TanksServer/GameLogic/MoveTanks.cs | 2 +- TanksServer/GameLogic/SpawnNewTanks.cs | 4 +- TanksServer/Graphics/DrawMapStep.cs | 2 +- 5 files changed, 34 insertions(+), 22 deletions(-) diff --git a/TanksServer/GameLogic/CollideBulletsWithMap.cs b/TanksServer/GameLogic/CollideBulletsWithMap.cs index 3c3113e..488084c 100644 --- a/TanksServer/GameLogic/CollideBulletsWithMap.cs +++ b/TanksServer/GameLogic/CollideBulletsWithMap.cs @@ -9,5 +9,5 @@ internal sealed class CollideBulletsWithMap(BulletManager bullets, MapService ma } private bool BulletHitsWall(Bullet bullet) => - map.Current.IsCurrentlyWall(bullet.Position.ToPixelPosition()); + map.Current.IsWall(bullet.Position.ToPixelPosition()); } diff --git a/TanksServer/GameLogic/MapService.cs b/TanksServer/GameLogic/MapService.cs index 6337e20..839dd2f 100644 --- a/TanksServer/GameLogic/MapService.cs +++ b/TanksServer/GameLogic/MapService.cs @@ -25,21 +25,19 @@ internal sealed class MapService private static Map LoadMapPng(string file) { - var dict = new Dictionary(); using var image = Image.Load(file); if (image.Width != PixelsPerRow || image.Height != PixelsPerColumn) throw new FileLoadException($"invalid image size in file {file}"); var whitePixel = new Rgba32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue); + var walls = new bool[PixelsPerRow, PixelsPerColumn]; + for (var y = 0; y < image.Height; y++) for (var x = 0; x < image.Width; x++) - { - if (image[x, y] == whitePixel) - dict[new PixelPosition(x, y)] = true; - } + walls[x, y] = image[x, y] == whitePixel; - return new Map(dict); + return new Map(walls); } private static Map LoadMapString(string file) @@ -48,28 +46,44 @@ internal sealed class MapService if (map.Length != TilesPerColumn * TilesPerRow) throw new FileLoadException($"cannot load map {file}: invalid length"); - var dict = new Dictionary(); + var walls = new bool[PixelsPerRow, PixelsPerColumn]; - for (ushort tileY = 0; tileY < MapService.TilesPerColumn; tileY++) - for (ushort tileX = 0; tileX < MapService.TilesPerRow; tileX++) + for (ushort tileX = 0; tileX < TilesPerRow; tileX++) + for (ushort tileY = 0; tileY < TilesPerColumn; tileY++) { var tile = new TilePosition(tileX, tileY); if (map[tileX + tileY * TilesPerRow] != '#') continue; - for (byte pixelInTileY = 0; pixelInTileY < MapService.TileSize; pixelInTileY++) - for (byte pixelInTileX = 0; pixelInTileX < MapService.TileSize; pixelInTileX++) + for (byte pixelInTileX = 0; pixelInTileX < TileSize; pixelInTileX++) + for (byte pixelInTileY = 0; pixelInTileY < TileSize; pixelInTileY++) { - var pixel = tile.ToPixelPosition().GetPixelRelative(pixelInTileX, pixelInTileY); - dict[pixel] = true; + var (x, y) = tile.ToPixelPosition().GetPixelRelative(pixelInTileX, pixelInTileY); + walls[x, y] = true; } } - return new Map(dict); + return new Map(walls); } } -internal sealed class Map(IReadOnlyDictionary walls) +internal sealed class Map(bool[,] walls) { - public bool IsCurrentlyWall(PixelPosition position) => walls.TryGetValue(position, out var value) && value; + public bool IsWall(int x, int y) => walls[x, y]; + + public bool IsWall(PixelPosition position) => walls[position.X, position.Y]; + + public bool IsWall(TilePosition position) + { + var pixel = position.ToPixelPosition(); + + for (short dx = 1; dx < MapService.TilesPerRow - 1; dx++) + for (short dy = 1; dy < MapService.TilesPerColumn - 1; dy++) + { + if (IsWall(pixel.GetPixelRelative(dx, dy))) + return true; + } + + return false; + } } diff --git a/TanksServer/GameLogic/MoveTanks.cs b/TanksServer/GameLogic/MoveTanks.cs index 31da8f0..138aeee 100644 --- a/TanksServer/GameLogic/MoveTanks.cs +++ b/TanksServer/GameLogic/MoveTanks.cs @@ -69,7 +69,7 @@ internal sealed class MoveTanks( for (short x = 0; x < MapService.TileSize; x++) { var pixelToCheck = topLeft.GetPixelRelative(x, y); - if (map.Current.IsCurrentlyWall(pixelToCheck)) + if (map.Current.IsWall(pixelToCheck)) return true; } diff --git a/TanksServer/GameLogic/SpawnNewTanks.cs b/TanksServer/GameLogic/SpawnNewTanks.cs index b523810..586fa73 100644 --- a/TanksServer/GameLogic/SpawnNewTanks.cs +++ b/TanksServer/GameLogic/SpawnNewTanks.cs @@ -28,9 +28,7 @@ internal sealed class SpawnNewTanks( for (ushort y = 1; y < MapService.TilesPerColumn - 1; y++) { var tile = new TilePosition(x, y); - - // TODO: implement lookup for non tile aligned walls - if (map.Current.IsCurrentlyWall(tile.ToPixelPosition())) + if (map.Current.IsWall(tile)) continue; var tilePixelCenter = tile.ToPixelPosition().GetPixelRelative(4, 4).ToFloatPosition(); diff --git a/TanksServer/Graphics/DrawMapStep.cs b/TanksServer/Graphics/DrawMapStep.cs index 8214612..efede99 100644 --- a/TanksServer/Graphics/DrawMapStep.cs +++ b/TanksServer/Graphics/DrawMapStep.cs @@ -11,7 +11,7 @@ internal sealed class DrawMapStep(MapService map) : IDrawStep for (ushort x = 0; x < MapService.PixelsPerRow; x++) { var pixel = new PixelPosition(x, y); - if (!map.Current.IsCurrentlyWall(pixel)) + if (!map.Current.IsWall(pixel)) continue; buffer[x, y] = true; }