/// <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"); } }
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); } } } }
private void TracePath(AreaTile areaTile) { while (areaTile != null) { parent.CreateAreaObject(null, areaTile.position, UnityEngine.Quaternion.identity); areaTile = areaTile.Parent; } }
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; }
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); }