prepare to send different data per client
This commit is contained in:
parent
fcd84d2c83
commit
fbaad86555
15 changed files with 245 additions and 128 deletions
|
@ -1,13 +1,16 @@
|
|||
using DisplayCommands;
|
||||
using TanksServer.GameLogic;
|
||||
|
||||
namespace TanksServer.Graphics;
|
||||
|
||||
internal sealed class DrawBulletsStep(BulletManager bullets) : IDrawStep
|
||||
{
|
||||
public void Draw(PixelGrid buffer)
|
||||
public void Draw(GamePixelGrid pixels)
|
||||
{
|
||||
foreach (var position in bullets.GetAll().Select(b => b.Position.ToPixelPosition()))
|
||||
buffer[(ushort)position.X, (ushort)position.Y] = true;
|
||||
foreach (var bullet in bullets.GetAll())
|
||||
{
|
||||
var position = bullet.Position.ToPixelPosition();
|
||||
pixels[position.X, position.Y].EntityType = GamePixelEntityType.Bullet;
|
||||
pixels[position.X, position.Y].BelongsTo = bullet.Owner;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
using DisplayCommands;
|
||||
using TanksServer.GameLogic;
|
||||
|
||||
namespace TanksServer.Graphics;
|
||||
|
||||
internal sealed class DrawMapStep(MapService map) : IDrawStep
|
||||
{
|
||||
public void Draw(PixelGrid buffer)
|
||||
public void Draw(GamePixelGrid pixels)
|
||||
{
|
||||
for (ushort y = 0; y < MapService.PixelsPerColumn; y++)
|
||||
for (ushort x = 0; x < MapService.PixelsPerRow; x++)
|
||||
|
@ -13,7 +12,8 @@ internal sealed class DrawMapStep(MapService map) : IDrawStep
|
|||
var pixel = new PixelPosition(x, y);
|
||||
if (!map.Current.IsWall(pixel))
|
||||
continue;
|
||||
buffer[x, y] = true;
|
||||
|
||||
pixels[x, y].EntityType = GamePixelEntityType.Wall;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ internal sealed class DrawTanksStep : IDrawStep
|
|||
_tankSpriteWidth = tankImage.Width;
|
||||
}
|
||||
|
||||
public void Draw(PixelGrid buffer)
|
||||
public void Draw(GamePixelGrid pixels)
|
||||
{
|
||||
foreach (var tank in _tanks)
|
||||
{
|
||||
|
@ -40,7 +40,8 @@ internal sealed class DrawTanksStep : IDrawStep
|
|||
continue;
|
||||
|
||||
var (x, y) = tankPosition.GetPixelRelative(dx, dy);
|
||||
buffer[(ushort)x, (ushort)y] = true;
|
||||
pixels[x, y].EntityType = GamePixelEntityType.Tank;
|
||||
pixels[x, y].BelongsTo = tank.Owner;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
21
TanksServer/Graphics/GamePixel.cs
Normal file
21
TanksServer/Graphics/GamePixel.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
namespace TanksServer.Graphics;
|
||||
|
||||
internal sealed class GamePixel
|
||||
{
|
||||
public Player? BelongsTo { get; set; }
|
||||
|
||||
public GamePixelEntityType? EntityType { get; set; }
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
BelongsTo = null;
|
||||
EntityType = null;
|
||||
}
|
||||
}
|
||||
|
||||
internal enum GamePixelEntityType : byte
|
||||
{
|
||||
Wall = 0x0,
|
||||
Tank = 0x1,
|
||||
Bullet = 0x2
|
||||
}
|
47
TanksServer/Graphics/GamePixelGrid.cs
Normal file
47
TanksServer/Graphics/GamePixelGrid.cs
Normal file
|
@ -0,0 +1,47 @@
|
|||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace TanksServer.Graphics;
|
||||
|
||||
internal sealed class GamePixelGrid : IEnumerable<GamePixel>
|
||||
{
|
||||
public int Width { get; }
|
||||
public int Height { get; }
|
||||
|
||||
private readonly GamePixel[,] _pixels;
|
||||
|
||||
public GamePixelGrid(int width, int height)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
|
||||
_pixels = new GamePixel[height, width];
|
||||
for (var row = 0; row < height; row++)
|
||||
for (var column = 0; column < width; column++)
|
||||
_pixels[row, column] = new GamePixel();
|
||||
}
|
||||
|
||||
public GamePixel this[int x, int y]
|
||||
{
|
||||
get
|
||||
{
|
||||
Debug.Assert(y * Width + x < _pixels.Length);
|
||||
return _pixels[y, x];
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
foreach (var pixel in _pixels)
|
||||
pixel.Clear();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
|
||||
public IEnumerator<GamePixel> GetEnumerator()
|
||||
{
|
||||
for (var row = 0; row < Height; row++)
|
||||
for (var column = 0; column < Width; column++)
|
||||
yield return _pixels[row, column];
|
||||
}
|
||||
}
|
|
@ -5,18 +5,30 @@ namespace TanksServer.Graphics;
|
|||
|
||||
internal sealed class GeneratePixelsTickStep(
|
||||
IEnumerable<IDrawStep> drawSteps,
|
||||
LastFinishedFrameProvider lastFrameProvider
|
||||
IEnumerable<IFrameConsumer> consumers
|
||||
) : ITickStep
|
||||
{
|
||||
private readonly List<IDrawStep> _drawSteps = drawSteps.ToList();
|
||||
private readonly PixelGrid _drawGrid = new(MapService.PixelsPerRow, MapService.PixelsPerColumn);
|
||||
private readonly List<IFrameConsumer> _consumers = consumers.ToList();
|
||||
|
||||
public Task TickAsync()
|
||||
private readonly PixelGrid _observerPixelGrid = new(MapService.PixelsPerRow, MapService.PixelsPerColumn);
|
||||
private readonly GamePixelGrid _gamePixelGrid = new(MapService.PixelsPerRow, MapService.PixelsPerColumn);
|
||||
|
||||
public async Task TickAsync()
|
||||
{
|
||||
_drawGrid.Clear();
|
||||
_gamePixelGrid.Clear();
|
||||
foreach (var step in _drawSteps)
|
||||
step.Draw(_drawGrid);
|
||||
lastFrameProvider.LastFrame = _drawGrid;
|
||||
return Task.CompletedTask;
|
||||
step.Draw(_gamePixelGrid);
|
||||
|
||||
_observerPixelGrid.Clear();
|
||||
for (var y = 0; y < MapService.PixelsPerColumn; y++)
|
||||
for (var x = 0; x < MapService.PixelsPerRow; x++)
|
||||
{
|
||||
if (_gamePixelGrid[x, y].EntityType.HasValue)
|
||||
_observerPixelGrid[(ushort)x, (ushort)y] = true;
|
||||
}
|
||||
|
||||
foreach (var consumer in _consumers)
|
||||
await consumer.OnFrameDoneAsync(_gamePixelGrid, _observerPixelGrid);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,5 +4,5 @@ namespace TanksServer.Graphics;
|
|||
|
||||
internal interface IDrawStep
|
||||
{
|
||||
void Draw(PixelGrid buffer);
|
||||
void Draw(GamePixelGrid pixels);
|
||||
}
|
||||
|
|
8
TanksServer/Graphics/IFrameConsumer.cs
Normal file
8
TanksServer/Graphics/IFrameConsumer.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
using DisplayCommands;
|
||||
|
||||
namespace TanksServer.Graphics;
|
||||
|
||||
internal interface IFrameConsumer
|
||||
{
|
||||
Task OnFrameDoneAsync(GamePixelGrid gamePixelGrid, PixelGrid observerPixels);
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
using DisplayCommands;
|
||||
|
||||
namespace TanksServer.Graphics;
|
||||
|
||||
internal sealed class LastFinishedFrameProvider
|
||||
{
|
||||
private PixelGrid? _lastFrame;
|
||||
|
||||
public PixelGrid LastFrame
|
||||
{
|
||||
get => _lastFrame ?? throw new InvalidOperationException("first frame not yet drawn");
|
||||
set => _lastFrame = value;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue