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 bool TryCreateEntity(int column, int row, bool isPartOfDrag, [NotNullWhen(true)] out Track?entity) { var neighbours = TrackNeighbors.GetConnectedNeighbours(_layout.ToLayout(), column, row, emptyIsConsideredConnected: true); // if they click and its the perfect spot for a cross track, just do it if (!isPartOfDrag && neighbours.Count == 4) { entity = new CrossTrack(); return(true); } if (isPartOfDrag) { if (neighbours.Count == 4) { entity = new CrossTrack(); return(true); } // if they're dragging, we're looking for them to complete an intersection neighbours = TrackNeighbors.GetConnectedNeighbours(_layout.ToLayout(), column - 1, row); if (neighbours.Count == 3 && neighbours.Right is null) { entity = new Track() { Direction = TrackDirection.Horizontal }; _layout.Set(column - 1, row, new CrossTrack()); return(true); } neighbours = TrackNeighbors.GetConnectedNeighbours(_layout.ToLayout(), column, row - 1); if (neighbours.Count == 3 && neighbours.Down is null) { entity = new Track() { Direction = TrackDirection.Vertical }; _layout.Set(column, row - 1, new CrossTrack()); return(true); } neighbours = TrackNeighbors.GetConnectedNeighbours(_layout.ToLayout(), column + 1, row); if (neighbours.Count == 3 && neighbours.Left is null) { entity = new Track() { Direction = TrackDirection.Horizontal }; _layout.Set(column + 1, row, new CrossTrack()); return(true); } neighbours = TrackNeighbors.GetConnectedNeighbours(_layout.ToLayout(), column, row + 1); if (neighbours.Count == 3 && neighbours.Up is null) { entity = new Track() { Direction = TrackDirection.Vertical }; _layout.Set(column, row + 1, new CrossTrack()); return(true); } } entity = null; return(false); }