delta time

This commit is contained in:
Vinzenz Schroeter 2024-04-16 19:40:08 +02:00
parent dec571d8c1
commit e16d4b1c1f
11 changed files with 29 additions and 28 deletions

View file

@ -2,7 +2,7 @@ namespace TanksServer.GameLogic;
internal sealed class CollideBulletsWithMap(BulletManager bullets, MapService map) : ITickStep internal sealed class CollideBulletsWithMap(BulletManager bullets, MapService map) : ITickStep
{ {
public Task TickAsync() public Task TickAsync(TimeSpan _)
{ {
bullets.RemoveWhere(TryHitAndDestroyWall); bullets.RemoveWhere(TryHitAndDestroyWall);
return Task.CompletedTask; return Task.CompletedTask;

View file

@ -6,7 +6,7 @@ internal sealed class CollideBulletsWithTanks(
SpawnQueue spawnQueue SpawnQueue spawnQueue
) : ITickStep ) : ITickStep
{ {
public Task TickAsync() public Task TickAsync(TimeSpan _)
{ {
bullets.RemoveWhere(BulletHitsTank); bullets.RemoveWhere(BulletHitsTank);
return Task.CompletedTask; return Task.CompletedTask;

View file

@ -9,8 +9,6 @@ internal sealed class GameTickWorker(
ILogger<GameTickWorker> logger ILogger<GameTickWorker> logger
) : IHostedService, IDisposable ) : IHostedService, IDisposable
{ {
private const int TicksPerSecond = 25;
private static readonly TimeSpan TickPacing = TimeSpan.FromMilliseconds(1000 / TicksPerSecond);
private readonly CancellationTokenSource _cancellation = new(); private readonly CancellationTokenSource _cancellation = new();
private readonly List<ITickStep> _steps = steps.ToList(); private readonly List<ITickStep> _steps = steps.ToList();
private Task? _run; private Task? _run;
@ -41,14 +39,14 @@ internal sealed class GameTickWorker(
while (!_cancellation.IsCancellationRequested) while (!_cancellation.IsCancellationRequested)
{ {
logger.LogTrace("since last frame: {}", sw.Elapsed); logger.LogTrace("since last frame: {}", sw.Elapsed);
var delta = sw.Elapsed;
sw.Restart(); sw.Restart();
foreach (var step in _steps) foreach (var step in _steps)
await step.TickAsync(); await step.TickAsync(delta);
var wantedDelay = TickPacing - sw.Elapsed; await Task.Delay(1);
if (wantedDelay.Ticks > 0)
await Task.Delay(wantedDelay);
} }
} }
catch (Exception ex) catch (Exception ex)

View file

@ -2,5 +2,5 @@ namespace TanksServer.GameLogic;
public interface ITickStep public interface ITickStep
{ {
Task TickAsync(); Task TickAsync(TimeSpan delta);
} }

View file

@ -2,20 +2,21 @@ namespace TanksServer.GameLogic;
internal sealed class MoveBullets(BulletManager bullets, IOptions<TanksConfiguration> config) : ITickStep internal sealed class MoveBullets(BulletManager bullets, IOptions<TanksConfiguration> config) : ITickStep
{ {
public Task TickAsync() public Task TickAsync(TimeSpan delta)
{ {
foreach (var bullet in bullets.GetAll()) foreach (var bullet in bullets.GetAll())
MoveBullet(bullet); MoveBullet(bullet, delta);
return Task.CompletedTask; 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; var angle = bullet.Rotation * 2 * Math.PI;
bullet.Position = new FloatPosition( bullet.Position = new FloatPosition(
bullet.Position.X + Math.Sin(angle) * config.Value.BulletSpeed, bullet.Position.X + Math.Sin(angle) * speed,
bullet.Position.Y - Math.Cos(angle) * config.Value.BulletSpeed bullet.Position.Y - Math.Cos(angle) * speed
); );
} }
} }

View file

@ -8,15 +8,15 @@ internal sealed class MoveTanks(
{ {
private readonly TanksConfiguration _config = options.Value; private readonly TanksConfiguration _config = options.Value;
public Task TickAsync() public Task TickAsync(TimeSpan delta)
{ {
foreach (var tank in tanks) foreach (var tank in tanks)
tank.Moved = TryMoveTank(tank); tank.Moved = TryMoveTank(tank, delta);
return Task.CompletedTask; return Task.CompletedTask;
} }
private bool TryMoveTank(Tank tank) private bool TryMoveTank(Tank tank, TimeSpan delta)
{ {
var player = tank.Owner; var player = tank.Owner;
@ -36,6 +36,8 @@ internal sealed class MoveTanks(
return false; return false;
} }
speed *= delta.TotalSeconds;
var angle = tank.Orientation / 16d * 2d * Math.PI; var angle = tank.Orientation / 16d * 2d * Math.PI;
var newX = tank.Position.X + Math.Sin(angle) * speed; var newX = tank.Position.X + Math.Sin(angle) * speed;
var newY = tank.Position.Y - Math.Cos(angle) * speed; var newY = tank.Position.Y - Math.Cos(angle) * speed;

View file

@ -8,7 +8,7 @@ internal sealed class RotateTanks(
{ {
private readonly TanksConfiguration _config = options.Value; private readonly TanksConfiguration _config = options.Value;
public Task TickAsync() public Task TickAsync(TimeSpan delta)
{ {
foreach (var tank in tanks) foreach (var tank in tanks)
{ {
@ -20,10 +20,10 @@ internal sealed class RotateTanks(
case { TurnRight: false, TurnLeft: false }: case { TurnRight: false, TurnLeft: false }:
continue; continue;
case { TurnLeft: true }: case { TurnLeft: true }:
tank.Rotation -= _config.TurnSpeed; tank.Rotation -= _config.TurnSpeed * delta.TotalSeconds;
break; break;
case { TurnRight: true }: case { TurnRight: true }:
tank.Rotation += _config.TurnSpeed; tank.Rotation += _config.TurnSpeed * delta.TotalSeconds;
break; break;
} }

View file

@ -8,7 +8,7 @@ internal sealed class ShootFromTanks(
{ {
private readonly TanksConfiguration _config = options.Value; private readonly TanksConfiguration _config = options.Value;
public Task TickAsync() public Task TickAsync(TimeSpan _)
{ {
foreach (var tank in tanks.Where(t => !t.Moved)) foreach (var tank in tanks.Where(t => !t.Moved))
Shoot(tank); Shoot(tank);
@ -28,8 +28,8 @@ internal sealed class ShootFromTanks(
var rotation = tank.Orientation / 16d; var rotation = tank.Orientation / 16d;
var angle = rotation * 2d * Math.PI; var angle = rotation * 2d * Math.PI;
var position = new FloatPosition( var position = new FloatPosition(
tank.Position.X + Math.Sin(angle) * _config.BulletSpeed, tank.Position.X + Math.Sin(angle) * 6,
tank.Position.Y - Math.Cos(angle) * _config.BulletSpeed tank.Position.Y - Math.Cos(angle) * 6
); );
bulletManager.Spawn(new Bullet(tank.Owner, position, rotation)); bulletManager.Spawn(new Bullet(tank.Owner, position, rotation));

View file

@ -7,7 +7,7 @@ internal sealed class SpawnNewTanks(
BulletManager bullets BulletManager bullets
) : ITickStep ) : ITickStep
{ {
public Task TickAsync() public Task TickAsync(TimeSpan _)
{ {
if (!queue.TryDequeueNext(out var player)) if (!queue.TryDequeueNext(out var player))
return Task.CompletedTask; return Task.CompletedTask;

View file

@ -14,7 +14,7 @@ internal sealed class GeneratePixelsTickStep(
private readonly PixelGrid _observerPixelGrid = new(MapService.PixelsPerRow, MapService.PixelsPerColumn); private readonly PixelGrid _observerPixelGrid = new(MapService.PixelsPerRow, MapService.PixelsPerColumn);
private readonly GamePixelGrid _gamePixelGrid = 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(); _gamePixelGrid.Clear();
foreach (var step in _drawSteps) foreach (var step in _drawSteps)

View file

@ -21,10 +21,10 @@
"Port": 2342 "Port": 2342
}, },
"Tanks": { "Tanks": {
"MoveSpeed": 1.5, "MoveSpeed": 37.5,
"TurnSpeed": 0.02, "TurnSpeed": 0.5,
"ShootDelayMs": 450, "ShootDelayMs": 450,
"BulletSpeed": 3 "BulletSpeed": 75
}, },
"Players": { "Players": {
"SpawnDelayMs": 3000, "SpawnDelayMs": 3000,