implement fast bullets
This commit is contained in:
parent
9ccb7c8df8
commit
9164d90443
|
@ -21,4 +21,6 @@ internal sealed class GameRules
|
||||||
public int SpawnDelayMs { get; set; }
|
public int SpawnDelayMs { get; set; }
|
||||||
|
|
||||||
public int IdleTimeoutMs { get; set; }
|
public int IdleTimeoutMs { get; set; }
|
||||||
|
|
||||||
|
public byte MagazineSize { get; set; } = 5;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ internal sealed class MapEntityManager(
|
||||||
IOptions<GameRules> options
|
IOptions<GameRules> options
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
private readonly GameRules _rules = options.Value;
|
||||||
private readonly HashSet<Bullet> _bullets = [];
|
private readonly HashSet<Bullet> _bullets = [];
|
||||||
private readonly HashSet<PowerUp> _powerUps = [];
|
private readonly HashSet<PowerUp> _powerUps = [];
|
||||||
private readonly Dictionary<Player, Tank> _playerTanks = [];
|
private readonly Dictionary<Player, Tank> _playerTanks = [];
|
||||||
|
@ -15,24 +16,31 @@ internal sealed class MapEntityManager(
|
||||||
public IEnumerable<Tank> Tanks => _playerTanks.Values;
|
public IEnumerable<Tank> Tanks => _playerTanks.Values;
|
||||||
public IEnumerable<PowerUp> PowerUps => _powerUps;
|
public IEnumerable<PowerUp> PowerUps => _powerUps;
|
||||||
|
|
||||||
public void SpawnBullet(Player tankOwner, FloatPosition position, double rotation, bool isExplosive)
|
public void SpawnBullet(Player tankOwner, FloatPosition position, double rotation, MagazineType type)
|
||||||
=> _bullets.Add(new Bullet
|
{
|
||||||
|
var speed = _rules.BulletSpeed * (type.HasFlag(MagazineType.Fast) ? 2 : 1);
|
||||||
|
_bullets.Add(new Bullet
|
||||||
{
|
{
|
||||||
Owner = tankOwner,
|
Owner = tankOwner,
|
||||||
Position = position,
|
Position = position,
|
||||||
Rotation = rotation,
|
Rotation = rotation,
|
||||||
IsExplosive = isExplosive,
|
IsExplosive = type.HasFlag(MagazineType.Explosive),
|
||||||
Timeout = DateTime.Now + _bulletTimeout,
|
Timeout = DateTime.Now + _bulletTimeout,
|
||||||
OwnerCollisionAfter = DateTime.Now + TimeSpan.FromSeconds(1),
|
OwnerCollisionAfter = DateTime.Now + TimeSpan.FromSeconds(1),
|
||||||
|
Speed = speed
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public void RemoveWhere(Predicate<Bullet> predicate) => _bullets.RemoveWhere(predicate);
|
public void RemoveWhere(Predicate<Bullet> predicate) => _bullets.RemoveWhere(predicate);
|
||||||
|
|
||||||
public void SpawnTank(Player player)
|
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;
|
_playerTanks[player] = tank;
|
||||||
logger.LogInformation("Tank added for player {}", player.Name);
|
logger.LogInformation("Tank added for player {}", player.Name);
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
namespace TanksServer.GameLogic;
|
namespace TanksServer.GameLogic;
|
||||||
|
|
||||||
internal sealed class MoveBullets(
|
internal sealed class MoveBullets(MapEntityManager entityManager) : ITickStep
|
||||||
MapEntityManager entityManager,
|
|
||||||
IOptions<GameRules> config
|
|
||||||
) : ITickStep
|
|
||||||
{
|
{
|
||||||
public ValueTask TickAsync(TimeSpan delta)
|
public ValueTask TickAsync(TimeSpan delta)
|
||||||
{
|
{
|
||||||
|
@ -13,9 +10,9 @@ internal sealed class MoveBullets(
|
||||||
return ValueTask.CompletedTask;
|
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;
|
var angle = bullet.Rotation * 2 * Math.PI;
|
||||||
bullet.Position = new FloatPosition(
|
bullet.Position = new FloatPosition(
|
||||||
bullet.Position.X + Math.Sin(angle) * speed,
|
bullet.Position.X + Math.Sin(angle) * speed,
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace TanksServer.GameLogic;
|
namespace TanksServer.GameLogic;
|
||||||
|
|
||||||
internal sealed class ShootFromTanks(
|
internal sealed class ShootFromTanks(
|
||||||
|
@ -32,8 +30,7 @@ internal sealed class ShootFromTanks(
|
||||||
UsedBullets = (byte)(tank.Magazine.UsedBullets + 1)
|
UsedBullets = (byte)(tank.Magazine.UsedBullets + 1)
|
||||||
};
|
};
|
||||||
|
|
||||||
var explosive = tank.Magazine.Type.HasFlag(MagazineType.Explosive);
|
|
||||||
tank.Owner.Scores.ShotsFired++;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,4 +15,6 @@ internal sealed class Bullet : IMapEntity
|
||||||
public PixelBounds Bounds => new(Position.ToPixelPosition(), Position.ToPixelPosition());
|
public PixelBounds Bounds => new(Position.ToPixelPosition(), Position.ToPixelPosition());
|
||||||
|
|
||||||
internal required DateTime OwnerCollisionAfter { get; init; }
|
internal required DateTime OwnerCollisionAfter { get; init; }
|
||||||
|
|
||||||
|
public required double Speed { get; init; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,11 @@ namespace TanksServer.Models;
|
||||||
[Flags]
|
[Flags]
|
||||||
internal enum MagazineType
|
internal enum MagazineType
|
||||||
{
|
{
|
||||||
Basic = 1 << 0,
|
Basic = 0,
|
||||||
Fast = 1 << 1,
|
Fast = 1 << 0,
|
||||||
Explosive = 1 << 2,
|
Explosive = 1 << 1,
|
||||||
Smart = 1 << 3,
|
Smart = 1 << 2,
|
||||||
Mine = 1 << 4,
|
Mine = 1 << 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
internal readonly record struct Magazine(MagazineType Type, byte UsedBullets, byte MaxBullets)
|
internal readonly record struct Magazine(MagazineType Type, byte UsedBullets, byte MaxBullets)
|
||||||
|
|
|
@ -3,11 +3,11 @@ using TanksServer.GameLogic;
|
||||||
|
|
||||||
namespace TanksServer.Models;
|
namespace TanksServer.Models;
|
||||||
|
|
||||||
internal sealed class Tank(Player player, FloatPosition spawnPosition) : IMapEntity
|
internal sealed class Tank : IMapEntity
|
||||||
{
|
{
|
||||||
private double _rotation;
|
private double _rotation;
|
||||||
|
|
||||||
public Player Owner { get; } = player;
|
public required Player Owner { get; init; }
|
||||||
|
|
||||||
public double Rotation
|
public double Rotation
|
||||||
{
|
{
|
||||||
|
@ -24,11 +24,11 @@ internal sealed class Tank(Player player, FloatPosition spawnPosition) : IMapEnt
|
||||||
|
|
||||||
public bool Moving { get; set; }
|
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 PixelBounds Bounds => Position.GetBoundsForCenter(MapService.TileSize);
|
||||||
|
|
||||||
public int Orientation => (int)Math.Round(Rotation * 16) % 16;
|
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; }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue