示例#1
0
        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();
        }
示例#2
0
        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;
        }
示例#3
0
        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);
        }
示例#6
0
        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();
            }
        }
示例#7
0
        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);
            }
        }
示例#8
0
        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);
                }
            }
        }
示例#9
0
        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);
            }
        }
示例#10
0
        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
            });
        }
示例#11
0
        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();
            }
        }
示例#12
0
        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;
            }
            }
        }
示例#13
0
        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);
                }
            }
        }
示例#14
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);
            }
        }
示例#15
0
        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;
        }
示例#16
0
        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);
                }
            }
        }
示例#17
0
        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();
            }
        }
示例#18
0
        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);
        }