示例#1
0
 public bool TraversableTo(MapSection mapSection)
 {
     if (XPos == mapSection.XPos - 1 && YPos == mapSection.YPos && HasOpenRight && mapSection.HasOpenLeft)
     {
         return(true);
     }
     if (XPos == mapSection.XPos + 1 && YPos == mapSection.YPos && HasOpenLeft && mapSection.HasOpenRight)
     {
         return(true);
     }
     if (XPos == mapSection.XPos && YPos == mapSection.YPos - 1 && HasOpenBottom && mapSection.HasOpenTop)
     {
         return(true);
     }
     if (XPos == mapSection.XPos && YPos == mapSection.YPos + 1 && HasOpenTop && mapSection.HasOpenBottom)
     {
         return(true);
     }
     return(false);
 }
示例#2
0
        public void InitializeMap(GraphicsDevice graphicsDevice, Rectangle clientBounds, MapSectionTypes?type = null)
        {
            _texture          = TextureCacheFactory.GetOnce("Maps/Tiles.png");
            _textureLocations = new Dictionary <TileTypes, Rectangle> {
                [TileTypes.Floor]      = new Rectangle(128, 256, 64, 64),
                [TileTypes.Wall]       = new Rectangle(0, 32, 64, 64),
                [TileTypes.SingleWall] = new Rectangle(320, 32, 64, 64)
            };
            _mapSectionWidth  = _textureLocations[TileTypes.Floor].Width * GameConstants.MapSectionSizeInTiles;
            _mapSectionHeight = _textureLocations[TileTypes.Floor].Height * GameConstants.MapSectionSizeInTiles;

            MapSection startSection = null;

            _sections = new MapSection[MapNumSectionsWide, MapNumSectionsTall];
            if (type.HasValue)
            {
                for (var x = 0; x < MapNumSectionsWide; x++)
                {
                    for (var y = 0; y < MapNumSectionsTall; y++)
                    {
                        _sections[x, y] = new MapSection(type.Value, new Rectangle(_mapSectionWidth * x, _mapSectionHeight * y, _mapSectionWidth, _mapSectionHeight), x, y);
                    }
                }
            }
            else
            {
                // First surround the map in wall sections
                for (var x = 0; x < MapNumSectionsWide; x++)
                {
                    var bottomY = MapNumSectionsTall - 1;
                    _sections[x, 0]       = new MapSection(MapSectionTypes.Wall, new Rectangle(_mapSectionWidth * x, _mapSectionHeight * 0, _mapSectionWidth, _mapSectionHeight), x, bottomY);
                    _sections[x, bottomY] = new MapSection(MapSectionTypes.Wall, new Rectangle(_mapSectionWidth * x, _mapSectionHeight * bottomY, _mapSectionWidth, _mapSectionHeight), x, bottomY);
                }
                for (var y = 1; y < MapNumSectionsTall - 1; y++)
                {
                    var rightX = MapNumSectionsWide - 1;
                    _sections[0, y]      = new MapSection(MapSectionTypes.Wall, new Rectangle(_mapSectionWidth * 0, _mapSectionHeight * y, _mapSectionWidth, _mapSectionHeight), rightX, y);
                    _sections[rightX, y] = new MapSection(MapSectionTypes.Wall, new Rectangle(_mapSectionWidth * (rightX), _mapSectionHeight * y, _mapSectionWidth, _mapSectionHeight), rightX, y);
                }
                // Create the start
                var startingSectionX = Helpers.RandomIntInRange(1, MapNumSectionsWide - 2);
                var startingSectionY = Helpers.RandomIntInRange(1, MapNumSectionsWide - 2);
                StartingPosition = new Vector2(startingSectionX * _mapSectionWidth + _mapSectionHeight / 2, startingSectionY * _mapSectionHeight + _mapSectionHeight / 2);
                _sections[startingSectionX, startingSectionY] = new MapSection(MapSectionTypes.Start, new Rectangle(_mapSectionWidth * startingSectionX, _mapSectionHeight * startingSectionY, _mapSectionWidth, _mapSectionHeight), startingSectionX, startingSectionY);
                startSection = _sections[startingSectionX, startingSectionY];
                // Create all of the other middle tiles
                for (var x = 1; x < MapNumSectionsWide - 1; x++)
                {
                    for (var y = 1; y < MapNumSectionsTall - 1; y++)
                    {
                        if (_sections[x, y] == null)
                        {
                            _sections[x, y] = new MapSection(MapSectionTypes.Walled, new Rectangle(_mapSectionWidth * x, _mapSectionHeight * y, _mapSectionWidth, _mapSectionHeight), x, y);
                        }
                    }
                }
                // Create a maze
                var numVisited = 1;
                var stack      = new List <(int, int)>();
                (int X, int Y)currentSection = (startingSectionX, startingSectionY);
                while (numVisited < (MapNumSectionsTall - 2) * (MapNumSectionsWide - 2))
                {
                    var adjacentCells = GetAdjacentSections(currentSection.X, currentSection.Y, true);

                    if (adjacentCells.Any())
                    {
                        var randomNeighbor = adjacentCells[Globals.Random.Next(adjacentCells.Count)];
                        switch (randomNeighbor.Direction)
                        {
                        case CardinalDirection.Up:
                            _sections[randomNeighbor.X, randomNeighbor.Y].DestroyWall(CardinalDirection.Down);
                            _sections[currentSection.X, currentSection.Y].DestroyWall(CardinalDirection.Up);
                            break;

                        case CardinalDirection.Down:
                            _sections[randomNeighbor.X, randomNeighbor.Y].DestroyWall(CardinalDirection.Up);
                            _sections[currentSection.X, currentSection.Y].DestroyWall(CardinalDirection.Down);
                            break;

                        case CardinalDirection.Left:
                            _sections[randomNeighbor.X, randomNeighbor.Y].DestroyWall(CardinalDirection.Right);
                            _sections[currentSection.X, currentSection.Y].DestroyWall(CardinalDirection.Left);
                            break;

                        case CardinalDirection.Right:
                            _sections[randomNeighbor.X, randomNeighbor.Y].DestroyWall(CardinalDirection.Left);
                            _sections[currentSection.X, currentSection.Y].DestroyWall(CardinalDirection.Right);
                            break;
                        }
                        stack.Add((currentSection.X, currentSection.Y));
                        currentSection = (randomNeighbor.X, randomNeighbor.Y);
                        numVisited++;
                    }
                    else
                    {
                        // Set current section to the popped section from the stack
                        currentSection = stack.Last();
                        stack.Remove(currentSection);
                    }
                }
            }

            // Find the furthest cell from the start and spawn the boss there (if this is a real map)
            if (startSection != null)
            {
                var sectionsToVisit = new List <MapSection> {
                    startSection
                };
                var sections = new Dictionary <MapSection, int?>
                {
                    [startSection] = 0
                };
                var bossSection = startSection;
                var maxDistance = 0;

                while (sectionsToVisit.Any())
                {
                    // Pop one
                    var section = sectionsToVisit.Last();
                    sectionsToVisit.Remove(section);

                    var adjacentCells = GetAdjacentSections(section.XPos, section.YPos, false);
                    var distance      = sections[section].Value + 1;
                    foreach (var cell in adjacentCells)
                    {
                        var adjacentSection = _sections[cell.X, cell.Y];
                        // If we've already gotten to this cell in the same or less distance then ignore
                        if (sections.Keys.Contains(adjacentSection) && sections[adjacentSection] <= distance)
                        {
                            continue;
                        }

                        // Process this section if we haven't already
                        if (!sectionsToVisit.Contains(adjacentSection))
                        {
                            sectionsToVisit.Add(adjacentSection);
                        }

                        sections[adjacentSection] = distance;

                        if (distance > maxDistance)
                        {
                            maxDistance = distance;
                            bossSection = adjacentSection;
                        }
                    }
                }

                bossSection.Type = MapSectionTypes.Boss;
            }

            // Tell the sections we are done making the map
            for (var x = 0; x < MapNumSectionsWide; x++)
            {
                for (var y = 0; y < MapNumSectionsTall; y++)
                {
                    _sections[x, y].MapComplete();
                }
            }
        }