From dec571d8c17d8cf918d5db98fb429784131d5f24 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Tue, 16 Apr 2024 18:55:34 +0200 Subject: [PATCH] destructible walls --- .../GameLogic/CollideBulletsWithMap.cs | 13 +++- TanksServer/GameLogic/MapService.cs | 35 +++++++---- .../Interactivity/AppSerializerContext.cs | 2 +- TanksServer/Program.cs | 17 ++---- TanksServer/appsettings.json | 60 +++++++++---------- 5 files changed, 72 insertions(+), 55 deletions(-) diff --git a/TanksServer/GameLogic/CollideBulletsWithMap.cs b/TanksServer/GameLogic/CollideBulletsWithMap.cs index 488084c..7221af2 100644 --- a/TanksServer/GameLogic/CollideBulletsWithMap.cs +++ b/TanksServer/GameLogic/CollideBulletsWithMap.cs @@ -4,10 +4,17 @@ internal sealed class CollideBulletsWithMap(BulletManager bullets, MapService ma { public Task TickAsync() { - bullets.RemoveWhere(BulletHitsWall); + bullets.RemoveWhere(TryHitAndDestroyWall); return Task.CompletedTask; } - private bool BulletHitsWall(Bullet bullet) => - map.Current.IsWall(bullet.Position.ToPixelPosition()); + private bool TryHitAndDestroyWall(Bullet bullet) + { + var pixel = bullet.Position.ToPixelPosition(); + if (!map.Current.IsWall(pixel)) + return false; + + map.Current.DestroyWallAt(pixel); + return true; + } } diff --git a/TanksServer/GameLogic/MapService.cs b/TanksServer/GameLogic/MapService.cs index ce78b49..600e58b 100644 --- a/TanksServer/GameLogic/MapService.cs +++ b/TanksServer/GameLogic/MapService.cs @@ -12,20 +12,25 @@ internal sealed class MapService public const ushort PixelsPerRow = TilesPerRow * TileSize; public const ushort PixelsPerColumn = TilesPerColumn * TileSize; - public Map[] All { get; } + private readonly Dictionary _maps = new(); - public Map Current { get; set; } + public IEnumerable MapNames => _maps.Keys; + + public Map Current { get; private set; } public MapService() { - var textMaps = Directory.EnumerateFiles("./assets/maps/", "*.txt").Select(LoadMapString); - var pngMaps = Directory.EnumerateFiles("./assets/maps/", "*.png").Select(LoadMapPng); + foreach (var file in Directory.EnumerateFiles("./assets/maps/", "*.txt")) + LoadMapString(file); + foreach (var file in Directory.EnumerateFiles("./assets/maps/", "*.png")) + LoadMapPng(file); - All = textMaps.Concat(pngMaps).ToArray(); - Current = All[Random.Shared.Next(All.Length)]; + var chosenMapIndex = Random.Shared.Next(_maps.Count); + var chosenMapName = _maps.Keys.Skip(chosenMapIndex).First(); + Current = new Map(chosenMapName, _maps[chosenMapName]); } - private static Map LoadMapPng(string file) + private void LoadMapPng(string file) { using var image = Image.Load(file); @@ -39,10 +44,10 @@ internal sealed class MapService for (var x = 0; x < image.Width; x++) walls[x, y] = image[x, y] == whitePixel; - return new Map(Path.GetFileName(file),walls); + _maps.Add(Path.GetFileName(file), walls); } - private static Map LoadMapString(string file) + private void LoadMapString(string file) { var map = File.ReadAllText(file).ReplaceLineEndings(string.Empty).Trim(); if (map.Length != TilesPerColumn * TilesPerRow) @@ -65,7 +70,15 @@ internal sealed class MapService } } - return new Map(Path.GetFileName(file), walls); + _maps.Add(Path.GetFileName(file), walls); + } + + public bool TrySwitchTo(string name) + { + if (!_maps.TryGetValue(name, out var mapData)) + return false; + Current = new Map(name, mapData); + return true; } } @@ -90,4 +103,6 @@ internal sealed class Map(string name, bool[,] walls) return false; } + + public void DestroyWallAt(PixelPosition pixel) => walls[pixel.X, pixel.Y] = false; } diff --git a/TanksServer/Interactivity/AppSerializerContext.cs b/TanksServer/Interactivity/AppSerializerContext.cs index e7e5ad2..da1cbbd 100644 --- a/TanksServer/Interactivity/AppSerializerContext.cs +++ b/TanksServer/Interactivity/AppSerializerContext.cs @@ -6,5 +6,5 @@ namespace TanksServer.Interactivity; [JsonSerializable(typeof(IEnumerable))] [JsonSerializable(typeof(Guid))] [JsonSerializable(typeof(NameId))] -[JsonSerializable(typeof(Dictionary))] +[JsonSerializable(typeof(IEnumerable))] internal sealed partial class AppSerializerContext : JsonSerializerContext; diff --git a/TanksServer/Program.cs b/TanksServer/Program.cs index 3a972a0..934443e 100644 --- a/TanksServer/Program.cs +++ b/TanksServer/Program.cs @@ -73,19 +73,14 @@ public static class Program return Results.Empty; }); - app.MapGet("/map", () => - { - var dict = mapService.All - .Select((m, i) => (m.Name, i)) - .ToDictionary(pair => pair.i, pair => pair.Name); - return dict; - }); + app.MapGet("/map", () =>mapService.MapNames); - app.MapPost("/map", ([FromQuery] int index) => + app.MapPost("/map", ([FromQuery] string name) => { - if (index < 0 || index >= mapService.All.Length) - return Results.NotFound("index does not exist"); - mapService.Current = mapService.All[index]; + if (string.IsNullOrWhiteSpace(name)) + return Results.BadRequest("invalid map name"); + if (!mapService.TrySwitchTo(name)) + return Results.NotFound("map with name not found"); return Results.Ok(); }); diff --git a/TanksServer/appsettings.json b/TanksServer/appsettings.json index 54fa331..9cd2e66 100644 --- a/TanksServer/appsettings.json +++ b/TanksServer/appsettings.json @@ -1,33 +1,33 @@ { - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning", - "TanksServer": "Debug", - "Microsoft.AspNetCore.HttpLogging": "Information" - } - }, - "AllowedHosts": "*", - "Kestrel": { - "Endpoints": { - "Http": { - "Url": "http://localhost:3000" - } - } - }, - "ServicePointDisplay": { - "Enable": true, - "Hostname": "172.23.42.29", - "Port": 2342 - }, - "Tanks": { - "MoveSpeed": 1.5, - "TurnSpeed": 0.02, - "ShootDelayMs": 450, - "BulletSpeed":4 - }, - "Players": { - "SpawnDelayMs": 3000, - "IdleTimeoutMs": 30000 + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning", + "TanksServer": "Debug", + "Microsoft.AspNetCore.HttpLogging": "Information" } + }, + "AllowedHosts": "*", + "Kestrel": { + "Endpoints": { + "Http": { + "Url": "http://localhost:3000" + } + } + }, + "ServicePointDisplay": { + "Enable": true, + "Hostname": "172.23.42.29", + "Port": 2342 + }, + "Tanks": { + "MoveSpeed": 1.5, + "TurnSpeed": 0.02, + "ShootDelayMs": 450, + "BulletSpeed": 3 + }, + "Players": { + "SpawnDelayMs": 3000, + "IdleTimeoutMs": 30000 + } }