public Vector3[] findPathTo(Vector3 start, Vector3 destination) { int counter = 0; openList.Clear(); closedList.Clear(); AStarObject.setDestination(destination); AStarObject startElement = new AStarObject(null, start); openList.Add(startElement); do { counter++; AStarObject currentSquare = findLowestF(); openList.Remove(currentSquare); closedList.Add(currentSquare); if (currentSquare.getPosition() == AStarObject.getDestination()) { break; } List <AStarObject> adjacentSquares = findAdjacents(currentSquare); foreach (AStarObject nearAO in adjacentSquares) { if (containsAstar(nearAO, closedList)) { continue; } if (!containsAstar(nearAO, openList)) { openList.Add(nearAO); } else { //update G } } } while(openList.Count != 0); getShortestPath(); Vector3[] waypoints = shortest.ToArray(); System.Array.Reverse(waypoints); return(waypoints); }
bool containsAstar(AStarObject element, List <AStarObject> list) { foreach (AStarObject ao in list) { if (ao.getPosition() == element.getPosition()) { return(true); } } return(false); }
AStarObject findLowestF() { AStarObject lowest = openList[0]; foreach (AStarObject ao in openList) { if (lowest.greaterFThan(ao)) { lowest = ao; } } return(lowest); }
public AStarObject(AStarObject parent, Vector3 position) { this.position = position; if (parent != null) { this.parent = parent; G = parent.G + 1; } else { G = 0; } H = vectorLength(position - destination); F = G + H; }
//Liste aller benachbarten PathElements List <AStarObject> findAdjacents(AStarObject ao) { List <AStarObject> adjacents = new List <AStarObject>(); //Check if curretn Position is PathElement SimplePathElement currentPositionElement = null; level.GetAllElements().TryGetValue(ao.getPosition(), out currentPositionElement); Vector3[] directions = { Vector3.forward, Vector3.back, Vector3.left, Vector3.right }; if (currentPositionElement != null) { foreach (Vector3 direction in directions) { if (currentPositionElement.getBarrierByDirection(direction) == Barrier.Walkable) { AStarObject newAO = getAdjacent(ao, ao.getPosition(), direction); if (newAO != null) { adjacents.Add(newAO); } } } } else { foreach (Vector3 direction in directions) { AStarObject newAO = getAdjacent(ao, ao.getPosition(), direction); if (newAO != null) { adjacents.Add(newAO); } } } return(adjacents); }
void getShortestPath() { shortest.Clear(); int G; AStarObject last = closedList [closedList.Count - 1]; G = last.getG(); if (last.getPosition() == AStarObject.getDestination()) { while (G != 0 && last.getParent() != null) { shortest.Add(last.getPosition()); last = last.getParent(); G = last.getG(); } } }
public bool greaterFThan(AStarObject other) { return(F > other.getF()); }
public void setParent(AStarObject parent) { this.parent = parent; G = parent.G + 1; }
AStarObject getAdjacent(AStarObject ao, Vector3 position, Vector3 direction) { Vector3 walkPosition = position + direction; Vector3 floorCubePosition = walkPosition + new Vector3(0, -1, 0); SimplePathElement walkElement = null; SimplePathElement floorElement = null; level.GetAllElements().TryGetValue(walkPosition, out walkElement); level.GetAllElements().TryGetValue(floorCubePosition, out floorElement); //Normal Walk if (walkElement != null) { if (walkElement.bottomBarrier == Barrier.Walkable && walkElement.getBarrierByDirection(-direction) == Barrier.Walkable) { //Adjazenz Block existiert return(new AStarObject(ao, position + direction)); } } else { if (floorElement != null) { if (floorElement.topBarrier == Barrier.Walkable) { //Adjazenz Block existiert return(new AStarObject(ao, position + direction)); } } } //Stairs Up if (walkElement != null) { if (walkElement.getBarrierByDirection(-direction) == Barrier.Stairs) { SimplePathElement aboveStairEntry = null; Vector3 aboveStairEntryPosition = position + Vector3.up; level.GetAllElements().TryGetValue(aboveStairEntryPosition, out aboveStairEntry); if (aboveStairEntry == null) { //checke Treppen Ende return(getAdjacent(ao, position + direction + Vector3.up, direction)); } } } //Stairs Down if (walkElement == null) { if (floorElement != null) { if (floorElement.topBarrier == Barrier.Stairs) { if (floorElement.getBarrierByDirection(direction) == Barrier.Stairs) { SimplePathElement aboveStairExit = null; Vector3 aboveStairExitPosition = walkPosition + direction; level.GetAllElements().TryGetValue(aboveStairExitPosition, out aboveStairExit); if (aboveStairExit == null) { //checke Treppen Start return(getAdjacent(ao, position + direction + Vector3.down, direction)); } } } } } return(null); }
public void LoadLevel(Vector2 lp) { print(levelPos); foreach (Transform child in wallParent) { Destroy(child.gameObject); } foreach (Transform child in groundParent) { Destroy(child.gameObject); } foreach (Transform child in holeParent) { Destroy(child.gameObject); } foreach (Transform child in stoolParent) { Destroy(child.gameObject); } doors = new List <GameObject>(); foreach (Transform child in doorParent) { Destroy(child.gameObject); } Random.State oldState = Random.state; Random.InitState(Mathf.FloorToInt(hash21(lp) * 1000000.0f)); bool[,] tiles = new bool[levelRadiusW * 2, levelRadiusH * 2]; bool[,] stools = new bool[levelRadiusW * 2, levelRadiusH * 2]; int roomRule = Random.Range(0, 24); //Corners Instantiate(wallCorner, new Vector3(-levelRadiusW, -levelRadiusH + 1), Quaternion.Euler(0.0f, 0.0f, 90.0f), wallParent); Instantiate(wallCorner, new Vector3(levelRadiusW, 1 - levelRadiusH), Quaternion.Euler(0.0f, 0.0f, 180.0f), wallParent); Instantiate(wallCorner, new Vector3(levelRadiusW, 1 + levelRadiusH), Quaternion.Euler(0.0f, 0.0f, -90.0f), wallParent); Instantiate(wallCorner, new Vector3(-levelRadiusW, 1 + levelRadiusH), Quaternion.Euler(0.0f, 0.0f, 0.0f), wallParent); //Fill for (int x = 0; x < levelRadiusW * 2; x++) { //Bottom wall Instantiate(wallStraight, new Vector3(1 + x - levelRadiusW, -levelRadiusH), Quaternion.Euler(0.0f, 0.0f, 180.0f), wallParent); for (int y = 0; y < levelRadiusH * 2; y++) { //Setting tile existence tiles[x, y] = tileRules[roomRule, y, x]; stools[x, y] = stoolRules[roomRule, y, x]; Instantiate( tiles[x, y] ? groundTile : hole, new Vector3(x - levelRadiusW, levelRadiusH + 1 - y), Quaternion.identity, tiles[x, y] ? groundParent : holeParent ); //Stools if (tiles[x, y] && stools[x, y]) { Instantiate( stool, new Vector3(x - levelRadiusW, levelRadiusH + 1 - y), Quaternion.identity, stoolParent ); } } //Top Wall Instantiate(wallStraight, new Vector3(x - levelRadiusW, 2 + levelRadiusH), Quaternion.Euler(0.0f, 0.0f, 0.0f), wallParent); } for (int y = 0; y < levelRadiusH * 2; y++) { //Left wall Instantiate(wallStraight, new Vector3(-1 - levelRadiusW, levelRadiusH - y), Quaternion.Euler(0.0f, 0.0f, 90.0f), wallParent); //Right Wall Instantiate(wallStraight, new Vector3(1 + levelRadiusW, levelRadiusH + 1 - y), Quaternion.Euler(0.0f, 0.0f, -90.0f), wallParent); } foreach (Transform child in groundParent) { child.gameObject.GetComponent <SpriteRenderer>().sortingOrder = -5 - levelRadiusH - (int)child.position.y; } if (hash21(levelPos + new Vector2(0.5f, 0.0f)) > 0.2f) { doors.Add(Instantiate(door, new Vector3(1 + levelRadiusW, 1.5f), Quaternion.Euler(0.0f, 0.0f, -90.0f), doorParent)); doors[doors.Count - 1].GetComponent <doorControl>().setDirection(new Vector2(1.0f, 0.0f)); } if (hash21(levelPos + new Vector2(-0.5f, 0.0f)) > 0.2f) { doors.Add(Instantiate(door, new Vector3(-1 - levelRadiusW, 0.5f), Quaternion.Euler(0.0f, 0.0f, 90.0f), doorParent)); doors[doors.Count - 1].GetComponent <doorControl>().setDirection(new Vector2(-1.0f, 0.0f)); } if (hash21(levelPos + new Vector2(0.0f, 0.5f)) > 0.2f) { doors.Add(Instantiate(door, new Vector3(-0.5f, 2 + levelRadiusH), Quaternion.Euler(0.0f, 0.0f, 0.0f), doorParent)); doors[doors.Count - 1].GetComponent <doorControl>().setDirection(new Vector2(0.0f, 1.0f)); } if (hash21(levelPos + new Vector2(0.0f, -0.5f)) > 0.2f) { doors.Add(Instantiate(door, new Vector3(0.5f, -levelRadiusH), Quaternion.Euler(0.0f, 0.0f, 180.0f), doorParent)); doors[doors.Count - 1].GetComponent <doorControl>().setDirection(new Vector2(0.0f, -1.0f)); } if (!vistedRooms.Contains(lp)) { vistedRooms.Add(lp); int enemyNum = 1; int enemyChance = 0; List <Transform> possiblePositions = new List <Transform>((Transform[])groundParent.GetComponentsInChildren <Transform>().Clone()); foreach (Transform t1 in stoolParent.GetComponentsInChildren <Transform>()) { foreach (Transform t2 in possiblePositions) { if ((t1.position - t2.position).sqrMagnitude < 0.5f) { possiblePositions.Remove(t2); break; } } } while (enemyChance < 1) { int posInd = Random.Range(0, possiblePositions.Count); Vector3 prefabPos = possiblePositions[posInd].position + new Vector3(0.5f, -0.5f, 0.0f); possiblePositions.RemoveAt(posInd); GameObject temp = Instantiate(enemies[Random.Range(0, enemies.Count)], prefabPos, Quaternion.identity, enemyParent); if (temp.GetComponent <EnemyAI>() != null) { temp.GetComponent <EnemyAI>().target = player.transform; temp.GetComponent <EnemyAI>().AstarObj = AStarObject.GetComponent <AstarPath>(); } enemyChance = Random.Range(0, ++enemyNum); } } Random.state = oldState; timeSinceLevelLoad = 0.0f; }