public void SetSize(int width, int height) { (int columns, int rows) = _pixelMapper.ViewPortPixelsToCoords(width, height); columns = Math.Max(columns, 1); rows = Math.Max(rows, 1); (_width, _height) = _pixelMapper.CoordsToViewPortPixels(columns, rows); _pixelMapper.SetViewPortSize(_width, _height); _gameBoard.Columns = columns; _gameBoard.Rows = rows; ResetBuffers(); }
public void Render(ICanvas canvas, int width, int height, IPixelMapper pixelMapper) { if (_terrainMap.IsEmpty()) { canvas.DrawRect(0, 0, pixelMapper.ViewPortWidth, pixelMapper.ViewPortHeight, new PaintBrush { Style = PaintStyle.Fill, Color = TerrainColourLookup.DefaultColour }); return; } // Draw any non-grass cells foreach (Terrain terrain in _terrainMap) { Color colour = TerrainColourLookup.GetTerrainColour(terrain); (int x, int y) = pixelMapper.CoordsToViewPortPixels(terrain.Column, terrain.Row); canvas.DrawRect(x, y, _gameParameters.CellSize, _gameParameters.CellSize, new PaintBrush { Style = PaintStyle.Fill, Color = colour }); // Debug, this draws coord and height onto cells //canvas.DrawText($"{terrain.Column},{terrain.Row}", x + 2, y + 0.3f * _gameParameters.CellSize, new PaintBrush { Style = PaintStyle.Fill, Color = Colors.Black }); //canvas.DrawText($"{terrain.Height}", x + 2, y + 0.7f * _gameParameters.CellSize, new PaintBrush { Style = PaintStyle.Fill, Color = Colors.Black }); } _dirty = false; }
public void Render(ICanvas canvas, int width, int height, IPixelMapper pixelMapper) { canvas.DrawRect(0, 0, pixelMapper.ViewPortWidth, pixelMapper.ViewPortHeight, new PaintBrush { Style = PaintStyle.Fill, Color = TerrainColourLookup.DefaultColour }); if (_terrainMap.IsEmpty()) { return; } // Draw any non-grass cells foreach (Terrain terrain in _terrainMap) { (int x, int y, bool onScreen) = pixelMapper.CoordsToViewPortPixels(terrain.Column, terrain.Row); if (!onScreen) { continue; } Color colour = TerrainColourLookup.GetTerrainColour(terrain); if (colour == TerrainColourLookup.DefaultColour) { continue; } canvas.DrawRect(x, y, pixelMapper.CellSize, pixelMapper.CellSize, new PaintBrush { Style = PaintStyle.Fill, Color = colour }); } _dirty = false; }
public void Render(ICanvas canvas, int width, int height, IPixelMapper pixelMapper) { (int topLeftColumn, int topLeftRow) = pixelMapper.ViewPortPixelsToCoords(0, 0); (int bottomRightColumn, int bottomRightRow) = pixelMapper.ViewPortPixelsToCoords(pixelMapper.ViewPortWidth, pixelMapper.ViewPortHeight); bottomRightColumn += 1; bottomRightRow += 1; var source = new Rectangle(topLeftColumn, topLeftRow, bottomRightColumn, bottomRightRow); (int destinationTopLeftX, int destinationTopLeftY, _) = pixelMapper.CoordsToViewPortPixels(topLeftColumn, topLeftRow); (int destinationBottomRightX, int destinationBottomRightY, _) = pixelMapper.CoordsToViewPortPixels(bottomRightColumn, bottomRightRow); var destination = new Rectangle(destinationTopLeftX, destinationTopLeftY, destinationBottomRightX, destinationBottomRightY); canvas.DrawImage(_terrainMapRenderer.GetTerrainImage(), source, destination); }
private static (Rectangle Source, Rectangle Destination) GetSourceAndDestinationRectangles(IPixelMapper pixelMapper) { (int topLeftColumn, int topLeftRow) = pixelMapper.ViewPortPixelsToCoords(0, 0); (int bottomRightColumn, int bottomRightRow) = pixelMapper.ViewPortPixelsToCoords(pixelMapper.ViewPortWidth, pixelMapper.ViewPortHeight); bottomRightColumn += 1; bottomRightRow += 1; Rectangle source = new(topLeftColumn, topLeftRow, bottomRightColumn, bottomRightRow); (int destinationTopLeftX, int destinationTopLeftY, _) = pixelMapper.CoordsToViewPortPixels(topLeftColumn, topLeftRow); (int destinationBottomRightX, int destinationBottomRightY, _) = pixelMapper.CoordsToViewPortPixels(bottomRightColumn, bottomRightRow); Rectangle destination = new(destinationTopLeftX, destinationTopLeftY, destinationBottomRightX, destinationBottomRightY); return(source, destination); }
public void Render(ICanvas canvas, int width, int height, IPixelMapper pixelMapper) { if (pixelMapper.CellSize != _lastCellSize) { _cache.Clear(); _lastCellSize = pixelMapper.CellSize; } foreach (T entity in _layout) { (int x, int y, bool onScreen) = pixelMapper.CoordsToViewPortPixels(entity.Column, entity.Row); if (!onScreen) { continue; } canvas.Save(); canvas.Translate(x, y); if (_renderer is ICachableRenderer <T> cachableRenderer) { canvas.ClipRect(new Rectangle(0, 0, pixelMapper.CellSize, pixelMapper.CellSize), false); string key = cachableRenderer.GetCacheKey(entity); if (!_cache.TryGetValue(key, out IImage cachedImage)) { using IImageCanvas imageCanvas = _imageFactory.CreateImageCanvas(pixelMapper.CellSize, pixelMapper.CellSize); float scale = pixelMapper.CellSize / 100.0f; imageCanvas.Canvas.Scale(scale, scale); _renderer.Render(imageCanvas.Canvas, entity); cachedImage = imageCanvas.Render(); _cache[key] = cachedImage; } canvas.DrawImage(cachedImage, 0, 0); } else { float scale = pixelMapper.CellSize / 100.0f; canvas.Scale(scale, scale); _renderer.Render(canvas, entity); } canvas.Restore(); } }
public void Render(ICanvas canvas, int width, int height, IPixelMapper pixelMapper) { var tunnelRoofColour = BuildModeAwareColour(Colors.LightGray); var firstMountain = new Terrain() { Height = Terrain.FirstMountainHeight }; var tunnelBaseColour = BuildModeAwareColour(TerrainMapRenderer.GetTerrainColour(firstMountain)); var entranceColourArray = new[] { tunnelBaseColour, tunnelRoofColour, tunnelBaseColour }; Dictionary <(int column, int row), Tunnel> entrances = new(); foreach (Track track in _trackLayout) { var terrain = _terrainMap.Get(track.Column, track.Row); if (!terrain.IsMountain) { continue; } (int x, int y, _) = pixelMapper.CoordsToViewPortPixels(track.Column, track.Row); // Paint over the tracks with the colour of the terrain. Would be awesome to remove this in future somehow var terrainColour = BuildModeAwareColour(TerrainMapRenderer.GetTerrainColour(terrain)); canvas.DrawRect(x, y, pixelMapper.CellSize, pixelMapper.CellSize, new PaintBrush { Style = PaintStyle.Fill, Color = terrainColour, }); TrackNeighbors trackNeighbours = track.GetConnectedNeighbors(); BuildEntrances(trackNeighbours.Up, Tunnel.Bottom, entrances); BuildEntrances(trackNeighbours.Right, Tunnel.Left, entrances); BuildEntrances(trackNeighbours.Down, Tunnel.Top, entrances); BuildEntrances(trackNeighbours.Left, Tunnel.Right, entrances); var currentCellTunnels = (IsEntrance(trackNeighbours.Up) ? Tunnel.Top : Tunnel.NoTunnels) | (IsEntrance(trackNeighbours.Right) ? Tunnel.Right : Tunnel.NoTunnels) | (IsEntrance(trackNeighbours.Down) ? Tunnel.Bottom : Tunnel.NoTunnels) | (IsEntrance(trackNeighbours.Left) ? Tunnel.Left : Tunnel.NoTunnels); DrawTunnel(canvas, pixelMapper, tunnelRoofColour, tunnelBaseColour, x, y, currentCellTunnels); } foreach (var(col, row, tunnels) in entrances) { DrawEntrance(canvas, pixelMapper, entranceColourArray, col, row, tunnels); } }
public void Render(ICanvas canvas, int width, int height) { foreach (Train train in _gameBoard.GetMovables()) { PaintBrush _paint = new PaintBrush { Color = _painter.GetPalette(train).FrontSectionEndColor, Style = PaintStyle.Fill }; (int x, int y) = _pixelMapper.CoordsToViewPortPixels(train.Column, train.Row); canvas.DrawRect(x, y, _parameters.CellSize, _parameters.CellSize, _paint); float speedModifier = 0.005f * ((_gameTimer?.TimeSinceLastTick / 16f) ?? 1); foreach (var position in _gameBoard.GetNextSteps(train, train.LookaheadDistance * speedModifier)) { (x, y) = _pixelMapper.CoordsToViewPortPixels(position.Column, position.Row); canvas.DrawRect(x, y, _parameters.CellSize, _parameters.CellSize, _paint); } } }
public void Render(ICanvas canvas, int width, int height) { foreach (Track track in _trackLayout) { if (!track.Happy) { continue; } (int x, int y) = _pixelMapper.CoordsToViewPortPixels(track.Column, track.Row); canvas.DrawRect(x, y, _parameters.CellSize, _parameters.CellSize, _paint); } }
private ViewportPoint FindContourPointBetweenAdjacentTerrain(Terrain sourceTerrain, Terrain adjacentTerrain) { var columnDelta = sourceTerrain.Column - adjacentTerrain.Column; var rowDelta = sourceTerrain.Row - adjacentTerrain.Row; // Adjacent means that there should only be exactly one difference between either Columns or Rows (And the other should have no difference) if ((Math.Abs(columnDelta) + Math.Abs(rowDelta)) != 1) { throw new ArgumentException("Trying to find contour point between terrain that is not adjacent"); } // Different columns, must be same row if (columnDelta != 0) { // columnDelta gt zero means we have source on right, adjacent on left so centre point is between them.. which means source edge (since cell edges are on left) // columnDelta lt zero means we have source on left, adjacent on right so centre point is again between them.. which means adjacent edge var selectedColumn = (columnDelta > 0 ? sourceTerrain.Column : adjacentTerrain.Column); var(pixX, pixY) = _pixelMapper.CoordsToViewPortPixels(selectedColumn, sourceTerrain.Row); return(new ViewportPoint { PixelX = pixX, PixelY = pixY + 0.5f * _trackParameters.CellSize, }); } var selectedRow = (rowDelta > 0 ? sourceTerrain.Row : adjacentTerrain.Row); var(pixelX, pixelY) = _pixelMapper.CoordsToViewPortPixels(sourceTerrain.Column, selectedRow); return(new ViewportPoint { PixelX = pixelX + 0.5f * _trackParameters.CellSize, PixelY = pixelY }); }
public void Render(ICanvas canvas, int width, int height, IPixelMapper pixelMapper) { foreach (Train train in _gameBoard.GetMovables()) { canvas.Save(); (int x, int y) = pixelMapper.CoordsToViewPortPixels(train.Column, train.Row); canvas.Translate(x, y); _trainRenderer.Render(canvas, train); canvas.Restore(); } }
private static void DrawEntrance(ICanvas canvas, IPixelMapper pixelMapper, Color[] entranceColourArray, int col, int row, Tunnel tunnels) { (int x, int y, _) = pixelMapper.CoordsToViewPortPixels(col, row); switch (tunnels) { case Tunnel.Top: case Tunnel.Right: case Tunnel.Bottom: case Tunnel.Left: { DrawSingleEntrance(tunnels, canvas, pixelMapper, x, y, entranceColourArray); break; } case Tunnel.StraightVertical: case Tunnel.StraightHorizontal: { DrawStraightEntrance(tunnels, canvas, pixelMapper, x, y, entranceColourArray); break; } case Tunnel.TopRightCorner: case Tunnel.BottomRightCorner: case Tunnel.TopLeftCorner: case Tunnel.BottomLeftCorner: { DrawTwoWayEntranceIntersection(tunnels, canvas, pixelMapper, x, y, entranceColourArray); break; } case Tunnel.ThreewayNoUp: case Tunnel.ThreewayNoRight: case Tunnel.ThreewayNoDown: case Tunnel.ThreewayNoLeft: { DrawThreeWayEntrance(tunnels, canvas, pixelMapper, x, y, entranceColourArray); break; } case Tunnel.FourWayIntersection: { DrawFourWayEntranceIntersection(canvas, pixelMapper, x, y, entranceColourArray); break; } } }
public void Render(ICanvas canvas, int width, int height, IPixelMapper pixelMapper) { if (pixelMapper.CellSize != _lastCellSize) { _imageCache.Clear(); _lastCellSize = pixelMapper.CellSize; } foreach (T entity in _layout) { var renderer = _renderers.FirstOrDefault(r => r.ShouldRender(entity)); if (renderer is null) { // TODO: Fill with Red to indicate error? continue; } (int x, int y, bool onScreen) = pixelMapper.CoordsToViewPortPixels(entity.Column, entity.Row); if (!onScreen) { continue; } string key = $"{entity.GetType().Name}.{entity.Identifier}"; if (_imageCache.IsDirty(key)) { using IImageCanvas imageCanvas = _imageFactory.CreateImageCanvas(pixelMapper.CellSize, pixelMapper.CellSize); float scale = pixelMapper.CellSize / 100.0f; imageCanvas.Canvas.Scale(scale, scale); renderer.Render(imageCanvas.Canvas, entity); _imageCache.Set(key, imageCanvas.Render()); } using (canvas.Scope()) { canvas.Translate(x, y); canvas.ClipRect(new Rectangle(0, 0, pixelMapper.CellSize, pixelMapper.CellSize), false, false); canvas.DrawImage(_imageCache.Get(key) !, 0, 0); } } }
public void Render(ICanvas canvas, int width, int height, IPixelMapper pixelMapper) { foreach (Track track in _trackLayout) { if (!track.Happy) { continue; } (int x, int y, bool onScreen) = pixelMapper.CoordsToViewPortPixels(track.Column, track.Row); if (!onScreen) { continue; } canvas.DrawRect(x, y, pixelMapper.CellSize, pixelMapper.CellSize, _paint); } }
public void Render(ICanvas canvas, int width, int height, IPixelMapper pixelMapper) { foreach (Track track in _trackLayout.OfType <Track>()) { (int x, int y) = pixelMapper.CoordsToViewPortPixels(track.Column, track.Row); if (x < -_gameParameters.CellSize || y < -_gameParameters.CellSize || x > width || y > height) { continue; } canvas.Save(); canvas.Translate(x, y); canvas.ClipRect(new Rectangle(0, 0, _gameParameters.CellSize, _gameParameters.CellSize), false); _trackRenderer.Render(canvas, track); canvas.Restore(); } _dirty = false; }
public void Render(ICanvas canvas, int width, int height, IPixelMapper pixelMapper) { foreach (Train train in _gameBoard.GetMovables()) { using (canvas.Scope()) { (int x, int y, bool onScreen) = pixelMapper.CoordsToViewPortPixels(train.Column, train.Row); if (!onScreen) { continue; } canvas.Translate(x, y); float scale = pixelMapper.CellSize / 100.0f; canvas.Scale(scale, scale); _trainRenderer.Render(canvas, train); } } }
public void SetSize(int width, int height) { _screenWidth = width; _screenHeight = height; _imageCache.SetDirtyAll(_screens); (int columns, int rows) = _pixelMapper.ViewPortPixelsToCoords(width, height); columns = Math.Max(columns, 1); rows = Math.Max(rows, 1); (width, height, _) = _pixelMapper.CoordsToViewPortPixels(columns + 1, rows + 1); if (_width != width || _height != height) { _width = width; _height = height; _pixelMapper.SetViewPortSize(_width, _height); // strictly speaking this only needs to clear renderers, but we already cleared screens // so its easier just to call clear _imageCache.Clear(); } }
public void ViewPortCoordsPixelsCoords_ChangingZoom() { int col = 0; int row = 0; (int x, int y, _) = _pixelMapper.CoordsToViewPortPixels(col, row); _pixelMapper.AdjustGameScale(2.0f); _pixelMapper.SetViewPort(0, 0); _pixelMapper.LogData(_output); (int actualCol, int actualRow) = _pixelMapper.ViewPortPixelsToCoords(x, y); Assert.Equal(col, actualCol); Assert.Equal(row, actualRow); }