Example #1
0
    private void ConstructLinks() //步驟3
    {
        currentStatus = GeneratingStatus.Construct_Links;
        /*此段以上負責狀態更改*/

        int        len    = lvToPut.Length;
        Vector2Int fromTo = new Vector2Int(-1, -1);

        for (int i = 0; i < len; i++)
        {
            if (lvInform[i].connection == 1 && fromTo.x < 0)
            {
                fromTo.x = i;
            }
            else if (lvInform[i].connection == 1 && fromTo.y < 0)
            {
                fromTo.y = i;
            }
            if (fromTo.x >= 0 && fromTo.y >= 0)
            {
                BuildLink(fromTo.x, fromTo.y, true);
                fromTo = new Vector2Int(-1, -1);
            }
        }

        FindPaths();
    }
Example #2
0
    private void Selecting() //步驟1
    {
        currentStatus = GeneratingStatus.Selecting;
        /*此段以上負責狀態更改*/

        int len = levels.Length;

        for (int i = 0; i < len; i++)
        {
            int        rand  = UnityEngine.Random.Range(0, len - 1);
            GameObject newGO = levels[i];
            levels[i]    = levels[rand];
            levels[rand] = newGO;
        }
        /*此段以上負責洗牌*/

        int lvCount = UnityEngine.Random.Range(minMap, maxMap);

        lvToPut  = new GameObject[lvCount + 1];
        lvInform = new Level[lvCount + 1];
        link     = new Vector2Int[lvCount + 1, lvCount + 1];
        for (int i = 0; i < lvCount + 1; i++)
        {
            for (int j = 0; j < lvCount + 1; j++)
            {
                link[i, j] = Vector2Int.zero;
            }
        }
        lvToPut[0]  = StartingPlace;
        lvInform[0] = StartingPlace.GetComponent <Level>();
        for (int i = 1; i < lvCount + 1; i++)
        {
            lvToPut[i]  = levels[i];
            lvInform[i] = lvToPut[i].GetComponent <Level>();
        }
        /*此段以上負責抽關卡*/

        for (int i = 1; i < lvCount; i++)
        {
            for (int j = i; j >= 1; j--)
            {
                if (Mathf.Max(lvInform[j].X, lvInform[j].Y) > Mathf.Max(lvInform[j - 1].X, lvInform[j - 1].Y))
                {
                    GameObject tempGO = lvToPut[j];
                    lvToPut[j]     = lvToPut[j - 1];
                    lvToPut[j - 1] = tempGO;
                    Level tempLV = lvInform[j];
                    lvInform[j]     = lvInform[j - 1];
                    lvInform[j - 1] = tempLV;
                }
                else
                {
                    break;
                }
            }
        }
        /*此段以上負責排序(用selection sort,因為基數不大(< 100),而且演算法in place且stable)*/

        PlaceLevels();
    }
Example #3
0
    IEnumerator Finish() //步驟7
    {
        AstarPath.active.data.gridGraph.center = Index2Pos(new Vector2(minX, minY), maxX - minX + 1, maxY - minY + 1);
        AstarPath.active.data.gridGraph.SetDimensions(4 * (maxX - minX) + 4, 4 * (maxY - minY) + 4, 1);
        AstarPath.active.Scan();
        yield return(new WaitForSeconds(1.5f));

        currentStatus = GeneratingStatus.Finish;
    }
Example #4
0
    private void FinalMakeup() //步驟6
    {
        currentStatus = GeneratingStatus.Final_Makeup;

        /*for (int i = 0; i < lvInform.Length; i++)
         * {
         *  for (int j = 0; j < lvInform[i].directions.Length; j++)
         *  {
         *      int k = (int)lvInform[i].directions[j].direction;
         *      if (lvInform[i].directions[j].connectedAmount == 0)
         *          Instantiate(makeUp[k], Index2Pos(ConnectionPos(i, j), 1, 1), Quaternion.identity);
         *  }
         * }*/
        StartCoroutine(Finish());
    }
Example #5
0
    private void BuildPaths() //步驟5
    {
        currentStatus = GeneratingStatus.Build_Paths;
        while (PathCoordinate.Count != 0)
        {
            //int spawnIndex = 0;
            Vector2Int Pos = PathCoordinate.Dequeue();

            /*if (Pos.y > 0 && map[Pos.x, Pos.y - 1] != 2 && map[Pos.x, Pos.y - 1] > 0)
             *  spawnIndex += 1;
             * if (Pos.y < mapY - 1 && map[Pos.x, Pos.y + 1] != 2 && map[Pos.x, Pos.y + 1] > 0)
             *  spawnIndex += 2;
             * if (Pos.x > 0 && map[Pos.x - 1, Pos.y] != 2 && map[Pos.x - 1, Pos.y] > 0)
             *  spawnIndex += 4;
             * if (Pos.x < mapX - 1 && map[Pos.x + 1, Pos.y] != 2 && map[Pos.x + 1, Pos.y] > 0)
             *  spawnIndex += 8;*/
            Instantiate(path, Index2Pos(Pos, 1, 1), Quaternion.identity, Composite.transform);
        }

        FinalMakeup();
    }
Example #6
0
    private void PlaceLevels() //步驟2
    {
        currentStatus = GeneratingStatus.Place_Levels;
        /*此段以上負責狀態更改*/

        int        len      = lvToPut.Length;
        Vector2Int startPos = new Vector2Int(UnityEngine.Random.Range(mapX / 2 - 5, mapX / 2 + 6), UnityEngine.Random.Range(mapY / 2 - 5, mapY / 2 + 6));

        PlaceLevelSetup(0, startPos);
        /*第一個被隨機生成的關卡*/

        for (int i = 1; i < len; i++)
        {
            bool findPlace = false;
            while (findPlace == false)
            {
                Vector4 newDir = checkDir.Pop();
                for (int j = 0; j < 5; j++)
                {
                    Vector2Int newPos = PickPosition(new Vector2(newDir.y, newDir.z), lvInform[(int)newDir.x].X, lvInform[(int)newDir.x].Y, lvInform[i].X, lvInform[i].Y, (int)newDir.w);
                    if (map[newPos.x, newPos.y] == 0 && map[newPos.x + lvInform[i].X - 1, newPos.y] == 0 && map[newPos.x, newPos.y + lvInform[i].Y - 1] == 0 && map[newPos.x + lvInform[i].X - 1, newPos.y + lvInform[i].Y - 1] == 0)
                    {
                        PlaceLevelSetup(i, newPos);

                        /*int rand = UnityEngine.Random.Range(0, i);
                         * while((lvInform[i].PosInArray - lvInform[rand].PosInArray).sqrMagnitude > 400)
                         *  rand = UnityEngine.Random.Range(0, i);*/
                        BuildLink(i - 1, i, false);
                        findPlace = true;
                        break;
                    }
                }
            }
        }
        /*此段以上負責生成關卡*/

        ConstructLinks();
    }
Example #7
0
    private void FindPaths() //步驟4
    {
        currentStatus = GeneratingStatus.Find_Paths;
        Queue <Vector2Int> temp = new Queue <Vector2Int>();

        while (linkConstructor.Count != 0)
        {
            temp.Clear();
            Vector4    newLink   = linkConstructor.Dequeue();
            Vector2Int from      = BuildLinkInit(temp, ConnectionPos((int)newLink.x, (int)newLink.y), (int)newLink.x, (int)newLink.y);
            Vector2Int to        = BuildLinkInit(temp, ConnectionPos((int)newLink.z, (int)newLink.w), (int)newLink.z, (int)newLink.w);
            int        stepcount = 0;
            while (stepcount < 100 && from != to)
            {
                stepcount++;
                if (map[from.x, from.y] != 1)
                {
                    PathCoordinate.Enqueue(from);
                }
                temp.Enqueue(from);
                map[from.x, from.y] = 3;
                int upCost = int.MaxValue, downCost = int.MaxValue, leftCost = int.MaxValue, rightCost = int.MaxValue;
                int oriCost = (to - from).sqrMagnitude;
                if (from.y > 0 && map[from.x, from.y - 1] < 2 && DeadEnd(from.x, from.y - 1) == false)
                {
                    upCost = (to - (from + new Vector2Int(0, -1))).sqrMagnitude;
                }
                if (from.y < mapY - 1 && map[from.x, from.y + 1] < 2 && DeadEnd(from.x, from.y + 1) == false)
                {
                    downCost = (to - (from + new Vector2Int(0, 1))).sqrMagnitude;
                }
                if (from.x > 0 && map[from.x - 1, from.y] < 2 && DeadEnd(from.x - 1, from.y) == false)
                {
                    leftCost = (to - (from + new Vector2Int(-1, 0))).sqrMagnitude;
                }
                if (from.x < mapX - 1 && map[from.x + 1, from.y] < 2 && DeadEnd(from.x + 1, from.y) == false)
                {
                    rightCost = (to - (from + new Vector2Int(1, 0))).sqrMagnitude;
                }
                int bestCost = (int)Mathf.Min(upCost, downCost, leftCost, rightCost);
                if (upCost - oriCost < 0 || upCost == bestCost)
                {
                    from += new Vector2Int(0, -1);
                }
                else if (downCost - oriCost < 0 || downCost == bestCost)
                {
                    from += new Vector2Int(0, 1);
                }
                else if (leftCost - oriCost < 0 || leftCost == bestCost)
                {
                    from += new Vector2Int(-1, 0);
                }
                else if (rightCost - oriCost < 0 || rightCost == bestCost)
                {
                    from += new Vector2Int(1, 0);
                }
                minX = ((from.x < minX) ? from.x : minX);
                minY = ((from.y < minY) ? from.y : minY);
                maxX = ((from.x > maxX) ? from.x : maxX);
                maxY = ((from.y > maxY) ? from.y : maxY);
            }
            if (map[from.x, from.y] != 1)
            {
                PathCoordinate.Enqueue(from);
            }
            map[from.x, from.y] = 3;
            temp.Enqueue(from);
            foreach (Vector2Int vector in temp)
            {
                map[vector.x, vector.y] = 1;
            }
        }
        //linkConstructor(a,b,c,d) => "從第a號關卡的第b號接口做一條路到第c號關卡的第d號接口"

#if UNITY_EDITOR
        string       path   = "Assets/Resources/Test.txt";
        StreamWriter writer = new StreamWriter(new FileStream(path, FileMode.Truncate));
        for (int i = 0; i < mapY; i++)
        {
            string str = "";
            for (int j = 0; j < mapX; j++)
            {
                if (map[j, i] >= 0)
                {
                    str += map[j, i].ToString();
                }
                else
                {
                    str += "+";
                }
            }
            str += "\n";
            writer.Write(str);
        }
        writer.Close();
#endif

        BuildPaths();
    }