// Använder nodens index och söker de fyra positionerna runt sig (n, s, w, e) och lägger dem i en lista. Den gör bara detta om den är inom banans scope. private static List<Node> GetNeighbours(Node node) { List<Node> neighbours = new List<Node>(); int x = node.X; int y = node.Y; if (x != 14) neighbours.Add(Map.nodeArray[x + 1, y]); if (y != 24) neighbours.Add(Map.nodeArray[x, y + 1]); if (x != 0) neighbours.Add(Map.nodeArray[x - 1, y]); if (y != 0) neighbours.Add(Map.nodeArray[x, y - 1]); return neighbours; }
//En bredden först sökning som öppnar alla noder som läggs i neighbour och om de inte redan är besökta och går att passeera läggs den i en separat lista. //Om den träffar målnoden går den tillbaka längs vägen genom att kolla på nodens förälder och hela tiden pusha den noden till stacken. public static MyStack FindPath(Node startNode, Node goalNode) { ResetNodes(); Node currentNode = startNode; List<Node> candidates = new List<Node>(); candidates.Add(currentNode); MyStack pathStack = new MyStack(); for (int a = 0; a < 1000; a++) { if (currentNode == goalNode) { List<Node> path = new List<Node>(); for (int i = 0; i < 500; i++) { if (currentNode == startNode) break; pathStack.Push(currentNode); currentNode = currentNode.parent; } return pathStack; } List<Node> neighbours = GetNeighbours(currentNode); for (int i = 0; i < neighbours.Count(); i++) { if (!neighbours[i].visited && neighbours[i].passable) { candidates.Add(neighbours[i]); neighbours[i].parent = currentNode; } } currentNode.visited = true; candidates.Remove(currentNode); if(candidates.Count > 0) currentNode = candidates[0]; } return null; }
//Initierar en bredden först sökning som returnerar en stack. Hittar en riktning från noden i stacken. Normaliserar värdet sedan värdet och sätyter det till spökets riktning. public void FindPath() { if (target == null) return; Node n = getNode(); Node m = target.getNode(); pathStack = pathFinder.FindPath(n, target.getNode()); //pathStack = pathFinder.FindPath(n, Map.nodeArray[2, 14]); if (pathStack == null || pathStack.Count() == 0) return; targetNode = (Node)pathStack.Pop(); targetDirection = new Vector2(targetNode.X, targetNode.Y) - new Vector2(n.X, n.Y); if (targetDirection != Vector2.Zero) targetDirection.Normalize(); else targetDirection = Vector2.Zero; }
//Använder en counter för att gå ett antal pixlar i spökets givna riktning för att sedan byta nod. void MoveToTargetNode() { Node n = getNode(); if (counter == 20) { if(pathStack == null || pathStack.Count() == 0) // Om vi inte har någon stack skapar vi en ny med en ny väg till målet. FindPath(); rec.X = targetNode.Y * 20; rec.Y = targetNode.X * 20; if (pathStack != null && pathStack.Count() != 0) targetNode = (Node)pathStack.Pop(); targetDirection = new Vector2(targetNode.X, targetNode.Y) - new Vector2(n.X, n.Y); if (targetDirection != Vector2.Zero) targetDirection.Normalize(); counter = 0; } else { rec.X += (int)targetDirection.Y; rec.Y += (int)targetDirection.X; counter++; } }
// Reads the textfile and creates a tile or gameobject public void CreateMap(List<String> list) { ReadString(list); int Cost = 1; nodeArray = new Node[list.Count, list[1].Length]; for (int i = 0; i < list.Count; i++) { for (int j = 0; j < list[i].Length; j++) { if (list[i][j] == 'x') { nodeArray[i, j] = new Node(false, Cost, i, j); wallList.Add(new Wall_Tile(tex2, new Vector2((j * 20), (i * 20)))); } if (list[i][j] == 'f') { nodeArray[i, j] = new Node(true, Cost, i, j); floorList.Add(new Food_Tile(tex3, new Vector2((j * 20), (i * 20)))); } if (list[i][j] == 's') { nodeArray[i, j] = new Node(true, Cost, i, j); floorList.Add(new Food_Tile(tex2, new Vector2((j * 20), (i * 20)))); specialWall.Add(new Food_Tile(tex2, new Vector2((j * 20), (i * 20)))); } if (list[i][j] == 'b') { nodeArray[i, j] = new Node(true, Cost, i, j); floorList.Add(new Bonus_Tile(tex1, new Vector2((j * 20), (i * 20)))); bonusList.Add(new Bonus_Tile(tex1, new Vector2((j * 20), (i * 20)))); } if (list[i][j] == 'u') { nodeArray[i, j] = new Node(true, Cost, i, j); floorList.Add(new Uber_Tile(tex1, new Vector2((j * 20), (i * 20)))); uberList.Add(new Uber_Tile(tex1, new Vector2((j * 20), (i * 20)))); } if (list[i][j] == 'g') { nodeArray[i, j] = new Node(true, Cost, i, j); ghost = new Ghost(tex1, new Vector2((j * 20), (i * 20))); ghostList.Add(ghost); objectList.Add(ghost); } if (list[i][j] == 'p') { nodeArray[i, j] = new Node(true, Cost, i, j); pacman = new Pacman(tex1, new Vector2((j * 20), (i * 20))); objectList.Add(pacman); } } } Ghost g = (Ghost)ghostList[0]; g.SetTarget(pacman); g.FindPath(); maxScore = floorList.Count(); }