Exemplo n.º 1
0
        public void initializeWithArray(Vector2 lowLeftBound, Vector2 upRightBound, Node.SquareType[][] terrainArr)
        {
            lowerLeftBound = lowLeftBound;
            upperRightBound = upRightBound;
            
            numXNodes = terrainArr[0].Length;
            numYNodes = terrainArr.Length;

            // Determine correct node density
            float xDist = lowerLeftBound.x - upperRightBound.x;
            nodeDensity = numXNodes / xDist;

            // Magic number allows for proper drawing of nodes.
            radii = 0.75f / nodeDensity;
            
            numValidNodes = 0;

            // Initialize the node array. Note the inverted y, normal x setup.
            nodeArr = new Node[numYNodes][];
            for (int y = 0; y < numYNodes; y++)
            {
                nodeArr[y] = new Node[numXNodes];

                for (int x = 0; x < numXNodes; x++)
                {
                    IntVec2 arrPos = new IntVec2(x, y);
                    Vector2 newPosV2 = ArrPosToWorldSpace(arrPos);

                    nodeArr[y][x] = new Node(transform.gameObject, nodeImg, newPosV2, arrPos, terrainArr[y][x], radii * 2, numValidNodes++);

                    //add up-left edge (inverse y)
                    if (allowedPaths > Paths.quadDir)
                    {
                        if (x - 1 >= 0 && y - 1 >= 0
                            && isOkayToFloodDiag(arrPos, IntVec2.down, IntVec2.left))
                            nodeArr[y][x].addBidirEdge(nodeArr[y - 1][x - 1], sqrt2);
                        //add up-right edge (inverse y)
                        if (x + 1 < numXNodes && y - 1 >= 0
                            && isOkayToFloodDiag(arrPos, IntVec2.down, IntVec2.right))
                            nodeArr[y][x].addBidirEdge(nodeArr[y - 1][x + 1], sqrt2);
                    }
                    //add up edge
                    if (y - 1 >= 0
                        && isOkayToFloodUDLR(arrPos, IntVec2.down, (Vector2)IntVec2.left))
                        nodeArr[y][x].addBidirEdge(nodeArr[y - 1][x], 1);
                    //add left edge
                    if (x - 1 >= 0
                        && isOkayToFloodUDLR(arrPos, IntVec2.left, (Vector2)IntVec2.up))
                        nodeArr[y][x].addBidirEdge(nodeArr[y][x - 1], 1);
                }
            }

            isInitialized = true;
        }
Exemplo n.º 2
0
 // Same, but with diagonals.
 private bool isOkayToFloodDiag(IntVec2 startPos, IntVec2 dir1, IntVec2 dir2)
 {
     return true;
 }
Exemplo n.º 3
0
        /// <summary>
        /// Converts an array position to world space.
        /// </summary>
        /// <param name="pos">The position in array space.</param>
        /// <returns>The position in world space.</returns>
        public Vector2 ArrPosToWorldSpace(IntVec2 pos)
        {
            float x = pos.x / nodeDensity;
            float y = pos.y / nodeDensity;
            x += lowerLeftBound.x;
            y += lowerLeftBound.y;

            return new Vector2(x, y);
        }
Exemplo n.º 4
0
 /// <summary>
 /// null helper function for floodfill.
 /// Returns true.
 /// </summary>
 /// <returns>true!</returns>
 private bool isOkayToFloodUDLR(IntVec2 startPos, IntVec2 direction, Vector2 orthAngle)
 {
     return true;
 }
Exemplo n.º 5
0
        // Same, but with diagonals.
        private bool isOkayToFloodDiag(IntVec2 startPos, IntVec2 dir1, IntVec2 dir2)
        {
            IntVec2 newPos = startPos + dir1 + dir2;
            IntVec2 orth = dir1 - dir2;
            Vector2 orthAngle = ((Vector2) orth) / sqrt2;
            Vector2 newPosV2 = ArrPosToWorldSpace(newPos);
            Vector2 oldPosV2 = ArrPosToWorldSpace(startPos);

            //Linecase uses width in consideration of spreading to new nodes, this time diagonally
            return (!Physics2D.OverlapCircle(newPosV2, radii, LAYER_FILTER_MASK)
                 && !Physics2D.Linecast(oldPosV2 + orthAngle * radii, newPosV2 + orthAngle * radii, LAYER_FILTER_MASK)
                 && !Physics2D.Linecast(oldPosV2 - orthAngle * radii, newPosV2 - orthAngle * radii, LAYER_FILTER_MASK));
        }
Exemplo n.º 6
0
        /// <summary>
        /// Helper function for floodfill. Does extra checks / physics checks to see if we can add a node in the specified location.
        /// </summary>
        /// <param name="startPos">The position to start from.</param>
        /// <param name="direction">The direction to go to.</param>
        /// <param name="orthAngle">The orthogonal to the direction.</param>
        /// <returns></returns>
        private bool isOkayToFloodUDLR(IntVec2 startPos, IntVec2 direction, Vector2 orthAngle)
        {
            IntVec2 newPos = startPos + direction;
            Vector2 newPosV2 = ArrPosToWorldSpace(newPos);
            Vector2 oldPosV2 = ArrPosToWorldSpace(startPos);

            //Linecase uses width in consideration of spreading to new nodes.
            return (!Physics2D.OverlapCircle(newPosV2, radii, LAYER_FILTER_MASK)
                 && !Physics2D.Linecast(oldPosV2 + orthAngle * radii, newPosV2 + orthAngle * radii, LAYER_FILTER_MASK)
                 && !Physics2D.Linecast(oldPosV2 - orthAngle * radii, newPosV2 - orthAngle * radii, LAYER_FILTER_MASK));
        }
Exemplo n.º 7
0
        /// <summary>
        /// Fills all nodes in area and connects edges as necessesary.
        /// Does not have stack overflow problems, but may create a graph
        /// that isn't connected all the way through.
        /// </summary>
        private void fillAll()
        {
            for (int y = 0; y < numYNodes; y++)
            {
                for (int x = 0; x < numXNodes; x++)
                {
                    IntVec2 arrPos = new IntVec2(x, y);
                    Vector2 newPosV2 = ArrPosToWorldSpace(arrPos);

#if DEBUG_PATHFINDER_UPDATELOOP
                    if (!Physics2D.OverlapCircle(newPosV2, radii, LAYER_FILTER_MASK))
#endif
                    {
                        nodeArr[y][x] = new Node(transform.gameObject, nodeImg, newPosV2, arrPos, Node.randWalkState(), radii * 2, numValidNodes++);

                        //add up-left edge (inverse y)
                        if (allowedPaths > Paths.quadDir)
                        {
                            if (x - 1 >= 0 && y - 1 >= 0
                                && nodeArr[y - 1][x - 1] != null
                                && isOkayToFloodDiag(arrPos, IntVec2.down, IntVec2.left))
                                nodeArr[y][x].addBidirEdge(nodeArr[y - 1][x - 1], sqrt2);
                            //add up-right edge (inverse y)
                            if (x + 1 < numXNodes && y - 1 >= 0
                                && nodeArr[y - 1][x + 1] != null
                                && isOkayToFloodDiag(arrPos, IntVec2.down, IntVec2.right))
                                nodeArr[y][x].addBidirEdge(nodeArr[y - 1][x + 1], sqrt2);
                        }
                        //add up edge
                        if (y - 1 >= 0
                            && nodeArr[y - 1][x] != null
                            && isOkayToFloodUDLR(arrPos, IntVec2.down, (Vector2)IntVec2.left))
                            nodeArr[y][x].addBidirEdge(nodeArr[y - 1][x], 1);
                        //add left edge
                        if (x - 1 >= 0
                            && nodeArr[y][x - 1] != null
                            && isOkayToFloodUDLR(arrPos, IntVec2.left, (Vector2)IntVec2.up))
                            nodeArr[y][x].addBidirEdge(nodeArr[y][x - 1], 1);
                    }
                }
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Constructs a Node.
        /// </summary>
        /// <param name="floorImg">The image which the node will use to display itself if set to do so.</param>
        /// <param name="position">Where the node is positioned in world space.</param>
        /// <param name="gridPos">The node position in the graph space.</param>
        /// <param name="scale">The node's visible scale.</param>
        /// <param name="num">The node's internal number.</param>
        /// <param name="vis">Whether the node is visible or not. Default is false.</param>
        public Node(GameObject parent, Sprite floorImg, Vector2 position, IntVec2 gridPos, SquareType typeOfTerrain, float scale = 0.75f, int num = 0, bool vis = true)
        {
            pos = position;
            this.gridPos = gridPos;
            GameObject drawer = new GameObject("Node " + pos);
            drawer.isStatic = true;
            drawer.transform.parent = parent.transform;

            //set sprite back in z, so it draws beneath everything.
            drawer.transform.position = new Vector3(position.x, position.y, 1);

            spriteDraw = drawer.AddComponent<SpriteRenderer>();
            spriteDraw.sprite = floorImg;
            drawer.tag = gameTag;
            // Draw a little bigger than scale.
            spriteDraw.transform.localScale = new Vector2(scale * 1.35f, scale * 1.35f);

            // Draw with 50% alpha-white.
            //spriteDraw.color = defColor;
            //terrainType = randWalkState();
            terrainType = typeOfTerrain;
            edgePenalty = costOfWalkState(terrainType);
            resetColor();
            //spriteDraw.color = Random.ColorHSV(0.2f, 1.0f, 0.1f, 0.7f, 0.2f, 1.0f);

            CameFrom = null;
            number = num;

#if DEBUG_NODE_EDGES
            lineDraw = drawer.AddComponent<LineRenderer>();
            lineDraw.SetWidth(0.1f, 0.1f);
            lineDraw.SetVertexCount(maxEdges * 2 + 1);
            for (int i = 0; i < 17; i++)
                lineDraw.SetPosition(i, pos);
#endif

#if DEBUG_NODE_TEXT
            GameObject guiText = new GameObject("Debug text on Node " + pos);
            Vector2 guiPos = new Vector2(Camera.main.WorldToScreenPoint(pos).x / Camera.main.pixelWidth,
                                         Camera.main.WorldToScreenPoint(pos).y / Camera.main.pixelHeight);
            guiText.transform.position = guiPos;
            visNodeNum = guiText.AddComponent<GUIText>();
            visNodeNum.text = num.ToString();
            visNodeNum.anchor = TextAnchor.MiddleCenter;
#endif
            // Do not move this, everything must be defined before calling Visible.
            Visible = vis;
        }