示例#1
0
    /// <summary>
    /// Starting with the existing map generate a random island.
    /// <param name="seed">The seed to use to generate the island. Set to null if no specific seed needed.</param>
    /// </summary>
    void GenerateMap(int?seed)
    {
        List <Hex> mapFringe   = new List <Hex>();
        List <Hex> waterFringe = new List <Hex>();

        Dictionary <Vector3Int, Hex> mapDict = new Dictionary <Vector3Int, Hex>();

        System.Random random;
        if (seed != null)
        {
            random = new System.Random((int)seed);
        }
        else
        {
            random = new System.Random();
        }

        // Generate map fringe
        foreach (Hex mapHex in hexes)
        {
            if (mapHex.neighbors.Count != 6)
            {
                if (!mapHex.aspectList.Contains(Hex.Aspect.Ocean))
                {
                    mapFringe.Add(mapHex);
                }
                else
                {
                    waterFringe.Add(mapHex);
                }
            }
            mapDict[mapHex.position] = mapHex;
        }

        // Generate the land mass
        List <GameObject> prefabList = Resources.LoadAll <GameObject>("Prefabs/Hexes/Land").ToList();

        for (int i = 0; i < generatedMapSize; ++i)
        {
            int hexIndex = random.Next(mapFringe.Count);
            Hex hex      = mapFringe[hexIndex];
            Hex newHex   = CreateHex(prefabList[random.Next(prefabList.Count)], hex.OpenNeighbors()[random.Next(6 - hex.neighbors.Count)]);
            mapDict[newHex.position] = newHex;

            foreach (Vector3Int direction in neighborDirections[newHex.z])
            {
                Hex neighborHex;
                if (mapDict.TryGetValue(newHex.Plus(direction), out neighborHex))
                {
                    newHex.AddNeighborBidirectional(neighborHex);
                    if (neighborHex.neighbors.Count == 6)
                    {
                        mapFringe.Remove(neighborHex);
                    }
                }
            }

            if (newHex.neighbors.Count < 6)
            {
                mapFringe.Add(newHex);
            }
        }

        // Generate shallow water around land mass
        prefabList = Resources.LoadAll <GameObject>("Prefabs/Hexes/Water/Shallow").ToList();

        while (mapFringe.Count != 0)
        {
            Hex fringeHex = mapFringe[mapFringe.Count - 1];
            foreach (Vector3Int location in fringeHex.OpenNeighbors())
            {
                Hex newHex = CreateHex(prefabList[random.Next(prefabList.Count)], location);
                mapDict[newHex.position] = newHex;

                foreach (Vector3Int direction in neighborDirections[newHex.z])
                {
                    Hex neighborHex;
                    if (mapDict.TryGetValue(newHex.Plus(direction), out neighborHex))
                    {
                        newHex.AddNeighborBidirectional(neighborHex);
                        if (neighborHex.neighbors.Count == 6)
                        {
                            mapFringe.Remove(neighborHex);
                        }
                    }
                }

                if (newHex.neighbors.Count < 6)
                {
                    waterFringe.Add(newHex);
                }
            }
        }

        // Generate deep water around land mass
        prefabList = Resources.LoadAll <GameObject>("Prefabs/Hexes/Water/Deep").ToList();

        while (waterFringe.Count != 0)
        {
            Hex fringeHex = waterFringe[waterFringe.Count - 1];
            foreach (Vector3Int location in fringeHex.OpenNeighbors())
            {
                Hex newHex = CreateHex(prefabList[random.Next(prefabList.Count)], location);
                mapDict[newHex.position] = newHex;

                foreach (Vector3Int direction in neighborDirections[newHex.z])
                {
                    Hex neighborHex;
                    if (mapDict.TryGetValue(newHex.Plus(direction), out neighborHex))
                    {
                        newHex.AddNeighborBidirectional(neighborHex);
                        if (neighborHex.neighbors.Count == 6)
                        {
                            waterFringe.Remove(neighborHex);
                        }
                    }
                }
            }

            waterFringe.Remove(fringeHex);
        }
    }