예제 #1
0
        private VertexArray GenerateCliffVertices(SurfaceContainer surface, int[] pos)
        {
            VertexArray vA = new VertexArray(PrimitiveType.Triangles);

            int[] cXY = new int[] { pos[0] * Props.chunkSize, pos[1] * Props.chunkSize };
            for (int i = 0; i < Props.chunkSize; i++)
            {
                for (int j = 0; j < Props.chunkSize; j++)
                {
                    //the current tile in the loop
                    byte currentTile = surface.GetTileFromWorldInt(pos, i, j);
                    #region Skip tile determination
                    if (currentTile != 0)
                    {
                        continue;
                    }
                    #endregion
                    //hash algo
                    int variantX = i * 266489917 + 374761393;
                    variantX  = (variantX << 17) | (variantX >> 15);
                    variantX += j * 266489917;
                    variantX *= 668265263;
                    variantX ^= variantX >> 15;
                    variantX *= 246822519;
                    variantX  = Math.Abs(variantX);
                    //origin that vertices will be defined relative to
                    int oX = (cXY[0] + i) * Props.tileSize;
                    int oY = (cXY[1] + j) * Props.tileSize;

                    int value   = 0;
                    int variant = variantX % 4;                                               //variant is determine by whether the transition is into an impassable tile

                    value += (surface.GetTileFromWorldInt(pos, i - 1, j - 1) != 0) ? 1 : 0;   //top left
                    value += (surface.GetTileFromWorldInt(pos, i, j - 1) != 0) ? 2 : 0;       //top center
                    value += (surface.GetTileFromWorldInt(pos, i + 1, j - 1) != 0) ? 4 : 0;   //top right
                    value += (surface.GetTileFromWorldInt(pos, i - 1, j) != 0) ? 8 : 0;       //left
                    value += (surface.GetTileFromWorldInt(pos, i + 1, j) != 0) ? 16 : 0;      //right
                    value += (surface.GetTileFromWorldInt(pos, i - 1, j + 1) != 0) ? 32 : 0;  //bottom left
                    value += (surface.GetTileFromWorldInt(pos, i, j + 1) != 0) ? 64 : 0;      //bottom center
                    value += (surface.GetTileFromWorldInt(pos, i + 1, j + 1) != 0) ? 128 : 0; //bottom right

                    //Virtual mapping of surrounding tiles
                    // 1 2 3
                    // 4 0 5
                    // 6 7 8
                    //bitflag values of surrounding tiles
                    // 1  2  4
                    // 8  0  16
                    // 32 64 128

                    //need specific checks for if left and right exist simultaneously
                    //if top and bottom exist simultaneously
                    //if two corners exist (u shape) in any config
                    //if four corners exist in any config

                    if (value == 0)
                    {
                        continue; //no surrounding tiles of tiletype
                    }
                    if (((value & 24) + (value & 2)) == 2)
                    {
                        //top fade
                        AppendQuadVerticesCliff(vA, oX, oY, 0, 0, variant, cliffShade, cliffBounds);
                    }
                    if (((value & 24) + (value & 64)) == 64)
                    {
                        //bottom fade
                        AppendQuadVerticesCliff(vA, oX, oY, 4, 0, variant, cliffShade, cliffBounds);
                    }
                    if (((value & 66) + (value & 8)) == 8)
                    {
                        //left fade
                        AppendQuadVerticesCliff(vA, oX, oY, 8, 0, variant, cliffShade, cliffBounds);
                    }
                    if (((value & 66) + (value & 16)) == 16)
                    {
                        //right fade
                        AppendQuadVerticesCliff(vA, oX, oY, 12, 0, variant, cliffShade, cliffBounds);
                    }
                    if ((value & 10) == 10)
                    {
                        //inside corner topleft
                        AppendQuadVerticesCliff(vA, oX, oY, 0, 1, variant, cliffShade, cliffBounds);
                    }
                    else if (((value & 1) + (value & 10)) == 1)
                    {
                        //outside corner topleft
                        AppendQuadVerticesCliff(vA, oX, oY, 0, 2, variant, cliffShade, cliffBounds);
                    }
                    if ((value & 18) == 18)
                    {
                        //inside corner topright
                        AppendQuadVerticesCliff(vA, oX, oY, 4, 1, variant, cliffShade, cliffBounds);
                    }
                    else if (((value & 4) + (value & 18)) == 4)
                    {
                        //outside corner topright
                        AppendQuadVerticesCliff(vA, oX, oY, 4, 2, variant, cliffShade, cliffBounds);
                    }
                    if ((value & 72) == 72)
                    {
                        //inside corner bottomleft
                        AppendQuadVerticesCliff(vA, oX, oY, 8, 1, variant, cliffShade, cliffBounds);
                    }
                    else if (((value & 32) + (value & 72)) == 32)
                    {
                        //outside corner bottomleft
                        AppendQuadVerticesCliff(vA, oX, oY, 8, 2, variant, cliffShade, cliffBounds);
                    }
                    if ((value & 80) == 80)
                    {
                        //inside corner bottomright
                        AppendQuadVerticesCliff(vA, oX, oY, 12, 1, variant, cliffShade, cliffBounds);
                    }
                    else if (((value & 128) + (value & 80)) == 128)
                    {
                        //outside corner bottomright
                        AppendQuadVerticesCliff(vA, oX, oY, 12, 2, variant, cliffShade, cliffBounds);
                    }
                }
            }
            return(vA);
        }
예제 #2
0
        public PathNode GetPath(SurfaceContainer surface, Vector2 start, Vector2 target, int pathTimeout, Base.CollisionLayer unwalkableMask, Base.CollisionLayer collisionMask, float frictionFactor)
        {
            this.frictionFactor = frictionFactor;
            int frictionMask = (int)(collisionMask & Base.CollisionLayer.Terrain); //a nonzero value means the pathcost is higher for lower frictions

            frictionMask = frictionMask / (1 + frictionMask);                      //Normalize the frictionmask to 0 or 1 using +1 trick
            int[] startCoords = surface.WorldToAbsoluteTileCoords(start.x, start.y);
            int[] endCoords   = surface.WorldToAbsoluteTileCoords(target.x, target.y);
            float heuristic   = CalculateHeuristic(startCoords, endCoords);

            PathNode        startNode  = new PathNode(null, 0, 0, heuristic, startCoords);
            List <PathNode> openList   = new List <PathNode>();
            List <PathNode> closedList = new List <PathNode>();
            PathNode        endNode    = null;

            openList.Add(startNode);
            while (openList.Count > 0 && pathTimeout > 0)
            {
                pathTimeout--;
                PathNode curNode     = null;
                int      removeIndex = 0;
                for (int i = 0; i < openList.Count; i++)
                {
                    if (curNode == null || openList[i].cost < curNode.cost)
                    {
                        removeIndex = i;
                        curNode     = openList[i];
                    }
                }
                openList.RemoveAt(removeIndex);
                closedList.Add(curNode);
                if (pathTimeout == 0 || (curNode.coords[0] == endCoords[0] && curNode.coords[1] == endCoords[1]))
                {
                    endNode = curNode;
                    break;
                }
                for (int i = curNode.coords[0] - 1; i <= curNode.coords[0] + 1; i++)
                {
                    for (int j = curNode.coords[1] - 1; j <= curNode.coords[1] + 1; j++)
                    {
                        bool ignore = false;
                        if (i < 0 || j < 0) //Check if coords are outside worldSize
                        {
                            ignore = true;
                        }
                        if (ignore == false) //else check that coords are not already in closedList
                        {
                            for (int k = 0; k < closedList.Count; k++)
                            {
                                if (closedList[k].coords[0] == i && closedList[k].coords[1] == j)
                                {
                                    ignore = true;
                                    break;
                                }
                            }
                        }
                        if (ignore == false) //else check that coords are not already in openList
                        {
                            for (int k = 0; k < openList.Count; k++)
                            {
                                if (openList[k].coords[0] == i && openList[k].coords[1] == j)
                                {
                                    ignore = true;
                                    break;
                                }
                            }
                        }
                        if (!ignore) //if neither of the preceding conditiosn set ignore to false, add tile to open list on path search
                        {
                            Tile tile      = tileCollection.GetTerrainTile(surface.GetTileFromWorldInt(i, j));
                            int  solidMask = (int)((unwalkableMask & collisionMask) & tile.collisionMask); // a zero value when the tile is walkable
                            if (solidMask == 0)
                            {
                                int[]    coords  = new int[] { i, j };
                                PathNode newNode = new PathNode(curNode, frictionMask * (frictionFactor * (1 / tile.frictionModifier)), curNode.begin + 1, CalculateHeuristic(coords, endCoords), coords);
                                openList.Add(newNode);
                            }
                        }
                    }
                }
            }
            return(endNode);
        }
예제 #3
0
        public VertexArray[] GenerateTerrainVertices(SurfaceContainer surface, int[] pos)
        {
            VertexArray[] terrainVertexArray = new VertexArray[terrainTiles.Count];
            terrainVertexArray[0] = GenerateCliffVertices(surface, pos);
            for (int curType = 1; curType < terrainTiles.Count; curType++)
            {
                Tile tile = terrainTiles[curType];
                terrainVertexArray[curType] = new VertexArray(PrimitiveType.Triangles);
                int[] cXY = new int[] { pos[0] * Props.chunkSize, pos[1] * Props.chunkSize };
                for (int i = 0; i < Props.chunkSize; i++)
                {
                    for (int j = 0; j < Props.chunkSize; j++)
                    {
                        //the current tile in the loop
                        byte currentTile = surface.GetTileFromWorldInt(pos, i, j);
                        if (currentTile > curType)
                        {
                            continue;
                        }
                        //hash algo
                        int variantX = i * 266489917 + 374761393;
                        variantX  = (variantX << 17) | (variantX >> 15);
                        variantX += j * 266489917;
                        variantX *= 668265263;
                        variantX ^= variantX >> 15;
                        variantX *= 246822519;
                        variantX  = Math.Abs(variantX);
                        //origin that vertices will be defined relative to
                        int oX = (cXY[0] + i) * Props.tileSize;
                        int oY = (cXY[1] + j) * Props.tileSize;

                        #region Regular tile variant determination
                        if (currentTile == curType)
                        {
                            int variantRegular = variantX % 8;
                            //Append regular tile variation
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 0, 0, variantRegular, tile.shade, tile.textureRect);
                            continue;
                        }
                        #endregion
                        int value   = 0;
                        int variant = variantX % 6; //variant is determine by whether the transition is into an impassable tile
                        if (currentTile != 0 && impassableTileTypes.Contains(currentTile))
                        {
                            variant += 6;
                        }

                        value += (surface.GetTileFromWorldInt(pos, i - 1, j - 1) == curType) ? 1 : 0;   //top left
                        value += (surface.GetTileFromWorldInt(pos, i, j - 1) == curType) ? 2 : 0;       //top center
                        value += (surface.GetTileFromWorldInt(pos, i + 1, j - 1) == curType) ? 4 : 0;   //top right
                        value += (surface.GetTileFromWorldInt(pos, i - 1, j) == curType) ? 8 : 0;       //left
                        value += (surface.GetTileFromWorldInt(pos, i + 1, j) == curType) ? 16 : 0;      //right
                        value += (surface.GetTileFromWorldInt(pos, i - 1, j + 1) == curType) ? 32 : 0;  //bottom left
                        value += (surface.GetTileFromWorldInt(pos, i, j + 1) == curType) ? 64 : 0;      //bottom center
                        value += (surface.GetTileFromWorldInt(pos, i + 1, j + 1) == curType) ? 128 : 0; //bottom right
                        if (value == 0)
                        {
                            continue; //no surrounding tiles of tiletype
                        }
                        if (((value & 24) + (value & 2)) == 2)
                        {
                            //top fade
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 0, 2, variant, tile.shade, tile.textureRect);
                        }
                        if (((value & 24) + (value & 64)) == 64)
                        {
                            //bottom fade
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 12, 2, variant, tile.shade, tile.textureRect);
                        }
                        if (((value & 66) + (value & 8)) == 8)
                        {
                            //left fade
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 0, 3, variant, tile.shade, tile.textureRect);
                        }
                        if (((value & 66) + (value & 16)) == 16)
                        {
                            //right fade
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 12, 3, variant, tile.shade, tile.textureRect);
                        }
                        if ((value & 10) == 10)
                        {
                            //inside corner topleft
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 0, 4, variant, tile.shade, tile.textureRect);
                        }
                        else if (((value & 1) + (value & 10)) == 1)
                        {
                            //outside corner topleft
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 0, 6, variant, tile.shade, tile.textureRect);
                        }
                        if ((value & 18) == 18)
                        {
                            //inside corner topright
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 12, 4, variant, tile.shade, tile.textureRect);
                        }
                        else if (((value & 4) + (value & 18)) == 4)
                        {
                            //outside corner topright
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 12, 6, variant, tile.shade, tile.textureRect);
                        }
                        if ((value & 72) == 72)
                        {
                            //inside corner bottomleft
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 0, 5, variant, tile.shade, tile.textureRect);
                        }
                        else if (((value & 32) + (value & 72)) == 32)
                        {
                            //outside corner bottomleft
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 0, 7, variant, tile.shade, tile.textureRect);
                        }
                        if ((value & 80) == 80)
                        {
                            //inside corner bottomright
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 12, 5, variant, tile.shade, tile.textureRect);
                        }
                        else if (((value & 128) + (value & 80)) == 128)
                        {
                            //outside corner bottomright
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 12, 7, variant, tile.shade, tile.textureRect);
                        }
                    }
                }
            }
            return(terrainVertexArray);
        }