예제 #1
0
        /// <summary>
        /// Fills list of TilePerims of tiles in a TileMap.
        /// </summary>
        /// <param name="tileMap">The TileMap which we are grabbing tiles from</param>
        /// <returns>A list containing the TilePerims in the input TileMap</returns>
        private static List <TilePerim> _FillTiles(TileMap tileMap)
        {
            var tilePerims = new List <TilePerim>();
            var usedCells  = new List <Vector2>(tileMap.GetUsedCells().OfType <Vector2>()); //thanks to godot's C# api array being non-typed i have to commit this atrocity

            for (int i = 0; i < usedCells.Count; i++)
            {
                Vector2           cell        = usedCells[i];
                Vector2           botCoord    = tileMap.MapToWorld(cell); //Thanks to graphics in general using reverse Y axis, the bottom coordinate actually has the HIGHEST y-value
                int               cellID      = tileMap.GetCellv(cell);
                Vector2           originCoord = botCoord - (new Vector2((float)Globals.TileWidth / 2, 0)) + tileMap.TileSet.TileGetTextureOffset(cellID);
                NavigationPolygon navPoly     = tileMap.TileSet.TileGetNavigationPolygon(cellID);

                Vector2[] vertices  = _ShiftVertices(navPoly.Vertices, originCoord);
                var       tilePerim = new TilePerim(vertices, cell, i);
                tilePerims.Add(tilePerim);
            }
            return(tilePerims);
        }
예제 #2
0
        /// <summary>
        /// Flood files TilePerims via DFS, coloring them, in order to find how they are grouped up.
        /// </summary>
        /// <param name="adjMatrix">Adjacency matrix of TilePerims.</param>
        /// <param name="tilePerims"></param>
        /// <param name="thisTile">The tile this function is currently 'looking' at (AKA coloring and checking neighbours)</param>
        /// <param name="color">Color that we paint tiles. Actually an integer.</param>
        /// <returns>The same TilePerim but with changed color. I chose not to modify the TilePerim within the func due to the immutability principle.</returns>
        private static List <TilePerim> _TileFloodFill(IReadOnlyDictionary <int, HashSet <int> > adjMatrix,
                                                       IEnumerable <TilePerim> tilePerims, TilePerim thisTile, int color)
        {
            var tilePerimsClone = new List <TilePerim>(tilePerims);
            var visited         = new HashSet <int>();
            var stack           = new Stack <TilePerim>();

            stack.Push(thisTile);
            visited.Add(thisTile.id);

            while (stack.Any())
            {
                TilePerim examinee = stack.Pop();
                foreach (int neighbourID in adjMatrix[examinee.id].Where(x => !visited.Contains(x)))
                {
                    TilePerim neighbour = tilePerimsClone.Find(x => x.id == neighbourID);
                    stack.Push(neighbour);
                    visited.Add(neighbourID);
                }
                examinee.color = color;
                tilePerimsClone[tilePerimsClone.FindIndex(0, x => x.id == examinee.id)] = examinee;
            }
            return(tilePerimsClone);
        }