Esempio n. 1
0
    /// <summary> A* path search -> HAS TO BE RUN ON MAIN THREAD</summary>
    /// <param name="tiles"></param>
    private void CreatePaths()
    {
        if (positions.Count() >= 2)
        {
            for (int i = 0; i < positions.Count - 1; i++)
            {
                UnityEngine.Debug.Log(positions[i]);

                activeTiles.Clear();
                visitedTiles.Clear();

                AreaTile start = new AreaTile()
                {
                    position = positions[i]
                };

                AreaTile end = new AreaTile()
                {
                    position = positions[i + 1]
                };

                start.SetDistance(end.position);
                activeTiles.Add(start);

                GeneratePathPoint(start, end);
            }
        }
        else
        {
            UnityEngine.Debug.Log("2 or more path points required to generate path");
        }
    }
Esempio n. 2
0
    private System.Collections.Generic.IEnumerable <AreaTile> GetTileGrid(AreaTile currentTile, AreaTile targetTile)
    {
        for (int z = -1; z < 2; z++)
        {
            for (int x = -1; x < 2; x++)
            {
                Vector3 position = currentTile.position;
                position.X += x;
                position.Z += z;


                if (parent.PositionWithinObject(parent.gameObject, position) & childObjects.All(obj => !parent.PositionWithinObject(obj.gameObject, position)))
                {
                    AreaTile gridTile = new AreaTile
                    {
                        position = position,
                        Parent   = currentTile,
                        Cost     = currentTile.Cost + 1
                    };

                    gridTile.SetDistance(targetTile.position);

                    yield return(gridTile);
                }
            }
        }
    }
Esempio n. 3
0
 private void TracePath(AreaTile areaTile)
 {
     while (areaTile != null)
     {
         parent.CreateAreaObject(null, areaTile.position, UnityEngine.Quaternion.identity);
         areaTile = areaTile.Parent;
     }
 }
Esempio n. 4
0
    private void GeneratePathPoint(AreaTile current, AreaTile end)
    {
        while (activeTiles.Any())
        {
            current = activeTiles.OrderBy(tile => tile.CostDistance).First();

            // Destination reached.
            if ((System.Math.Round(current.position.X, 0) == System.Math.Round(end.position.X, 0)) &&
                (System.Math.Round(current.position.Z, 0) == System.Math.Round(end.position.Z, 0)))
            {
                TracePath(current);
                return;
            }

            visitedTiles.Add(current);
            activeTiles.Remove(current);

            foreach (AreaTile tile in GetTileGrid(current, end))
            {
                double currentTileX = System.Math.Round(tile.position.X, 0);
                double currentTileZ = System.Math.Round(tile.position.Z, 0);
                if (visitedTiles.Any(cTile => (System.Math.Round(cTile.position.X, 0) == currentTileX) &&
                                     (System.Math.Round(cTile.position.Z, 0) == currentTileZ)))
                {
                    continue;
                }

                if (activeTiles.Any(cTile => (System.Math.Round(cTile.position.X, 0) == currentTileX) &&
                                    (System.Math.Round(cTile.position.Z, 0) == currentTileZ)))
                {
                    AreaTile scannedTile = activeTiles.First(cTile => (System.Math.Round(cTile.position.X, 0) == currentTileX) &&
                                                             (System.Math.Round(cTile.position.Z, 0) == currentTileZ));

                    if (scannedTile.CostDistance > tile.CostDistance)
                    {
                        activeTiles.Remove(scannedTile);
                        activeTiles.Add(tile);
                    }
                }
                else
                {
                    activeTiles.Add(tile);
                }
            }
        }
    }
    /// <summary>
    /// Returns the next object in the given world direction, starting from the position,
    /// but not including the position itself
    /// </summary>
    /// <param name="pos"></param>
    /// <param name="dir"></param>
    /// <returns></returns>
    public static Entity nextObjectInDirection(Vector2 pos, Vector2 dir, bool checkTiles = false)
    {
        if (pos == null || dir == null || dir == Vector2.zero)
        {
            return(null);
        }
        dir.Normalize();
        if (dir.magnitude < 1)
        {
            return(null);
        }
        pos  += dir;
        pos.x = Mathf.Round(pos.x);
        pos.y = Mathf.Round(pos.y);
        while (pos.x >= 0 && pos.x < grid.GetLength(0) &&
               pos.y >= 0 && pos.y < grid.GetLength(1))
        {
            GameObject go = objectAtPosition(pos);
            if (go != null)
            {
                return(go.GetComponent <Entity>());
            }
            if (checkTiles)
            {
                AreaTile tile = areaGrid[(int)pos.x, (int)pos.y];
                if (tile.type != AreaTile.AreaType.GROUND)
                {
                    return(tile);
                }
            }

            pos  += dir;
            pos.x = Mathf.Round(pos.x);
            pos.y = Mathf.Round(pos.y);
        }
        return(null);
    }
        /*private AreaTileType[,] ListToMatrix(List<AreaTile> pass, List<AreaTile> bord, int resolution, Random random, double proba)
        {
            int minX = 0;
            int maxX = 0;
            int minY = 0;
            int maxY = 0;

            foreach (AreaTile tile in bord)
            {
                if (tile.X < minX) minX = tile.X;
                if (tile.Y < minY) minY = tile.Y;
                if (tile.X > maxX) maxX = tile.X;
                if (tile.Y > maxY) maxY = tile.Y;
            }

            foreach (AreaTile tile in pass)
            {
                if (tile.X < minX) minX = tile.X;
                if (tile.Y < minY) minY = tile.Y;
                if (tile.X > maxX) maxX = tile.X;
                if (tile.Y > maxY) maxY = tile.Y;
            }
            minX *= resolution;
            minY *= resolution;
            maxX *= resolution;
            maxY *= resolution;

            Width = maxX - minX + resolution;
            Height = maxY - minY + resolution;
            Center = new AreaTile(-minX, -minY);

            AreaTileType[,] res = new AreaTileType[Width, Height];
            for (int i = 0; i < Width; i++)
            {
                for (int j = 0; j < Height; j++)
                {
                    res[i, j] = AreaTileType.Depth;
                }
            }

            foreach (AreaTile tile in pass)
            {
                for (int i = 0; i < resolution; i++)
                {
                    for (int j = 0; j < resolution; j++)
                    {
                        res[tile.X * resolution + i - minX, tile.Y * resolution + j - minY] = AreaTileType.Ground;
                    }
                }
            }

            foreach (AreaTile tile in bord)
            {
                for (int i = 0; i < resolution; i++)
                {
                    for (int j = 0; j < resolution; j++)
                    {
                        res[tile.X * resolution + i - minX, tile.Y * resolution + j - minY] = AreaTileType.Wall;
                    }
                }

                if (resolution > 1)
                {

                    //x--
                    //---
                    //---

                    if (!bord.Contains(new AreaTile(tile.X - 1, tile.Y - 1)) &&
                        ((pass.Contains(new AreaTile(tile.X - 1, tile.Y)) && random.NextDouble() < proba) ||
                        (pass.Contains(new AreaTile(tile.X, tile.Y - 1)) && random.NextDouble() < proba)))
                    {
                        res[tile.X * resolution - minX, tile.Y * resolution - minY] = AreaTileType.Ground;
                    }

                    //-x-
                    //---
                    //---

                    if (pass.Contains(new AreaTile(tile.X, tile.Y - 1)))
                    {
                        for (int k = 1; k < resolution - 1; k++)
                        {
                            if (random.NextDouble() < proba)
                            {
                                res[tile.X * resolution + k - minX, tile.Y * resolution - minY] = AreaTileType.Ground;
                            }
                        }
                    }

                    //--x
                    //---
                    //---

                    if (!bord.Contains(new AreaTile(tile.X + 1, tile.Y - 1)) &&
                        ((pass.Contains(new AreaTile(tile.X + 1, tile.Y)) && random.NextDouble() < proba) ||
                        (pass.Contains(new AreaTile(tile.X, tile.Y - 1)) && random.NextDouble() < proba)))
                    {
                        res[(tile.X + 1) * resolution - 1 - minX, tile.Y * resolution - minY] = AreaTileType.Ground;
                    }

                    //---
                    //--x
                    //---

                    if (pass.Contains(new AreaTile(tile.X + 1, tile.Y)))
                    {
                        for (int k = 1; k < resolution - 1; k++)
                        {
                            if (random.NextDouble() < proba)
                            {
                                res[(tile.X + 1) * resolution - 1 - minX, tile.Y * resolution + k - minY] = AreaTileType.Ground;
                            }
                        }
                    }

                    //---
                    //---
                    //--x

                    if (!bord.Contains(new AreaTile(tile.X + 1, tile.Y + 1)) &&
                        ((pass.Contains(new AreaTile(tile.X + 1, tile.Y)) && random.NextDouble() < proba) ||
                        (pass.Contains(new AreaTile(tile.X, tile.Y + 1)) && random.NextDouble() < proba)))
                    {
                        res[(tile.X + 1) * resolution - 1 - minX, (tile.Y + 1) * resolution - 1 - minY] = AreaTileType.Ground;
                    }

                    //-x-
                    //---
                    //---

                    if (pass.Contains(new AreaTile(tile.X, tile.Y + 1)))
                    {
                        for (int k = 1; k < resolution - 1; k++)
                        {
                            if (random.NextDouble() < proba)
                            {
                                res[tile.X * resolution + k - minX, (tile.Y + 1) * resolution - 1 - minY] = AreaTileType.Ground;
                            }
                        }
                    }

                    //---
                    //---
                    //x--

                    if (!bord.Contains(new AreaTile(tile.X - 1, tile.Y + 1)) &&
                        ((pass.Contains(new AreaTile(tile.X - 1, tile.Y)) && random.NextDouble() < proba) ||
                        (pass.Contains(new AreaTile(tile.X, tile.Y + 1)) && random.NextDouble() < proba)))
                    {
                        res[tile.X * resolution - minX, (tile.Y + 1) * resolution - 1 - minY] = AreaTileType.Ground;
                    }

                    //---
                    //x--
                    //---

                    if (pass.Contains(new AreaTile(tile.X - 1, tile.Y)))
                    {
                        for (int k = 1; k < resolution - 1; k++)
                        {
                            if (random.NextDouble() < proba)
                            {
                                res[tile.X * resolution - minX, tile.Y * resolution + k - minY] = AreaTileType.Ground;
                            }
                        }
                    }

                }
            }

            return res;
        }*/
        private AreaTileType[,] ListToMatrix(HashSet<AreaTile> pass, HashSet<AreaTile> bord, int resolution, Random random, double proba)
        {
            int minX = 0;
            int maxX = 0;
            int minY = 0;
            int maxY = 0;

            foreach (AreaTile tile in bord)
            {
                if (tile.X < minX) minX = tile.X;
                if (tile.Y < minY) minY = tile.Y;
                if (tile.X > maxX) maxX = tile.X;
                if (tile.Y > maxY) maxY = tile.Y;
            }

            foreach (AreaTile tile in pass)
            {
                if (tile.X < minX) minX = tile.X;
                if (tile.Y < minY) minY = tile.Y;
                if (tile.X > maxX) maxX = tile.X;
                if (tile.Y > maxY) maxY = tile.Y;
            }
            minX *= resolution;
            minY *= resolution;
            maxX *= resolution;
            maxY *= resolution;

            Width = maxX - minX + resolution;
            Height = maxY - minY + resolution;
            Center = new AreaTile(-minX, -minY);

            AreaTileType[,] res = new AreaTileType[Width, Height];
            for (int i = 0; i < Width; i++)
            {
                for (int j = 0; j < Height; j++)
                {
                    res[i, j] = AreaTileType.Depth;
                }
            }

            foreach (AreaTile tile in pass)
            {
                for (int i = 0; i < resolution; i++)
                {
                    for (int j = 0; j < resolution; j++)
                    {
                        res[tile.X * resolution + i - minX, tile.Y * resolution + j - minY] = AreaTileType.Ground;
                    }
                }
            }

            foreach (AreaTile tile in bord)
            {
                for (int i = 0; i < resolution; i++)
                {
                    for (int j = 0; j < resolution; j++)
                    {
                        res[tile.X * resolution + i - minX, tile.Y * resolution + j - minY] = AreaTileType.Wall;
                    }
                }

                if (resolution > 1)
                {

                    //x--
                    //---
                    //---

                    if (!bord.Contains(new AreaTile(tile.X - 1, tile.Y - 1)) &&
                        ((pass.Contains(new AreaTile(tile.X - 1, tile.Y)) && random.NextDouble() < proba) ||
                        (pass.Contains(new AreaTile(tile.X, tile.Y - 1)) && random.NextDouble() < proba)))
                    {
                        res[tile.X * resolution - minX, tile.Y * resolution - minY] = AreaTileType.Ground;
                    }

                    //-x-
                    //---
                    //---

                    if (pass.Contains(new AreaTile(tile.X, tile.Y - 1)))
                    {
                        for (int k = 1; k < resolution - 1; k++)
                        {
                            if (random.NextDouble() < proba)
                            {
                                res[tile.X * resolution + k - minX, tile.Y * resolution - minY] = AreaTileType.Ground;
                            }
                        }
                    }

                    //--x
                    //---
                    //---

                    if (!bord.Contains(new AreaTile(tile.X + 1, tile.Y - 1)) &&
                        ((pass.Contains(new AreaTile(tile.X + 1, tile.Y)) && random.NextDouble() < proba) ||
                        (pass.Contains(new AreaTile(tile.X, tile.Y - 1)) && random.NextDouble() < proba)))
                    {
                        res[(tile.X + 1) * resolution - 1 - minX, tile.Y * resolution - minY] = AreaTileType.Ground;
                    }

                    //---
                    //--x
                    //---

                    if (pass.Contains(new AreaTile(tile.X + 1, tile.Y)))
                    {
                        for (int k = 1; k < resolution - 1; k++)
                        {
                            if (random.NextDouble() < proba)
                            {
                                res[(tile.X + 1) * resolution - 1 - minX, tile.Y * resolution + k - minY] = AreaTileType.Ground;
                            }
                        }
                    }

                    //---
                    //---
                    //--x

                    if (!bord.Contains(new AreaTile(tile.X + 1, tile.Y + 1)) &&
                        ((pass.Contains(new AreaTile(tile.X + 1, tile.Y)) && random.NextDouble() < proba) ||
                        (pass.Contains(new AreaTile(tile.X, tile.Y + 1)) && random.NextDouble() < proba)))
                    {
                        res[(tile.X + 1) * resolution - 1 - minX, (tile.Y + 1) * resolution - 1 - minY] = AreaTileType.Ground;
                    }

                    //-x-
                    //---
                    //---

                    if (pass.Contains(new AreaTile(tile.X, tile.Y + 1)))
                    {
                        for (int k = 1; k < resolution - 1; k++)
                        {
                            if (random.NextDouble() < proba)
                            {
                                res[tile.X * resolution + k - minX, (tile.Y + 1) * resolution - 1 - minY] = AreaTileType.Ground;
                            }
                        }
                    }

                    //---
                    //---
                    //x--

                    if (!bord.Contains(new AreaTile(tile.X - 1, tile.Y + 1)) &&
                        ((pass.Contains(new AreaTile(tile.X - 1, tile.Y)) && random.NextDouble() < proba) ||
                        (pass.Contains(new AreaTile(tile.X, tile.Y + 1)) && random.NextDouble() < proba)))
                    {
                        res[tile.X * resolution - minX, (tile.Y + 1) * resolution - 1 - minY] = AreaTileType.Ground;
                    }

                    //---
                    //x--
                    //---

                    if (pass.Contains(new AreaTile(tile.X - 1, tile.Y)))
                    {
                        for (int k = 1; k < resolution - 1; k++)
                        {
                            if (random.NextDouble() < proba)
                            {
                                res[tile.X * resolution - minX, tile.Y * resolution + k - minY] = AreaTileType.Ground;
                            }
                        }
                    }

                }
            }

            return res;
        }
        public void HillGen2(int baseSize, List<AreaTile> sources, int mult, int threshold)
        {
            HashSet<AreaTile> passable = new HashSet<AreaTile>();
            HashSet<AreaTile> border = new HashSet<AreaTile>();
            HashSet<AreaTile> ring = new HashSet<AreaTile>();
            //AreaTile center = new AreaTile(0, 0);
            //initCenter(center, passable, border, ring);
            List<HashSet<AreaTile>> borders = new List<HashSet<AreaTile>>();
            foreach (AreaTile source in sources)
            {
                AreaTile source2 = new AreaTile(source.X * mult, source.Y * mult);
                InitCenter(source2, passable, border, ring);
                HashSet<AreaTile> border2 = new HashSet<AreaTile>();
                borders.Add(border2);
                InitCenter(source2, passable, border2, ring);
            }

            for (int i = 0; i < baseSize; i++)
            {
                HashSet<AreaTile> border2 = borders[i % borders.Count];
                if (border2.Count == 0)
                {
                    continue;
                }

                List<AreaTile> validBorders = GetValidBorders(passable, border2);
                if (validBorders.Count == 0)
                {
                    continue;
                }
                AreaTile tile = validBorders[random.Next(validBorders.Count)];
                border2.Remove(tile);
                border.Remove(tile);
                passable.Add(tile);

                Add8adjTiles(random.Next(8), tile, border, passable, ring, border2);
            }

            RemoveNoBorder(passable, border, 1, random, true);

            List<AreaTile> validborderPaths = GetValidBorderPaths(passable, border);
            for (int i = 0; i < 1 + validborderPaths.Count / 50; i++)
            {
                AreaTile exit = validborderPaths[random.Next(validborderPaths.Count)];
                border.Remove(exit);
                passable.Add(exit);
            }

            int subSize = GetValidCenters(passable, border).Count;
            if (subSize > threshold) HillGen3(subSize, passable, border, threshold);

            passable.UnionWith(ring);

            _tiles = ListToMatrix(passable, border, 1, random, 0);
        }
 private void InitCenter(AreaTile center, HashSet<AreaTile> passable, HashSet<AreaTile> border, HashSet<AreaTile> ring)
 {
     passable.Add(new AreaTile(center.X, center.Y));
     border.Add(new AreaTile(center.X + 1, center.Y));
     border.Add(new AreaTile(center.X - 1, center.Y));
     border.Add(new AreaTile(center.X, center.Y + 1));
     border.Add(new AreaTile(center.X, center.Y - 1));
     border.Add(new AreaTile(center.X + 1, center.Y + 1));
     border.Add(new AreaTile(center.X - 1, center.Y - 1));
     border.Add(new AreaTile(center.X - 1, center.Y + 1));
     border.Add(new AreaTile(center.X + 1, center.Y - 1));
     ring.Add(new AreaTile(center.X + 2, center.Y + 2));
     ring.Add(new AreaTile(center.X + 2, center.Y + 1));
     ring.Add(new AreaTile(center.X + 2, center.Y));
     ring.Add(new AreaTile(center.X + 2, center.Y - 1));
     ring.Add(new AreaTile(center.X + 2, center.Y - 2));
     ring.Add(new AreaTile(center.X + 1, center.Y + 2));
     ring.Add(new AreaTile(center.X, center.Y + 2));
     ring.Add(new AreaTile(center.X - 1, center.Y + 2));
     ring.Add(new AreaTile(center.X - 2, center.Y + 2));
     ring.Add(new AreaTile(center.X - 2, center.Y + 1));
     ring.Add(new AreaTile(center.X - 2, center.Y));
     ring.Add(new AreaTile(center.X - 2, center.Y - 1));
     ring.Add(new AreaTile(center.X - 2, center.Y - 2));
     ring.Add(new AreaTile(center.X - 1, center.Y - 2));
     ring.Add(new AreaTile(center.X, center.Y - 2));
     ring.Add(new AreaTile(center.X + 1, center.Y - 2));
 }
        /*private int GetAdjVoidTiles(AreaTile tile, List<AreaTile> passable, List<AreaTile> border, bool square)
        {
            int res = 0;

            AreaTile adjTile = new AreaTile(tile.X + 1, tile.Y);
            if (!passable.Contains(adjTile) && !border.Contains(adjTile)) res++;
            adjTile = new AreaTile(tile.X, tile.Y + 1);
            if (!passable.Contains(adjTile) && !border.Contains(adjTile)) res++;
            adjTile = new AreaTile(tile.X - 1, tile.Y);
            if (!passable.Contains(adjTile) && !border.Contains(adjTile)) res++;
            adjTile = new AreaTile(tile.X, tile.Y - 1);
            if (!passable.Contains(adjTile) && !border.Contains(adjTile)) res++;

            if (square)
            {
                adjTile = new AreaTile(tile.X + 1, tile.Y + 1);
                if (!passable.Contains(adjTile) && !border.Contains(adjTile)) res++;
                adjTile = new AreaTile(tile.X + 1, tile.Y - 1);
                if (!passable.Contains(adjTile) && !border.Contains(adjTile)) res++;
                adjTile = new AreaTile(tile.X - 1, tile.Y + 1);
                if (!passable.Contains(adjTile) && !border.Contains(adjTile)) res++;
                adjTile = new AreaTile(tile.X - 1, tile.Y - 1);
                if (!passable.Contains(adjTile) && !border.Contains(adjTile)) res++;
            }

            return res;
        }*/
        private int GetAdjVoidTiles(AreaTile tile, HashSet<AreaTile> passable, HashSet<AreaTile> border, bool square)
        {
            int res = 0;

            AreaTile adjTile = new AreaTile(tile.X + 1, tile.Y);
            if (!passable.Contains(adjTile) && !border.Contains(adjTile)) res++;
            adjTile = new AreaTile(tile.X, tile.Y + 1);
            if (!passable.Contains(adjTile) && !border.Contains(adjTile)) res++;
            adjTile = new AreaTile(tile.X - 1, tile.Y);
            if (!passable.Contains(adjTile) && !border.Contains(adjTile)) res++;
            adjTile = new AreaTile(tile.X, tile.Y - 1);
            if (!passable.Contains(adjTile) && !border.Contains(adjTile)) res++;

            if (square)
            {
                adjTile = new AreaTile(tile.X + 1, tile.Y + 1);
                if (!passable.Contains(adjTile) && !border.Contains(adjTile)) res++;
                adjTile = new AreaTile(tile.X + 1, tile.Y - 1);
                if (!passable.Contains(adjTile) && !border.Contains(adjTile)) res++;
                adjTile = new AreaTile(tile.X - 1, tile.Y + 1);
                if (!passable.Contains(adjTile) && !border.Contains(adjTile)) res++;
                adjTile = new AreaTile(tile.X - 1, tile.Y - 1);
                if (!passable.Contains(adjTile) && !border.Contains(adjTile)) res++;
            }

            return res;
        }
 private int Dist(AreaTile t1, AreaTile t2, bool square)
 {
     if (!square) return Math.Abs(t1.X - t2.X) + Math.Abs(t1.Y - t2.Y);
     else return Math.Max(Math.Abs(t1.X - t2.X), Math.Abs(t1.Y - t2.Y));
 }
        private List<AreaTile> Add8adjTiles(int k, AreaTile tile, HashSet<AreaTile> adding, HashSet<AreaTile> removing, HashSet<AreaTile> removing2, HashSet<AreaTile> adding2)
        {
            List<AreaTile> added = new List<AreaTile>();
            AreaTile newTile;
            int d = 1;
            k = (k + d) % 8;
            if (k < 0) k += 8;
            for (int j = 0; j < 8; j++)
            {
                switch (k)
                {
                    case 0:
                        newTile = new AreaTile(tile.X + 1, tile.Y);
                        if (!adding.Contains(newTile) && !removing.Contains(newTile))
                        {
                            adding.Add(newTile);
                            if (adding2 != null) adding2.Add(newTile);
                            if (removing2 != null)
                            {
                                removing2.Remove(newTile);
                                added.Add(newTile);
                            }
                        }
                        break;
                    case 1:
                        newTile = new AreaTile(tile.X, tile.Y + 1);
                        if (!adding.Contains(newTile) && !removing.Contains(newTile))
                        {
                            adding.Add(newTile);
                            if (adding2 != null) adding2.Add(newTile);
                            if (removing2 != null)
                            {
                                removing2.Remove(newTile);
                                added.Add(newTile);
                            }
                        }
                        break;
                    case 2:
                        newTile = new AreaTile(tile.X - 1, tile.Y);
                        if (!adding.Contains(newTile) && !removing.Contains(newTile))
                        {
                            adding.Add(newTile);
                            if (adding2 != null) adding2.Add(newTile);
                            if (removing2 != null)
                            {
                                removing2.Remove(newTile);
                                added.Add(newTile);
                            }
                        }
                        break;
                    case 3:
                        newTile = new AreaTile(tile.X, tile.Y - 1);
                        if (!adding.Contains(newTile) && !removing.Contains(newTile))
                        {
                            adding.Add(newTile);
                            if (adding2 != null) adding2.Add(newTile);
                            if (removing2 != null)
                            {
                                removing2.Remove(newTile);
                                added.Add(newTile);
                            }
                        }
                        break;
                    case 4:
                        newTile = new AreaTile(tile.X + 1, tile.Y + 1);
                        if (!adding.Contains(newTile) && !removing.Contains(newTile))
                        {
                            adding.Add(newTile);
                            if (adding2 != null) adding2.Add(newTile);
                            if (removing2 != null)
                            {
                                removing2.Remove(newTile);
                                added.Add(newTile);
                            }
                        }
                        break;
                    case 5:
                        newTile = new AreaTile(tile.X + 1, tile.Y - 1);
                        if (!adding.Contains(newTile) && !removing.Contains(newTile))
                        {
                            adding.Add(newTile);
                            if (adding2 != null) adding2.Add(newTile);
                            if (removing2 != null)
                            {
                                removing2.Remove(newTile);
                                added.Add(newTile);
                            }
                        }
                        break;
                    case 6:
                        newTile = new AreaTile(tile.X - 1, tile.Y + 1);
                        if (!adding.Contains(newTile) && !removing.Contains(newTile))
                        {
                            adding.Add(newTile);
                            if (adding2 != null) adding2.Add(newTile);
                            if (removing2 != null)
                            {
                                removing2.Remove(newTile);
                                added.Add(newTile);
                            }
                        }
                        break;
                    case 7:
                        newTile = new AreaTile(tile.X - 1, tile.Y - 1);
                        if (!adding.Contains(newTile) && !removing.Contains(newTile))
                        {
                            adding.Add(newTile);
                            if (adding2 != null) adding2.Add(newTile);
                            if (removing2 != null)
                            {
                                removing2.Remove(newTile);
                                added.Add(newTile);
                            }
                        }
                        break;
                }
                k = (k + d) % 8;
                if (k < 0) k += 8;
            }
            k = (k - d) % 8;
            if (k < 0) k += 8;

            HashSet<AreaTile> removing1 = new HashSet<AreaTile>(removing);
            removing1.UnionWith(adding);
            foreach (AreaTile t in added)
            {
                Add8adjTiles(0, t, removing2, removing1, null, null);
            }

            return added;
        }
        public void StretchedMazeGen(int baseSize, double mazeness, int stretchX, int stretchY, int stretchBase, bool square, int resolution, double rmBorder, double rmNoBorder, double noise)
        {
            List<AreaTile> passable = new List<AreaTile>();
            List<AreaTile> border = new List<AreaTile>();
            List<AreaTile>[] borders = new List<AreaTile>[stretchX * stretchY];

            for (int i = 0; i < stretchX; i++)
            {
                for (int j = 0; j < stretchY; j++)
                {
                    int x = i * stretchBase - (stretchX - 1) * stretchBase / 2;
                    int y = j * stretchBase - (stretchY - 1) * stretchBase / 2;
                    passable.Add(new AreaTile(x, y));
                    border.Add(new AreaTile(x + 1, y));
                    border.Add(new AreaTile(x - 1, y));
                    border.Add(new AreaTile(x, y + 1));
                    border.Add(new AreaTile(x, y - 1));

                    List<AreaTile> border2 = new List<AreaTile>();
                    borders[j * stretchX + i] = border2;
                    border2.Add(new AreaTile(x + 1, y));
                    border2.Add(new AreaTile(x - 1, y));
                    border2.Add(new AreaTile(x, y + 1));
                    border2.Add(new AreaTile(x, y - 1));
                }
            }

            int k = random.Next(4);
            for (int i = 0; i < baseSize; i++)
            {
                List<AreaTile> border2 = borders[i % (stretchX * stretchY)];
                if (border2.Count == 0)
                {
                    continue;
                }
                AreaTile tile = GetRandomBorder(border2, mazeness, true);
                bool isLast = square && tile.Equals(border2.Last());
                border.Remove(tile);
                border2.Remove(tile);
                passable.Add(tile);

                AreaTile newBorderTile;
                if (!isLast) k = random.Next(4);

                //int d = (random.Next(2) * 2) - 1;
                int d = 1;
                k = (k + d) % 4;
                if (k < 0) k += 4;
                for (int j = 0; j < 4; j++)
                {
                    switch (k)
                    {
                        case 0:
                            newBorderTile = new AreaTile(tile.X + 1, tile.Y);
                            if (!passable.Contains(newBorderTile) && !border.Contains(newBorderTile))
                            {
                                border.Add(newBorderTile);
                                border2.Add(newBorderTile);
                            }
                            break;
                        case 1:
                            newBorderTile = new AreaTile(tile.X, tile.Y + 1);
                            if (!passable.Contains(newBorderTile) && !border.Contains(newBorderTile))
                            {
                                border.Add(newBorderTile);
                                border2.Add(newBorderTile);
                            }
                            break;
                        case 2:
                            newBorderTile = new AreaTile(tile.X - 1, tile.Y);
                            if (!passable.Contains(newBorderTile) && !border.Contains(newBorderTile))
                            {
                                border.Add(newBorderTile);
                                border2.Add(newBorderTile);
                            }
                            break;
                        case 3:
                            newBorderTile = new AreaTile(tile.X, tile.Y - 1);
                            if (!passable.Contains(newBorderTile) && !border.Contains(newBorderTile))
                            {
                                border.Add(newBorderTile);
                                border2.Add(newBorderTile);
                            }
                            break;
                    }
                    k = (k + d) % 4;
                    if (k < 0) k += 4;
                }
                k = (k - d) % 4;
                if (k < 0) k += 4;
            }

            var passableSet = new HashSet<AreaTile>(passable);
            var borderSet = new HashSet<AreaTile>(border);

            if (rmBorder > 0) RemoveBorder(passableSet, borderSet, rmBorder, random);
            if (rmNoBorder > 0) RemoveNoBorder(passableSet, borderSet, rmNoBorder, random, false);

            _tiles = ListToMatrix(passableSet, borderSet, resolution, random, noise);
        }
        public List<AreaTile> MazeGen(int baseSize, double mazeness, bool square, int resolution, double rmBorder, double rmNoBorder, double noise)
        {
            List<AreaTile> passable = new List<AreaTile>();
            List<AreaTile> border = new List<AreaTile>();

            passable.Add(new AreaTile(0, 0));
            border.Add(new AreaTile(1, 0));
            border.Add(new AreaTile(-1, 0));
            border.Add(new AreaTile(0, 1));
            border.Add(new AreaTile(0, -1));

            int k = random.Next(4);
            for (int i = 0; i < baseSize; i++)
            {
                AreaTile tile = GetRandomBorder(border, mazeness, true);
                bool isLast = square && tile.Equals(border.Last());
                border.Remove(tile);
                passable.Add(tile);

                AreaTile newBorderTile;
                if (!isLast) k = random.Next(4);

                //int d = (random.Next(2) * 2) - 1;
                //technique pour rendre aléatoire l'ordre d'ajout des nouvelles bordures
                int d = 1;
                k = (k + d) % 4;
                if (k < 0) k += 4;
                for (int j = 0; j < 4; j++)
                {
                    switch (k)
                    {
                        case 0:
                            newBorderTile = new AreaTile(tile.X + 1, tile.Y);
                            if (!passable.Contains(newBorderTile) && !border.Contains(newBorderTile))
                            {
                                border.Add(newBorderTile);
                            }
                            break;
                        case 1:
                            newBorderTile = new AreaTile(tile.X, tile.Y + 1);
                            if (!passable.Contains(newBorderTile) && !border.Contains(newBorderTile))
                            {
                                border.Add(newBorderTile);
                            }
                            break;
                        case 2:
                            newBorderTile = new AreaTile(tile.X - 1, tile.Y);
                            if (!passable.Contains(newBorderTile) && !border.Contains(newBorderTile))
                            {
                                border.Add(newBorderTile);
                            }
                            break;
                        case 3:
                            newBorderTile = new AreaTile(tile.X, tile.Y - 1);
                            if (!passable.Contains(newBorderTile) && !border.Contains(newBorderTile))
                            {
                                border.Add(newBorderTile);
                            }
                            break;
                    }
                    k = (k + d) % 4;
                    if (k < 0) k += 4;
                }
                k = (k - d) % 4;
                if (k < 0) k += 4;
            }

            var passableSet = new HashSet<AreaTile>(passable);
            var borderSet = new HashSet<AreaTile>(border);

            if (rmBorder > 0) RemoveBorder(passableSet, borderSet, rmBorder, random);
            if (rmNoBorder > 0) RemoveNoBorder(passableSet, borderSet, rmNoBorder, random, false);

            _tiles = ListToMatrix(passableSet, borderSet, resolution, random, noise);
            return border;
        }
        public void LineGen(int deltaX, int deltaY, double noise, int minDeriv, int resolution, double proba, int thickness)
        {
            random = new Random();
            HashSet<AreaTile> passable = new HashSet<AreaTile>();
            AreaTile currentTile = new AreaTile(0, 0);
            passable.Add(currentTile);
            HashSet<AreaTile> border = new HashSet<AreaTile>();
            border.Add(new AreaTile(1, 0));
            border.Add(new AreaTile(-1, 0));
            border.Add(new AreaTile(0, 1));
            border.Add(new AreaTile(0, -1));

            AreaTile lastTile = currentTile;
            AreaTile nextTile;
            while (!passable.Contains(new AreaTile(deltaX, deltaY)))
            {
                int dist, dxtmp, dytmp, ddx, ddy, dx, dy, currentX, currentY, X, Y;
                ddx = 0;
                ddy = 0;
                do
                {
                    dxtmp = deltaX - currentTile.X;
                    dytmp = deltaY - currentTile.Y;
                    dist = Math.Abs(dxtmp) + Math.Abs(dytmp);

                    if (dist > (Math.Abs(deltaX) + Math.Abs(deltaY)) * 0.02) // 2% de la distance
                    {
                        ddx = (int)Math.Round((random.NextDouble() * 2 - 1) * (int)Math.Round(noise * (minDeriv + (random.NextDouble() * Math.Min(Math.Abs(dxtmp), Math.Abs(dytmp))))));
                        ddy = (int)Math.Round((random.NextDouble() * 2 - 1) * (int)Math.Round(noise * (minDeriv + (random.NextDouble() * Math.Min(Math.Abs(dxtmp), Math.Abs(dytmp))))));
                    }
                    else
                    {
                        ddx = 0;
                        ddy = 0;
                    }

                    dx = dxtmp + ddx;
                    dy = dytmp + ddy;

                    if (Math.Abs(dx) + Math.Abs(dy) == 0)
                    {
                        dx = dxtmp;
                        dy = dytmp;
                    }

                    currentX = currentTile.X;
                    currentY = currentTile.Y;
                    if (dy == 0 || (double)Math.Abs(dx) / (double)Math.Abs(dy) > (double)Math.Abs(deltaX) / (double)Math.Abs(deltaY))
                    {
                        X = Math.Sign(dx);
                        Y = 0;
                    }
                    else
                    {
                        X = 0;
                        Y = Math.Sign(dy);
                    }
                    nextTile = new AreaTile(currentX + X, currentY + Y);
                } while (nextTile.Equals(lastTile));

                border.Remove(nextTile);
                passable.Add(nextTile);
                lastTile = currentTile;
                currentTile = nextTile;

                AreaTile newBorderTile;
                for (int j = 0; j < 4; j++)
                {
                    switch (j)
                    {
                        case 0:
                            newBorderTile = new AreaTile(nextTile.X + 1, nextTile.Y);
                            if (!passable.Contains(newBorderTile) && !border.Contains(newBorderTile)) border.Add(newBorderTile);
                            break;
                        case 1:
                            newBorderTile = new AreaTile(nextTile.X, nextTile.Y + 1);
                            if (!passable.Contains(newBorderTile) && !border.Contains(newBorderTile)) border.Add(newBorderTile);
                            break;
                        case 2:
                            newBorderTile = new AreaTile(nextTile.X - 1, nextTile.Y);
                            if (!passable.Contains(newBorderTile) && !border.Contains(newBorderTile)) border.Add(newBorderTile);
                            break;
                        case 3:
                            newBorderTile = new AreaTile(nextTile.X, nextTile.Y - 1);
                            if (!passable.Contains(newBorderTile) && !border.Contains(newBorderTile)) border.Add(newBorderTile);
                            break;
                    }
                }

                for (int i = 0; i < thickness; i++)
                {
                    HashSet<AreaTile> newPassableTiles = new HashSet<AreaTile>();
                    foreach (AreaTile t in passable)
                    {
                        newPassableTiles.Add(new AreaTile(nextTile.X + 1, nextTile.Y));
                        newPassableTiles.Add(new AreaTile(nextTile.X, nextTile.Y + 1));
                        newPassableTiles.Add(new AreaTile(nextTile.X - 1, nextTile.Y));
                        newPassableTiles.Add(new AreaTile(nextTile.X, nextTile.Y - 1));
                    }

                    foreach (AreaTile t in newPassableTiles)
                    {
                        passable.Add(t);
                        if (border.Contains(t))
                        {
                            border.Remove(t);
                            newBorderTile = new AreaTile(t.X + 1, t.Y);
                            if (!passable.Contains(newBorderTile)) border.Add(newBorderTile);
                            newBorderTile = new AreaTile(t.X, t.Y + 1);
                            if (!passable.Contains(newBorderTile)) border.Add(newBorderTile);
                            newBorderTile = new AreaTile(t.X - 1, t.Y);
                            if (!passable.Contains(newBorderTile)) border.Add(newBorderTile);
                            newBorderTile = new AreaTile(t.X, t.Y - 1);
                            if (!passable.Contains(newBorderTile)) border.Add(newBorderTile);
                        }
                    }
                }
            }

            _tiles = ListToMatrix(passable, border, resolution, random, proba);
        }
 private bool ValidCenter(AreaTile tile, HashSet<AreaTile> border)
 {
     foreach (AreaTile tile2 in border)
     {
         if (Dist(tile, tile2, true) < 3) return false;
     }
     return true;
 }
Esempio n. 16
0
    public static Vector2 moveObject(GameObject obj, Vector2 moveTo)
    {
        //Area Tile processing
        AreaTile at = obj.GetComponent <AreaTile>();

        if (at)
        {
            AreaTile otherTile = null;
            foreach (AreaTile aTile in FindObjectsOfType <AreaTile>())
            {
                if ((Vector2)aTile.transform.position == moveTo)
                {
                    otherTile = aTile;
                    break;
                }
            }
            AreaTile.AreaType prevType = at.type;
            switch (at.type)
            {
            case AreaTile.AreaType.GROUND:
                at.type = AreaTile.AreaType.VOID;
                break;

            case AreaTile.AreaType.WALL:
            case AreaTile.AreaType.TRAP:
            case AreaTile.AreaType.GOAL:
                at.type = AreaTile.AreaType.GROUND;
                break;

            case AreaTile.AreaType.VOID:
                return(obj.transform.position);
            }
            at.GetComponent <SpriteRenderer>().color = instance.colorScheme.getColor(at.type);
            if (otherTile != null)
            {
                switch (otherTile.type)
                {
                case AreaTile.AreaType.GROUND:
                    otherTile.type = prevType;
                    break;

                case AreaTile.AreaType.WALL:
                case AreaTile.AreaType.TRAP:
                case AreaTile.AreaType.GOAL:
                    if (prevType == AreaTile.AreaType.GROUND)
                    {
                        //do nothing
                    }
                    else
                    {
                    }
                    return(obj.transform.position);

                case AreaTile.AreaType.VOID:
                    if (prevType == AreaTile.AreaType.GROUND)
                    {
                        otherTile.type = prevType;
                    }
                    break;
                }
                otherTile.GetComponent <SpriteRenderer>().color = instance.colorScheme.getColor(otherTile.type);
                return(obj.transform.position);
            }
            return(obj.transform.position);
        }
        //Regular game object processing
        if (!objectPositions.ContainsKey(obj))
        {
            registerObject(obj, obj.transform.position);
        }
        Vector2 oldPos = objectPositions[obj];

        if (grid[(int)moveTo.x, (int)moveTo.y] == null)
        {
            grid[(int)oldPos.x, (int)oldPos.y] = null;
            grid[(int)moveTo.x, (int)moveTo.y] = obj;
            objectPositions[obj] = moveTo;
            return(moveTo);
        }
        return(oldPos);
    }