show tank infos in client
This commit is contained in:
		
							parent
							
								
									a50a9770c9
								
							
						
					
					
						commit
						0f4eec6343
					
				
					 9 changed files with 73 additions and 26 deletions
				
			
		|  | @ -11,13 +11,13 @@ internal sealed class CollideBullets( | |||
| 
 | ||||
|     public Task TickAsync(TimeSpan _) | ||||
|     { | ||||
|         entityManager.RemoveBulletsWhere(BulletHitsTank); | ||||
|         entityManager.RemoveBulletsWhere(TryHitAndDestroyWall); | ||||
|         entityManager.RemoveBulletsWhere(TimeoutBullet); | ||||
|         entityManager.RemoveWhere(BulletHitsTank); | ||||
|         entityManager.RemoveWhere(BulletHitsWall); | ||||
|         entityManager.RemoveWhere(BulletTimesOut); | ||||
|         return Task.CompletedTask; | ||||
|     } | ||||
| 
 | ||||
|     private bool TimeoutBullet(Bullet bullet) | ||||
|     private bool BulletTimesOut(Bullet bullet) | ||||
|     { | ||||
|         if (bullet.Timeout > DateTime.Now) | ||||
|             return false; | ||||
|  | @ -27,7 +27,7 @@ internal sealed class CollideBullets( | |||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     private bool TryHitAndDestroyWall(Bullet bullet) | ||||
|     private bool BulletHitsWall(Bullet bullet) | ||||
|     { | ||||
|         var pixel = bullet.Position.ToPixelPosition(); | ||||
|         if (!map.Current.IsWall(pixel)) | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ internal sealed class MapEntityManager( | |||
|     private readonly HashSet<Bullet> _bullets = []; | ||||
|     private readonly HashSet<Tank> _tanks = []; | ||||
|     private readonly HashSet<PowerUp> _powerUps = []; | ||||
|     private readonly Dictionary<Player, Tank> _playerTanks = []; | ||||
|     private readonly TimeSpan _bulletTimeout = TimeSpan.FromMilliseconds(options.Value.BulletTimeoutMs); | ||||
| 
 | ||||
|     public IEnumerable<Bullet> Bullets => _bullets; | ||||
|  | @ -31,14 +32,16 @@ internal sealed class MapEntityManager( | |||
|             OwnerCollisionAfter = DateTime.Now + TimeSpan.FromSeconds(1), | ||||
|         }); | ||||
| 
 | ||||
|     public void RemoveBulletsWhere(Predicate<Bullet> predicate) => _bullets.RemoveWhere(predicate); | ||||
|     public void RemoveWhere(Predicate<Bullet> predicate) => _bullets.RemoveWhere(predicate); | ||||
| 
 | ||||
|     public void SpawnTank(Player player) | ||||
|     { | ||||
|         _tanks.Add(new Tank(player, ChooseSpawnPosition()) | ||||
|         var tank = new Tank(player, ChooseSpawnPosition()) | ||||
|         { | ||||
|             Rotation = Random.Shared.NextDouble() | ||||
|         }); | ||||
|         }; | ||||
|         _tanks.Add(tank); | ||||
|         _playerTanks[player] = tank; | ||||
|         logger.LogInformation("Tank added for player {}", player.Id); | ||||
|     } | ||||
| 
 | ||||
|  | @ -50,6 +53,7 @@ internal sealed class MapEntityManager( | |||
|     { | ||||
|         logger.LogInformation("Tank removed for player {}", tank.Owner.Id); | ||||
|         _tanks.Remove(tank); | ||||
|         _playerTanks.Remove(tank.Owner); | ||||
|     } | ||||
| 
 | ||||
|     public FloatPosition ChooseSpawnPosition() | ||||
|  | @ -75,4 +79,6 @@ internal sealed class MapEntityManager( | |||
|         var min = candidates.MaxBy(pair => pair.Value).Key; | ||||
|         return min.ToPixelPosition().GetPixelRelative(4, 4).ToFloatPosition(); | ||||
|     } | ||||
| 
 | ||||
|     public Tank? GetCurrentTankOfPlayer(Player player) => _playerTanks.GetValueOrDefault(player); | ||||
| } | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ internal sealed class MoveTanks( | |||
|     public Task TickAsync(TimeSpan delta) | ||||
|     { | ||||
|         foreach (var tank in entityManager.Tanks) | ||||
|             tank.Moved = TryMoveTank(tank, delta); | ||||
|             tank.Moving = TryMoveTank(tank, delta); | ||||
| 
 | ||||
|         return Task.CompletedTask; | ||||
|     } | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ internal sealed class ShootFromTanks( | |||
| 
 | ||||
|     public Task TickAsync(TimeSpan _) | ||||
|     { | ||||
|         foreach (var tank in entityManager.Tanks.Where(t => !t.Moved)) | ||||
|         foreach (var tank in entityManager.Tanks.Where(t => !t.Moving)) | ||||
|             Shoot(tank); | ||||
| 
 | ||||
|         return Task.CompletedTask; | ||||
|  |  | |||
|  | @ -1,12 +1,14 @@ | |||
| using System.Net.WebSockets; | ||||
| using System.Text.Json; | ||||
| using TanksServer.GameLogic; | ||||
| 
 | ||||
| namespace TanksServer.Interactivity; | ||||
| 
 | ||||
| internal sealed class PlayerInfoConnection( | ||||
|     Player player, | ||||
|     ILogger logger, | ||||
|     WebSocket rawSocket | ||||
|     WebSocket rawSocket, | ||||
|     MapEntityManager entityManager | ||||
| ) : WebsocketServerConnection(logger, new ByteChannelWebSocket(rawSocket, logger, 0)), IDisposable | ||||
| { | ||||
|     private readonly SemaphoreSlim _wantedFrames = new(1); | ||||
|  | @ -45,7 +47,11 @@ internal sealed class PlayerInfoConnection( | |||
| 
 | ||||
|     private byte[]? GetMessageToSend() | ||||
|     { | ||||
|         var info = new PlayerInfo(player.Name, player.Scores, player.Controls); | ||||
|         var tank = entityManager.GetCurrentTankOfPlayer(player); | ||||
|         var tankInfo = tank != null | ||||
|             ? new TankInfo(tank.Orientation, tank.ExplosiveBullets, tank.Position.ToPixelPosition(), tank.Moving) | ||||
|             : null; | ||||
|         var info = new PlayerInfo(player.Name, player.Scores, player.Controls, tankInfo); | ||||
|         var response = JsonSerializer.SerializeToUtf8Bytes(info, _context.PlayerInfo); | ||||
| 
 | ||||
|         if (response.SequenceEqual(_lastMessage)) | ||||
|  |  | |||
|  | @ -7,7 +7,8 @@ namespace TanksServer.Interactivity; | |||
| internal sealed class PlayerServer( | ||||
|     ILogger<PlayerServer> logger, | ||||
|     ILogger<PlayerInfoConnection> connectionLogger, | ||||
|     TankSpawnQueue tankSpawnQueue | ||||
|     TankSpawnQueue tankSpawnQueue, | ||||
|     MapEntityManager entityManager | ||||
| ) : WebsocketServer<PlayerInfoConnection>(logger), ITickStep | ||||
| { | ||||
|     private readonly ConcurrentDictionary<string, Player> _players = new(); | ||||
|  | @ -46,7 +47,7 @@ internal sealed class PlayerServer( | |||
|     public IEnumerable<Player> GetAll() => _players.Values; | ||||
| 
 | ||||
|     public Task HandleClientAsync(WebSocket webSocket, Player player) | ||||
|         => HandleClientAsync(new PlayerInfoConnection(player, connectionLogger, webSocket)); | ||||
|         => HandleClientAsync(new PlayerInfoConnection(player, connectionLogger, webSocket, entityManager)); | ||||
| 
 | ||||
|     public Task TickAsync(TimeSpan delta) | ||||
|         => ParallelForEachConnectionAsync(connection => connection.OnGameTickAsync()); | ||||
|  |  | |||
|  | @ -1,3 +1,15 @@ | |||
| namespace TanksServer.Models; | ||||
| 
 | ||||
| internal sealed record class PlayerInfo(string Name, Scores Scores, PlayerControls Controls); | ||||
| internal sealed record class TankInfo( | ||||
|     int Orientation, | ||||
|     byte ExplosiveBullets, | ||||
|     PixelPosition Position, | ||||
|     bool Moving | ||||
| ); | ||||
| 
 | ||||
| internal sealed record class PlayerInfo( | ||||
|     string Name, | ||||
|     Scores Scores, | ||||
|     PlayerControls Controls, | ||||
|     TankInfo? Tank | ||||
| ); | ||||
|  |  | |||
|  | @ -22,7 +22,7 @@ internal sealed class Tank(Player player, FloatPosition spawnPosition) : IMapEnt | |||
| 
 | ||||
|     public DateTime NextShotAfter { get; set; } | ||||
| 
 | ||||
|     public bool Moved { get; set; } | ||||
|     public bool Moving { get; set; } | ||||
| 
 | ||||
|     public FloatPosition Position { get; set; } = spawnPosition; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vinzenz Schroeter
						Vinzenz Schroeter