diff --git a/TanksServer/GameLogic/CollideBulletsWithMap.cs b/TanksServer/GameLogic/CollideBulletsWithMap.cs index 7221af2..f53faa3 100644 --- a/TanksServer/GameLogic/CollideBulletsWithMap.cs +++ b/TanksServer/GameLogic/CollideBulletsWithMap.cs @@ -2,7 +2,7 @@ namespace TanksServer.GameLogic; internal sealed class CollideBulletsWithMap(BulletManager bullets, MapService map) : ITickStep { - public Task TickAsync() + public Task TickAsync(TimeSpan _) { bullets.RemoveWhere(TryHitAndDestroyWall); return Task.CompletedTask; diff --git a/TanksServer/GameLogic/CollideBulletsWithTanks.cs b/TanksServer/GameLogic/CollideBulletsWithTanks.cs index c32d4d0..8c4518a 100644 --- a/TanksServer/GameLogic/CollideBulletsWithTanks.cs +++ b/TanksServer/GameLogic/CollideBulletsWithTanks.cs @@ -6,7 +6,7 @@ internal sealed class CollideBulletsWithTanks( SpawnQueue spawnQueue ) : ITickStep { - public Task TickAsync() + public Task TickAsync(TimeSpan _) { bullets.RemoveWhere(BulletHitsTank); return Task.CompletedTask; diff --git a/TanksServer/GameLogic/GameTickWorker.cs b/TanksServer/GameLogic/GameTickWorker.cs index 25732f1..9f6dd85 100644 --- a/TanksServer/GameLogic/GameTickWorker.cs +++ b/TanksServer/GameLogic/GameTickWorker.cs @@ -9,8 +9,6 @@ internal sealed class GameTickWorker( ILogger logger ) : IHostedService, IDisposable { - private const int TicksPerSecond = 25; - private static readonly TimeSpan TickPacing = TimeSpan.FromMilliseconds(1000 / TicksPerSecond); private readonly CancellationTokenSource _cancellation = new(); private readonly List _steps = steps.ToList(); private Task? _run; @@ -41,14 +39,14 @@ internal sealed class GameTickWorker( while (!_cancellation.IsCancellationRequested) { logger.LogTrace("since last frame: {}", sw.Elapsed); + + var delta = sw.Elapsed; sw.Restart(); foreach (var step in _steps) - await step.TickAsync(); + await step.TickAsync(delta); - var wantedDelay = TickPacing - sw.Elapsed; - if (wantedDelay.Ticks > 0) - await Task.Delay(wantedDelay); + await Task.Delay(1); } } catch (Exception ex) diff --git a/TanksServer/GameLogic/ITickStep.cs b/TanksServer/GameLogic/ITickStep.cs index fb74f23..f2501d7 100644 --- a/TanksServer/GameLogic/ITickStep.cs +++ b/TanksServer/GameLogic/ITickStep.cs @@ -2,5 +2,5 @@ namespace TanksServer.GameLogic; public interface ITickStep { - Task TickAsync(); + Task TickAsync(TimeSpan delta); } diff --git a/TanksServer/GameLogic/MoveBullets.cs b/TanksServer/GameLogic/MoveBullets.cs index de75272..1139266 100644 --- a/TanksServer/GameLogic/MoveBullets.cs +++ b/TanksServer/GameLogic/MoveBullets.cs @@ -2,20 +2,21 @@ namespace TanksServer.GameLogic; internal sealed class MoveBullets(BulletManager bullets, IOptions config) : ITickStep { - public Task TickAsync() + public Task TickAsync(TimeSpan delta) { foreach (var bullet in bullets.GetAll()) - MoveBullet(bullet); + MoveBullet(bullet, delta); return Task.CompletedTask; } - private void MoveBullet(Bullet bullet) + private void MoveBullet(Bullet bullet, TimeSpan delta) { + var speed = config.Value.BulletSpeed * delta.TotalSeconds; var angle = bullet.Rotation * 2 * Math.PI; bullet.Position = new FloatPosition( - bullet.Position.X + Math.Sin(angle) * config.Value.BulletSpeed, - bullet.Position.Y - Math.Cos(angle) * config.Value.BulletSpeed + bullet.Position.X + Math.Sin(angle) * speed, + bullet.Position.Y - Math.Cos(angle) * speed ); } } diff --git a/TanksServer/GameLogic/MoveTanks.cs b/TanksServer/GameLogic/MoveTanks.cs index 138aeee..e23459d 100644 --- a/TanksServer/GameLogic/MoveTanks.cs +++ b/TanksServer/GameLogic/MoveTanks.cs @@ -8,15 +8,15 @@ internal sealed class MoveTanks( { private readonly TanksConfiguration _config = options.Value; - public Task TickAsync() + public Task TickAsync(TimeSpan delta) { foreach (var tank in tanks) - tank.Moved = TryMoveTank(tank); + tank.Moved = TryMoveTank(tank, delta); return Task.CompletedTask; } - private bool TryMoveTank(Tank tank) + private bool TryMoveTank(Tank tank, TimeSpan delta) { var player = tank.Owner; @@ -36,6 +36,8 @@ internal sealed class MoveTanks( return false; } + speed *= delta.TotalSeconds; + var angle = tank.Orientation / 16d * 2d * Math.PI; var newX = tank.Position.X + Math.Sin(angle) * speed; var newY = tank.Position.Y - Math.Cos(angle) * speed; diff --git a/TanksServer/GameLogic/RotateTanks.cs b/TanksServer/GameLogic/RotateTanks.cs index 316700f..5419b4b 100644 --- a/TanksServer/GameLogic/RotateTanks.cs +++ b/TanksServer/GameLogic/RotateTanks.cs @@ -8,7 +8,7 @@ internal sealed class RotateTanks( { private readonly TanksConfiguration _config = options.Value; - public Task TickAsync() + public Task TickAsync(TimeSpan delta) { foreach (var tank in tanks) { @@ -20,10 +20,10 @@ internal sealed class RotateTanks( case { TurnRight: false, TurnLeft: false }: continue; case { TurnLeft: true }: - tank.Rotation -= _config.TurnSpeed; + tank.Rotation -= _config.TurnSpeed * delta.TotalSeconds; break; case { TurnRight: true }: - tank.Rotation += _config.TurnSpeed; + tank.Rotation += _config.TurnSpeed * delta.TotalSeconds; break; } diff --git a/TanksServer/GameLogic/ShootFromTanks.cs b/TanksServer/GameLogic/ShootFromTanks.cs index cbeea48..ade1975 100644 --- a/TanksServer/GameLogic/ShootFromTanks.cs +++ b/TanksServer/GameLogic/ShootFromTanks.cs @@ -8,7 +8,7 @@ internal sealed class ShootFromTanks( { private readonly TanksConfiguration _config = options.Value; - public Task TickAsync() + public Task TickAsync(TimeSpan _) { foreach (var tank in tanks.Where(t => !t.Moved)) Shoot(tank); @@ -28,8 +28,8 @@ internal sealed class ShootFromTanks( var rotation = tank.Orientation / 16d; var angle = rotation * 2d * Math.PI; var position = new FloatPosition( - tank.Position.X + Math.Sin(angle) * _config.BulletSpeed, - tank.Position.Y - Math.Cos(angle) * _config.BulletSpeed + tank.Position.X + Math.Sin(angle) * 6, + tank.Position.Y - Math.Cos(angle) * 6 ); bulletManager.Spawn(new Bullet(tank.Owner, position, rotation)); diff --git a/TanksServer/GameLogic/SpawnNewTanks.cs b/TanksServer/GameLogic/SpawnNewTanks.cs index 586fa73..faf6580 100644 --- a/TanksServer/GameLogic/SpawnNewTanks.cs +++ b/TanksServer/GameLogic/SpawnNewTanks.cs @@ -7,7 +7,7 @@ internal sealed class SpawnNewTanks( BulletManager bullets ) : ITickStep { - public Task TickAsync() + public Task TickAsync(TimeSpan _) { if (!queue.TryDequeueNext(out var player)) return Task.CompletedTask; diff --git a/TanksServer/Graphics/GeneratePixelsTickStep.cs b/TanksServer/Graphics/GeneratePixelsTickStep.cs index 5ddced4..aecfcc7 100644 --- a/TanksServer/Graphics/GeneratePixelsTickStep.cs +++ b/TanksServer/Graphics/GeneratePixelsTickStep.cs @@ -14,7 +14,7 @@ internal sealed class GeneratePixelsTickStep( private readonly PixelGrid _observerPixelGrid = new(MapService.PixelsPerRow, MapService.PixelsPerColumn); private readonly GamePixelGrid _gamePixelGrid = new(MapService.PixelsPerRow, MapService.PixelsPerColumn); - public async Task TickAsync() + public async Task TickAsync(TimeSpan _) { _gamePixelGrid.Clear(); foreach (var step in _drawSteps) diff --git a/TanksServer/appsettings.json b/TanksServer/appsettings.json index 9cd2e66..f086ed1 100644 --- a/TanksServer/appsettings.json +++ b/TanksServer/appsettings.json @@ -21,10 +21,10 @@ "Port": 2342 }, "Tanks": { - "MoveSpeed": 1.5, - "TurnSpeed": 0.02, + "MoveSpeed": 37.5, + "TurnSpeed": 0.5, "ShootDelayMs": 450, - "BulletSpeed": 3 + "BulletSpeed": 75 }, "Players": { "SpawnDelayMs": 3000,