Пример #1
0
    public void TestDstar()
    {
        GameManager.SpecialPathNode pTile = Player.GetTileOn();
        GameManager.SpecialPathNode eTile = this.GetTileOn();
        dstar.InitializeGoals(eTile.X, eTile.Y, pTile.X, pTile.Y);
        dstar.Replan();
        List <GameManager.SpecialPathNode> p = dstar.GetPath();
        string s_p = "";

        foreach (GameManager.SpecialPathNode n in p)
        {
            s_p += "(" + n.X + ", " + n.Y + ") ";
            n.tile.GetComponent <SpriteRenderer>().color = Color.red;
        }
        Debug.Log(s_p);

        dstar.UpdateStart(GameManager.ExitTile.X, GameManager.ExitTile.Y);
        dstar.Replan();
        List <GameManager.SpecialPathNode> p2 = dstar.GetPath();
        string s_e = "";

        foreach (GameManager.SpecialPathNode n in p2)
        {
            s_e += "(" + n.X + ", " + n.Y + ") ";
            n.tile.GetComponent <SpriteRenderer>().color = Color.blue;
        }
        Debug.Log(s_e);
    }
Пример #2
0
    /*
     * LayoutBoardFromArray creates the board area inside the outer wall layer according to
     * an input 2D setupArray[x,y] of int values. The following key should be used for the setup array:
     * -2 : empty (for unreachable area)
     * -1 : obstacle
     * 0  : floor
     * 1  : base enemy
     * 2  : boss enemy
     *
     * Note: this function does not affect placement of doors or player.
     */
    GameManager.SpecialPathNode[,] LayoutBoardFromArray(int[,] setupArray, GameManager.SpecialPathNode[,] boardArray)
    {
        int numRows = setupArray.GetLength(0);
        int numCols = setupArray.GetLength(1);

        for (int c = 0; c < numCols; c++)
        {
            for (int r = 0; r < numRows; r++)
            {
                GameObject toInstantiate = null;
                bool       wall          = false;
                bool       IsEnemy       = false;
                switch (setupArray[c, r])
                {
                case 0:
                    toInstantiate = floorTile;
                    break;

                case -1:
                    toInstantiate = obstacleTile;
                    wall          = true;
                    break;

                case 1:
                    toInstantiate = enemy;
                    wall          = true;
                    IsEnemy       = true;
                    break;

                case 2:
                    toInstantiate = boss;
                    break;
                }
                if (toInstantiate != null)
                {
                    GameObject instance = Instantiate(toInstantiate, new Vector3(c, r, 0f), Quaternion.identity) as GameObject;                  //r,numRows-1-c,0f), Quaternion.identity) as GameObject;
                    instance.transform.SetParent(boardHolder);
                    if (IsEnemy)
                    {
                        Enemy thisEnemy = instance.GetComponent <Enemy>();
                        if (Enemies == null)
                        {
                            Enemies = new List <Enemy>();
                        }
                        Enemies.Add(thisEnemy);
                        thisEnemy.TileX = c + 1;
                        thisEnemy.TileY = r + 1;
                    }
                    GameManager.SpecialPathNode thisNode = new GameManager.SpecialPathNode();
                    thisNode.X               = c + 1;
                    thisNode.Y               = r + 1;
                    thisNode.tile            = instance;
                    thisNode.IsWall          = wall;
                    boardArray[c + 1, r + 1] = thisNode;
                }
            }
        }
        return(boardArray);
    }
Пример #3
0
 private void MoveToDstarNode(GameManager.SpecialPathNode node)
 {
     if (node != null)
     {
         IsMoving         = true;
         CurrentDstarNode = node;
         GoalPos          = node.tile.transform.position;
     }
 }
Пример #4
0
    GameObject[,] LayoutObjectAtRandom(GameObject tile, int min, int max, GameObject[,] boardArray, bool IsWall)
    {
        int objectCount = Random.Range(min, max + 1);

        for (int i = 0; i < objectCount; i++)
        {
            Vector3    randomPosition            = RandomPosition();
            GameObject instance                  = Instantiate(tile, randomPosition, Quaternion.identity) as GameObject;
            GameManager.SpecialPathNode thisNode = new GameManager.SpecialPathNode();
            thisNode.X      = (int)(randomPosition.x) + 1;
            thisNode.Y      = (int)(randomPosition.y) + 1;
            thisNode.tile   = instance;
            thisNode.IsWall = IsWall;
            boardArray[(int)(randomPosition.x) + 1, (int)(randomPosition.y) + 1] = instance;
        }
        return(boardArray);
    }
Пример #5
0
    public void MoveToTileDstar(GameManager.SpecialPathNode tile)
    {
        GameManager.SpecialPathNode eTile = this.GetTileOn();
        CurDstarIndex = 0;
        if (DstarPath.Count == 0)
        {
            //First time
            dstar.InitializeGoals(eTile.X, eTile.Y, tile.X, tile.Y);
            dstar.Replan();
            DstarPath = dstar.GetPath();
            DstarPath.Add(tile);
        }
        else
        {
            //Debug.Log("Replanning");
            dstar.UpdateStart(eTile.X, eTile.Y);
            dstar.UpdateGoal(tile.X, tile.Y);
            dstar.Replan();
            DstarPath = dstar.GetPath();
            DstarPath.Add(tile);
        }
        if (DstarPath.Count > 1)
        {
            //Debug.Log("Found path");
            //Debug.Log(DstarPath[0].X + ", " + DstarPath[0].Y);
            //Debug.Log(eTile.X + ", " + eTile.Y);
            IsMoving         = true;
            GoalPos          = DstarPath[1].tile.transform.position;
            CurrentDstarNode = DstarPath[1];
            CurDstarIndex    = 1;

            /*
             * string s_e = "";
             * foreach (GameManager.SpecialPathNode n in DstarPath)
             * {
             *  s_e += "(" + n.X + ", " + n.Y + ") ";
             *  //n.tile.GetComponent<SpriteRenderer>().color = Color.blue;
             * }*/
            //Debug.Log(s_e);
            //CurrentGoalNode = DstarPath[0];
            //LinkedListNode<GameManager.SpecialPathNode> next = path.First;
        }
    }
Пример #6
0
    public bool MoveToTile(GameManager.SpecialPathNode tile)
    {
        path = aStar.Search(TileX, TileY, tile.X, tile.Y, null);
        //Debug.Log("Enemy: " + TileX + ", " + TileY + "; Player: " + tile.X + ", " + tile.Y);
        if (path != null && path.Count > 0)
        {
            IsMoving        = true;
            GoalPos         = path.First.Value.tile.transform.position;
            CurrentGoalNode = path.First;
            LinkedListNode <GameManager.SpecialPathNode> next = path.First;

            /*
             * string pathStr = "";
             * while (next != null)
             * {
             *  pathStr += "(" + next.Value.X + ", " + next.Value.Y + "); ";
             *  next = next.Next;
             * }
             * //Debug.Log(pathStr);*/
            return(true);
        }
        return(false);
    }
Пример #7
0
    public override void Update()
    {
        Bullet target   = null;
        Enemy  attacked = null;

        //Debug.Log("CURRENT DECISION: " + curDecision);

        prevDecision = curDecision;

        //Determine if player tile changed
        prevPlayerTile = nTile;
        nTile          = Player.GetTileOn();

        //Only calculate distance change if new tile.
        if (nTile != prevPlayerTile)
        {
            //
        }
        //Get bullet if close to move to
        target = BulletVisibleDecision();
        PlayerHPDecision();
        attacked = FriendlyEnemyHasSight();
        EnemyHPDecision();
        //Only need to recalculate distance to player if the player changes tiles
        if (prevBulletDecision.value != bulletClose.value || nTile != prevPlayerTile || curDecision == "DONEMOVINGTOBULLET" || curDecision == "DONEMOVINGTOENEMY")
        {
            //Prevents too many decisions from happening
            if ((Time.time > nextActionTime))
            {
                nextActionTime = Time.time + period;

                //We have to perform the decision even distance result is the same, to make sure the enemy paths to the newest player position
                //If we did not, the enemy could just stay in range but never be hit by the enemy
                string dis = DistanceToPlayerDecision();
                if (dis == "FAR")
                {
                    if (curDecision != "MOVINGTOBULLET")// && curDecision != "MOVINGTOENEMY")
                    {
                        //Debug.Log("Making a decision");
                        curDecision = MakeDecision.MakeDecision(new List <AttributeValue <string> >()
                        {
                            playerDist, bulletClose, playerHPDecision, enemyAttackedDecision, thisHPDecision
                        });
                    }
                }
                else
                {
                    //Debug.Log("Making a decision");
                    curDecision = MakeDecision.MakeDecision(new List <AttributeValue <string> >()
                    {
                        playerDist, bulletClose, playerHPDecision, enemyAttackedDecision, thisHPDecision
                    });
                }
            }
        }



        //Execute decision

        if (curDecision == "CHASE")
        {
            GameManager.SpecialPathNode playerTile = Player.GetTileOn();
            if (DoDstarLite)
            {
                this.MoveToTileDstar(playerTile);
            }
            else
            {
                this.MoveToTile(playerTile);
            }

            //To make sure it keeps moving, rather than sitting on "CHASE"
            curDecision = "FINDINGPLAYER";
        }
        else if (curDecision == "STAY")
        {
            IsMoving = false;
        }
        else if (curDecision == "FINDBULLET")
        {
            if (target != null)
            {
                Debug.Log(target);
                if (DoDstarLite)
                {
                    this.MoveToTileDstar(target.GetTileOn());
                }
                else
                {
                    this.MoveToTile(target.GetTileOn());
                }
                curDecision = "MOVINGTOBULLET";
            }
        }
        else if (curDecision == "DEFENDGOAL")
        {
            print("ENEMY DEFENDING GOAL");
            GameManager.SpecialPathNode exitTile = GameManager.ExitTile;
            //Debug.Log("EXit: " + exitTile.X + ", " + exitTile.Y);
            if (DoDstarLite)
            {
                this.MoveToTileDstar(exitTile);
            }
            else
            {
                this.MoveToTile(exitTile);
            }
            curDecision = "DEFENDINGGOAL";
        }
        else if (curDecision == "DEFENDINGGOAL")
        {
            float dist = Vector3.Distance(this.transform.position, GameManager.ExitTile.tile.transform.position);
            if (dist < 2.0f)
            {
                IsMoving    = false;
                curDecision = "ATGOAL";
            }
        }
        else if (curDecision == "FINDENEMY")
        {
            if (attacked != null)
            {
                if (DoDstarLite)
                {
                    this.MoveToTileDstar(attacked.GetTileOn());
                }
                else
                {
                    this.MoveToTile(attacked.GetTileOn());
                }

                curDecision = "MOVINGTOENEMY";
            }
        }

        Position = transform.position;
        if (DoDstarLite)
        {
            if ((CurrentDstarNode != null) && IsAtGoal(CurrentDstarNode.tile.transform.position))
            {
                CurDstarIndex++;
                if (CurDstarIndex >= DstarPath.Count)
                {
                    Debug.Log("Final Node found");
                    //end of nodes
                    IsMoving = false;
                    if (curDecision == "MOVINGTOBULLET")
                    {
                        curDecision = "DONEMOVINGTOBULLET";
                    }
                    if (curDecision == "MOVINGTOENEMY")
                    {
                        curDecision = "DONEMOVINGTOENEMY";
                    }
                    CurrentDstarNode = null;
                }
                else
                {
                    GameManager.SpecialPathNode next = DstarPath[CurDstarIndex];
                    MoveToDstarNode(next);
                }
            }
            else
            {
                if (CurrentDstarNode != null)
                {
                    TileX = CurrentDstarNode.X;
                    TileY = CurrentDstarNode.Y;
                }
            }
        }
        else
        {
            if ((CurrentGoalNode != null) && IsAtGoal(CurrentGoalNode.Value.tile.transform.position))
            {
                LinkedListNode <GameManager.SpecialPathNode> next = CurrentGoalNode.Next;
                if (next == null)
                {
                    //Debug.Log("Final node found");
                    //end of list
                    IsMoving = false;
                    if (curDecision == "MOVINGTOBULLET")
                    {
                        curDecision = "DONEMOVINGTOBULLET";
                    }
                    if (curDecision == "MOVINGTOENEMY")
                    {
                        curDecision = "DONEMOVINGTOENEMY";
                    }
                }
                else
                {
                    MoveToNode(next);
                }
            }
            else
            {
                if (CurrentGoalNode != null)
                {
                    TileX = CurrentGoalNode.Value.X;
                    TileY = CurrentGoalNode.Value.Y;
                }
            }
        }

        if (IsMoving)
        {
            //Debug.Log("goal: " + GoalPos);
            transform.position = Vector3.MoveTowards(transform.position, GoalPos, Speed * Time.deltaTime);
        }

        if (DoDstarLite)
        {
            /*
             * string s_e = "";
             * foreach (GameManager.SpecialPathNode n in DstarPath)
             * {
             *  s_e += "(" + n.X + ", " + n.Y + ") ";
             *  n.tile.GetComponent<SpriteRenderer>().color = Color.blue;
             * }*/
        }
    }
Пример #8
0
 private void MoveToDstarNode(GameManager.SpecialPathNode node)
 {
     if (node != null)
     {
         IsMoving = true;
         CurrentDstarNode = node;
         GoalPos = node.tile.transform.position;
     }
 }
Пример #9
0
    public override void Update()
    {
        Bullet target = null;
        Enemy attacked = null;
        //Debug.Log("CURRENT DECISION: " + curDecision);

        prevDecision = curDecision;

        //Determine if player tile changed
        prevPlayerTile = nTile;
        nTile = Player.GetTileOn();

        //Only calculate distance change if new tile.
        if (nTile != prevPlayerTile)
        {
            //
        }
        //Get bullet if close to move to
        target = BulletVisibleDecision();
        PlayerHPDecision();
        attacked = FriendlyEnemyHasSight();
        EnemyHPDecision();
        //Only need to recalculate distance to player if the player changes tiles
        if (prevBulletDecision.value != bulletClose.value || nTile != prevPlayerTile || curDecision == "DONEMOVINGTOBULLET" || curDecision == "DONEMOVINGTOENEMY")
        {
            //Prevents too many decisions from happening
            if ((Time.time > nextActionTime))
            {
                nextActionTime = Time.time + period;

                //We have to perform the decision even distance result is the same, to make sure the enemy paths to the newest player position
                //If we did not, the enemy could just stay in range but never be hit by the enemy
                string dis = DistanceToPlayerDecision();
                if (dis == "FAR")
                {
                    if (curDecision != "MOVINGTOBULLET")// && curDecision != "MOVINGTOENEMY")
                    {
                        //Debug.Log("Making a decision");
                        curDecision = MakeDecision.MakeDecision(new List<AttributeValue<string>>() { playerDist, bulletClose, playerHPDecision, enemyAttackedDecision, thisHPDecision });
                    }
                }
                else
                {
                    //Debug.Log("Making a decision");
                    curDecision = MakeDecision.MakeDecision(new List<AttributeValue<string>>() { playerDist, bulletClose, playerHPDecision, enemyAttackedDecision, thisHPDecision });
                }

            }
        }

        //Execute decision

        if (curDecision == "CHASE")
        {
            GameManager.SpecialPathNode playerTile = Player.GetTileOn();
            if (DoDstarLite)
            {
                this.MoveToTileDstar(playerTile);
            }
            else
            {
                this.MoveToTile(playerTile);
            }

            //To make sure it keeps moving, rather than sitting on "CHASE"
            curDecision = "FINDINGPLAYER";
        }
        else if (curDecision == "STAY")
        {
            IsMoving = false;
        }
        else if (curDecision == "FINDBULLET")
        {

            if (target != null)
            {
                Debug.Log(target);
                if (DoDstarLite)
                {
                    this.MoveToTileDstar(target.GetTileOn());
                }
                else
                {
                    this.MoveToTile(target.GetTileOn());
                }
                curDecision = "MOVINGTOBULLET";
            }
        }
        else if (curDecision == "DEFENDGOAL")
        {
            print ("ENEMY DEFENDING GOAL");
            GameManager.SpecialPathNode exitTile = GameManager.ExitTile;
            //Debug.Log("EXit: " + exitTile.X + ", " + exitTile.Y);
            if (DoDstarLite)
            {
                this.MoveToTileDstar(exitTile);
            }
            else
            {
                this.MoveToTile(exitTile);
            }
            curDecision = "DEFENDINGGOAL";
        }
        else if (curDecision == "DEFENDINGGOAL")
        {
            float dist = Vector3.Distance(this.transform.position, GameManager.ExitTile.tile.transform.position);
            if (dist < 2.0f)
            {
                IsMoving = false;
                curDecision = "ATGOAL";
            }
        }
        else if (curDecision == "FINDENEMY")
        {
            if (attacked != null)
            {
                if (DoDstarLite)
                {
                    this.MoveToTileDstar(attacked.GetTileOn());
                }
                else
                {
                    this.MoveToTile(attacked.GetTileOn());
                }

                curDecision = "MOVINGTOENEMY";
            }
        }

        Position = transform.position;
        if (DoDstarLite)
        {
            if ((CurrentDstarNode != null) && IsAtGoal(CurrentDstarNode.tile.transform.position))
            {
                CurDstarIndex++;
                if (CurDstarIndex >= DstarPath.Count)
                {
                    Debug.Log("Final Node found");
                    //end of nodes
                    IsMoving = false;
                    if (curDecision == "MOVINGTOBULLET")
                    {
                        curDecision = "DONEMOVINGTOBULLET";
                    }
                    if (curDecision == "MOVINGTOENEMY")
                    {
                        curDecision = "DONEMOVINGTOENEMY";
                    }
                    CurrentDstarNode = null;
                }
                else
                {
                    GameManager.SpecialPathNode next = DstarPath[CurDstarIndex];
                    MoveToDstarNode(next);
                }
            }
            else
            {
                if (CurrentDstarNode != null)
                {
                    TileX = CurrentDstarNode.X;
                    TileY = CurrentDstarNode.Y;
                }
            }
        }
        else
        {
            if ((CurrentGoalNode != null) && IsAtGoal(CurrentGoalNode.Value.tile.transform.position))
            {

                LinkedListNode<GameManager.SpecialPathNode> next = CurrentGoalNode.Next;
                if (next == null)
                {
                    //Debug.Log("Final node found");
                    //end of list
                    IsMoving = false;
                    if (curDecision == "MOVINGTOBULLET")
                    {
                        curDecision = "DONEMOVINGTOBULLET";
                    }
                    if (curDecision == "MOVINGTOENEMY")
                    {
                        curDecision = "DONEMOVINGTOENEMY";
                    }
                }
                else
                {
                    MoveToNode(next);
                }
            }
            else
            {
                if (CurrentGoalNode != null)
                {
                    TileX = CurrentGoalNode.Value.X;
                    TileY = CurrentGoalNode.Value.Y;
                }
            }
        }

        if (IsMoving)
        {
            //Debug.Log("goal: " + GoalPos);
            transform.position = Vector3.MoveTowards(transform.position, GoalPos, Speed * Time.deltaTime);
        }

        if (DoDstarLite)
        {
            /*
            string s_e = "";
            foreach (GameManager.SpecialPathNode n in DstarPath)
            {
                s_e += "(" + n.X + ", " + n.Y + ") ";
                n.tile.GetComponent<SpriteRenderer>().color = Color.blue;
            }*/
        }
    }
Пример #10
0
 public void MoveToTileDstar(GameManager.SpecialPathNode tile)
 {
     GameManager.SpecialPathNode eTile = this.GetTileOn();
     CurDstarIndex = 0;
     if (DstarPath.Count == 0)
     {
         //First time
         dstar.InitializeGoals(eTile.X, eTile.Y, tile.X, tile.Y);
         dstar.Replan();
         DstarPath = dstar.GetPath();
         DstarPath.Add(tile);
     }
     else
     {
         //Debug.Log("Replanning");
         dstar.UpdateStart(eTile.X, eTile.Y);
         dstar.UpdateGoal(tile.X, tile.Y);
         dstar.Replan();
         DstarPath = dstar.GetPath();
         DstarPath.Add(tile);
     }
     if (DstarPath.Count > 1)
     {
         //Debug.Log("Found path");
         //Debug.Log(DstarPath[0].X + ", " + DstarPath[0].Y);
         //Debug.Log(eTile.X + ", " + eTile.Y);
         IsMoving = true;
         GoalPos = DstarPath[1].tile.transform.position;
         CurrentDstarNode = DstarPath[1];
         CurDstarIndex = 1;
         /*
         string s_e = "";
         foreach (GameManager.SpecialPathNode n in DstarPath)
         {
             s_e += "(" + n.X + ", " + n.Y + ") ";
             //n.tile.GetComponent<SpriteRenderer>().color = Color.blue;
         }*/
         //Debug.Log(s_e);
         //CurrentGoalNode = DstarPath[0];
         //LinkedListNode<GameManager.SpecialPathNode> next = path.First;
     }
 }
Пример #11
0
    ///*
    /// GenerateBlankBlobMap uses a procedural generation algorithm (cell automaton) to create the
    /// base floor layout of a map with a number of floor tiles equal to the input area.
    /// NOTE: should output blank map with format blankMap[x,y]
    ///*
    GameManager.SpecialPathNode[,] GenerateBlankBlobMap(int area, int optSeed = int.MinValue)
    {
        if (optSeed != int.MinValue)
        {
            Random.seed = optSeed;
        }
        print("blob map seed:" + Random.seed);

        Dictionary <Vector3, Cell> activeCells = new Dictionary <Vector3, Cell>();
        Vector3 startLoc = new Vector3(0, 0, 0f);

        activeCells.Add(startLoc, new Cell(startLoc));
        int currArea = 1;


        List <Cell> toBeActivated = new List <Cell>();

        while (currArea < area)
        {
            toBeActivated.Clear();
            List <Cell> allActive = activeCells.Values.ToList();
            for (int i = 0; i < allActive.Count; i++)
            {
                List <Cell> neighbors = GetNeighbors(allActive[i], activeCells, false);
                if (neighbors.Count >= 4 && neighbors.Count > 0)                    //If this active cell has 4 or less active neighbors, add one randomly.
                {
                    toBeActivated.Add(neighbors[Random.Range(0, neighbors.Count)]); //Get a random inactive neighbor and set it to be active on the next generation.
                }
            }
            if (toBeActivated.Count == 0)
            {
                List <Cell> neighbors = GetNeighbors(allActive[Random.Range(0, allActive.Count)], activeCells, false);
                if (neighbors.Count > 0)
                {
                    toBeActivated.Add(neighbors[Random.Range(0, neighbors.Count)]);
                }
            }
            for (int j = 0; j < toBeActivated.Count; j++)
            {
                Cell c = toBeActivated[j];
                if (!activeCells.ContainsKey(c.location))
                {
                    c.activate();
                    activeCells.Add(c.location, c);
                    currArea++;
                }
            }
        }

        ////Now there is a dictionary full of cells to be turned into floor tiles, create the output array.
        //First, figure out how big the 2d array needs to be to contain the map, then create the empty array.
        List <Vector3> sortByX = activeCells.Keys.ToList();

        sortByX.Sort((a, b) => a.x.CompareTo(b.x));
        int            minX    = (int)sortByX[0].x;
        int            xNum    = (int)sortByX[sortByX.Count - 1].x - minX + 1;
        List <Vector3> sortByY = activeCells.Keys.ToList();

        sortByY.Sort((a, b) => a.y.CompareTo(b.y));
        int minY = (int)sortByY[0].y;
        int yNum = (int)sortByY[sortByY.Count - 1].y - minY + 1;

        GameManager.SpecialPathNode[,] blankMap = new GameManager.SpecialPathNode[xNum + 2, yNum + 2];

        //Now convert the cells to the correct data type and fill the array.
        List <Cell> cells = activeCells.Values.ToList();

        for (int k = 0; k < cells.Count; k++)
        {
            GameManager.SpecialPathNode node = new GameManager.SpecialPathNode();
            //Calculate adjusted x-y coords so that all values are >0 (-minX/Y) and there is room for boundary around (+1).
            int adjustedX = (int)cells[k].location.x - minX + 1;
            int adjustedY = (int)cells[k].location.y - minY + 1;
            node.X      = adjustedX;
            node.Y      = adjustedY;
            node.tile   = floorTile;
            node.IsWall = false;

            blankMap[adjustedX, adjustedY] = node;           //y-minY+1,x-minX+1] = node; //+1 here shifts the tiles so there is room to add the walls around them.
        }
        return(blankMap);
    }
Пример #12
0
    ///*
    /// BoardSetup creates the floor and outer walls of the level and places the exit and enter doors on the
    /// upper and lower walls, respectively. If no exitLoc and/or enterLoc is specified, the door
    /// will be placed at a random horizontal location on the upper/lower wall.
    /// NOTE: This function is only used to build the default map.
    ///*
    GameManager.SpecialPathNode[,] BoardSetup(int exitLoc = -1, int enterLoc = -1)
    {
        if (exitLoc == -1)
        {
            exitLoc = Random.Range(0, columns);
        }
        if (enterLoc == -1)
        {
            enterLoc = Random.Range(0, columns);
        }

        boardHolder = new GameObject("Board").transform;
        GameManager.SpecialPathNode[,] boardArray = new GameManager.SpecialPathNode[columns + 2, rows + 2];
        for (int x = -1; x < columns + 1; x++)
        {
            for (int y = -1; y < rows + 1; y++)
            {
                GameObject toInstantiate = floorTile;
                if (y == -1)
                {
                    if (x == enterLoc)
                    {
                        toInstantiate = entrance;
                        Instantiate(player, new Vector3(x, y + 1, 0f), Quaternion.identity);

                        /**
                         * Debug.Log("player stuff: " + player.transform.position + ", " + new Vector3(x, y + 1, 0f) + ", " + (y + 1 + 1) + ", " + (x));
                         * PlayerLoc = new GameManager.SpecialPathNode();
                         * PlayerLoc.X = x + 1;
                         * PlayerLoc.Y = y + 1 + 1;
                         * PlayerLoc.tile = player;
                         * PlayerLoc.IsWall = false;*/
                    }
                    else
                    {
                        toInstantiate = obstacleTile;
                    }
                }
                else if (y == rows)
                {
                    if (x == exitLoc)
                    {
                        toInstantiate = exit;
                    }
                    else
                    {
                        toInstantiate = obstacleTile;
                    }
                }
                else if (x == -1 || x == columns)
                {
                    toInstantiate = obstacleTile;
                }

                GameObject instance = Instantiate(toInstantiate, new Vector3(x, y, 0f), Quaternion.identity) as GameObject;
                instance.transform.SetParent(boardHolder);
                GameManager.SpecialPathNode thisNode = new GameManager.SpecialPathNode();
                thisNode.X               = x + 1;
                thisNode.Y               = y + 1;
                thisNode.tile            = instance;
                thisNode.IsWall          = true;
                boardArray[x + 1, y + 1] = thisNode;
            }
        }
        return(boardArray);
    }
Пример #13
0
 bool isFloorNode(GameManager.SpecialPathNode node)
 {
     return(node != null && node.tile == floorTile);
 }
Пример #14
0
/*////////////////////PROCEDURAL MAP GENERATION FUNCTIONS////////////////////////////////*/


    ///
    /// Adds walls, doors, and enemies to the border of an input blank map. Places the
    /// enter door on a south-most wall, and places the exit door on one of the
    /// north-most walls. The number of enemies placed corresponds to the input level.
    /// NOTE: input blankMap should be array of nodes in blankMap[x,y] format
    ///
    GameManager.SpecialPathNode[,] FillBlankMap(GameManager.SpecialPathNode[,] blankMap, int level, int optSeed = int.MinValue)
    {
        if (optSeed != int.MinValue)
        {
            Random.seed = optSeed;
        }
        print("walls/doors seed:" + Random.seed);

        GameManager.SpecialPathNode[,] walledMap = blankMap;
        int xNum = walledMap.GetLength(0);
        int yNum = walledMap.GetLength(1);

        for (int x = 0; x < xNum; x++)
        {
            int leftInd  = (x > 0)?(x - 1):(0);
            int rightInd = (x < xNum - 1)?(x + 1):(xNum - 1);
            for (int y = 0; y < yNum; y++)
            {
                int downInd = (y > 0)?(y - 1):(0);
                int upInd   = (y < yNum - 1)?(y + 1):(yNum - 1);
                int[,] cases = new int[4, 2] {       //Four cases with (x,y) in each
                    { leftInd, y },                  //Case 0: right edge of floor
                    { rightInd, y },                 //Case 1: left edge of floor
                    { x, downInd },                  //Case 2: upper edge of floor
                    { x, upInd }
                };                                   //Case 3: lower edge of floor
                //If any of the cases are true create an obstacle tile.
                for (int caseNum = 0; caseNum < cases.GetLength(0); caseNum++)
                {
                    int caseX = cases[caseNum, 0];
                    int caseY = cases[caseNum, 1];
                    if (isFloorNode(blankMap[caseX, caseY]) && blankMap[x, y] == null)                  //current cell is empty and one above it is floor
                    {
                        GameManager.SpecialPathNode node = new GameManager.SpecialPathNode();
                        node.X          = x;
                        node.Y          = y;
                        node.tile       = obstacleTile;
                        node.IsWall     = true;
                        walledMap[x, y] = node;
                    }
                }
            }
        }

        //Now add the enter and exit doors...

        bool[,] travSpace = getTraversableSpace(walledMap);

        //Exit door:
        int        exitY       = walledMap.GetLength(1);
        List <int> exitOptions = new List <int>();

        while (exitOptions.Count == 0 && exitY > 0)
        {
            exitY--;
            for (int i = 0; i < walledMap.GetLength(0); i++)
            {
                if (walledMap[i, exitY] != null && walledMap[i, exitY].tile == obstacleTile && travSpace[i, exitY - 1])
                {
                    exitOptions.Add(i);
                }
            }
        }
        int exitX = exitOptions[Random.Range(0, exitOptions.Count)];

        walledMap[exitX, exitY].tile = exit;

        //Enter door:
        int        enterY       = -1;
        List <int> enterOptions = new List <int>();

        while (enterOptions.Count == 0 && enterY < walledMap.GetLength(1) - 1)
        {
            enterY++;
            for (int i = 0; i < walledMap.GetLength(0); i++)
            {
                if (walledMap[i, enterY] != null && walledMap[i, enterY].tile == obstacleTile && travSpace[i, enterY + 1])
                {
                    enterOptions.Add(i);
                }
            }
        }
        int enterX = enterOptions[Random.Range(0, enterOptions.Count)];

        walledMap[enterX, enterY].tile = entrance;

        //Now place the player and enemies on the map based on the level and traversable space.
        Vector3 playerLoc = new Vector3(enterX, enterY + 1, 0f);

        Instantiate(player, playerLoc, Quaternion.identity);
        int numEnemies = level * 2;      //Mathf.Max((int)(Mathf.Log(level, 2f)+1)*level/3,level);

        for (int i = 0; i < numEnemies; i++)
        {
            int     randX   = -1;
            int     randY   = -1;
            Vector3 randVec = new Vector3(randX, randY, 0f);
            while (randX == -1 || randY == -1 || !travSpace[randX, randY] || Vector3.Distance(randVec, playerLoc) < 10)
            {
                randX   = Random.Range(0, travSpace.GetLength(0));
                randY   = Random.Range(0, travSpace.GetLength(1));
                randVec = new Vector3(randX, randY, 0f);
            }
            GameObject instance  = Instantiate(enemy, randVec, Quaternion.identity) as GameObject;
            Enemy      thisEnemy = instance.GetComponent <Enemy>();
            if (Enemies == null)
            {
                Enemies = new List <Enemy>();
            }
            Enemies.Add(thisEnemy);
        }

        return(walledMap);
    }