implement fast bullets

This commit is contained in:
Vinzenz Schroeter 2024-04-29 16:59:37 +02:00
parent 9ccb7c8df8
commit 9164d90443
7 changed files with 30 additions and 24 deletions

View file

@ -21,4 +21,6 @@ internal sealed class GameRules
public int SpawnDelayMs { get; set; }
public int IdleTimeoutMs { get; set; }
public byte MagazineSize { get; set; } = 5;
}

View file

@ -6,6 +6,7 @@ internal sealed class MapEntityManager(
IOptions<GameRules> options
)
{
private readonly GameRules _rules = options.Value;
private readonly HashSet<Bullet> _bullets = [];
private readonly HashSet<PowerUp> _powerUps = [];
private readonly Dictionary<Player, Tank> _playerTanks = [];
@ -15,24 +16,31 @@ internal sealed class MapEntityManager(
public IEnumerable<Tank> Tanks => _playerTanks.Values;
public IEnumerable<PowerUp> PowerUps => _powerUps;
public void SpawnBullet(Player tankOwner, FloatPosition position, double rotation, bool isExplosive)
=> _bullets.Add(new Bullet
public void SpawnBullet(Player tankOwner, FloatPosition position, double rotation, MagazineType type)
{
var speed = _rules.BulletSpeed * (type.HasFlag(MagazineType.Fast) ? 2 : 1);
_bullets.Add(new Bullet
{
Owner = tankOwner,
Position = position,
Rotation = rotation,
IsExplosive = isExplosive,
IsExplosive = type.HasFlag(MagazineType.Explosive),
Timeout = DateTime.Now + _bulletTimeout,
OwnerCollisionAfter = DateTime.Now + TimeSpan.FromSeconds(1),
Speed = speed
});
}
public void RemoveWhere(Predicate<Bullet> predicate) => _bullets.RemoveWhere(predicate);
public void SpawnTank(Player player)
{
var tank = new Tank(player, ChooseSpawnPosition())
var tank = new Tank
{
Rotation = Random.Shared.NextDouble()
Owner = player,
Position = ChooseSpawnPosition(),
Rotation = Random.Shared.NextDouble(),
Magazine = new Magazine(MagazineType.Basic, 0, _rules.MagazineSize)
};
_playerTanks[player] = tank;
logger.LogInformation("Tank added for player {}", player.Name);

View file

@ -1,9 +1,6 @@
namespace TanksServer.GameLogic;
internal sealed class MoveBullets(
MapEntityManager entityManager,
IOptions<GameRules> config
) : ITickStep
internal sealed class MoveBullets(MapEntityManager entityManager) : ITickStep
{
public ValueTask TickAsync(TimeSpan delta)
{
@ -13,9 +10,9 @@ internal sealed class MoveBullets(
return ValueTask.CompletedTask;
}
private void MoveBullet(Bullet bullet, TimeSpan delta)
private static void MoveBullet(Bullet bullet, TimeSpan delta)
{
var speed = config.Value.BulletSpeed * delta.TotalSeconds;
var speed = bullet.Speed * delta.TotalSeconds;
var angle = bullet.Rotation * 2 * Math.PI;
bullet.Position = new FloatPosition(
bullet.Position.X + Math.Sin(angle) * speed,

View file

@ -1,5 +1,3 @@
using System.Diagnostics;
namespace TanksServer.GameLogic;
internal sealed class ShootFromTanks(
@ -32,8 +30,7 @@ internal sealed class ShootFromTanks(
UsedBullets = (byte)(tank.Magazine.UsedBullets + 1)
};
var explosive = tank.Magazine.Type.HasFlag(MagazineType.Explosive);
tank.Owner.Scores.ShotsFired++;
entityManager.SpawnBullet(tank.Owner, tank.Position, tank.Orientation / 16d, explosive);
entityManager.SpawnBullet(tank.Owner, tank.Position, tank.Orientation / 16d, tank.Magazine.Type);
}
}

View file

@ -15,4 +15,6 @@ internal sealed class Bullet : IMapEntity
public PixelBounds Bounds => new(Position.ToPixelPosition(), Position.ToPixelPosition());
internal required DateTime OwnerCollisionAfter { get; init; }
public required double Speed { get; init; }
}

View file

@ -5,11 +5,11 @@ namespace TanksServer.Models;
[Flags]
internal enum MagazineType
{
Basic = 1 << 0,
Fast = 1 << 1,
Explosive = 1 << 2,
Smart = 1 << 3,
Mine = 1 << 4,
Basic = 0,
Fast = 1 << 0,
Explosive = 1 << 1,
Smart = 1 << 2,
Mine = 1 << 3,
}
internal readonly record struct Magazine(MagazineType Type, byte UsedBullets, byte MaxBullets)

View file

@ -3,11 +3,11 @@ using TanksServer.GameLogic;
namespace TanksServer.Models;
internal sealed class Tank(Player player, FloatPosition spawnPosition) : IMapEntity
internal sealed class Tank : IMapEntity
{
private double _rotation;
public Player Owner { get; } = player;
public required Player Owner { get; init; }
public double Rotation
{
@ -24,11 +24,11 @@ internal sealed class Tank(Player player, FloatPosition spawnPosition) : IMapEnt
public bool Moving { get; set; }
public FloatPosition Position { get; set; } = spawnPosition;
public required FloatPosition Position { get; set; }
public PixelBounds Bounds => Position.GetBoundsForCenter(MapService.TileSize);
public int Orientation => (int)Math.Round(Rotation * 16) % 16;
public Magazine Magazine { get; set; } = new(MagazineType.Basic, 0, 5);
public required Magazine Magazine { get; set; }
}