Пример #1
0
        /// <summary>
        /// Gets minimap textures for a specified surface.  The position is the centered location. The range is the number of chunks x/y away from center to get.
        /// </summary>
        /// <param name="surface"></param>
        /// <param name="position"></param>
        /// <param name="ranges"></param>
        public void GenerateMinimapTextures(SurfaceContainer surface, Vector2 position, int xRange, int yRange, List <VertexArray> vertexArrays)
        {
            int[] chunkIndices = SurfaceContainer.WorldToChunkCoords(position);
            vertexArrays.Clear();
            for (int i = chunkIndices[0] - xRange; i <= chunkIndices[0] + xRange; i++)
            {
                for (int j = chunkIndices[1] - yRange; j <= chunkIndices[1] + yRange; j++)
                {
                    Chunk chunk = surface.GetChunk((i * surface.worldSize) + j, false);
                    if (chunk != null)
                    {
                        VertexArray vA;
                        if (!minimapVertexArrays.TryGetValue(i * surface.worldSize + j, out vA))
                        {
                            vA = tileCollection.GenerateTerrainMinimap(chunk, (i * surface.worldSize) + j, surface.worldSize);
                            minimapVertexArrays.Add(i * surface.worldSize + j, vA);
                        }
                        vertexArrays.Add(vA);
                        //next get entities
                        //This is very dynamic so there is no point caching it
                        List <Entity> entityList  = chunk.entityList;
                        VertexArray   entityArray = new VertexArray(PrimitiveType.Triangles);
                        int           oX          = i * Props.chunkSize;
                        int           oY          = j * Props.chunkSize;
                        for (int l = 0; l < entityList.Count; l++)
                        {
                            EntityPhysical e = entityList[l] as EntityPhysical;
                            if (e == null)
                            {
                                continue;
                            }
                            int[] pos        = surface.WorldToAbsoluteTileCoords(e.position.x, e.position.y);
                            float halfWidth  = e.tileWidth;
                            float halfHeight = e.tileHeight;
                            entityArray.Append(new Vertex(new Vector2f(pos[0] - halfWidth, pos[1] - halfHeight), e.mapColor));
                            entityArray.Append(new Vertex(new Vector2f(pos[0] + halfWidth, pos[1] - halfHeight), e.mapColor));
                            entityArray.Append(new Vertex(new Vector2f(pos[0] - halfWidth, pos[1] + halfHeight), e.mapColor));

                            entityArray.Append(new Vertex(new Vector2f(pos[0] + halfWidth, pos[1] - halfHeight), e.mapColor));
                            entityArray.Append(new Vertex(new Vector2f(pos[0] + halfWidth, pos[1] + halfHeight), e.mapColor));
                            entityArray.Append(new Vertex(new Vector2f(pos[0] - halfWidth, pos[1] + halfHeight), e.mapColor));
                        }
                        if (entityArray.VertexCount > 0)
                        {
                            vertexArrays.Add(entityArray);
                        }
                    }
                }
            }
        }
Пример #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);
        }