// permet d'analyser la map, pour ensuite exécuter // l'algorithme A-Star et trouver le chemin public List <NatNode> FindPath(int startX, int startY, int endX, int endY) { // Analyser la map //nodeMap = new Node[grid.GetLargueur(), grid.GetHauteur()]; NatNode start = grid.GetGridObject(startX, startY); NatNode goal = grid.GetGridObject(endX, endY); for (int x = 0; x < grid.GetLargueur(); x++) { for (int y = 0; y < grid.GetHauteur(); y++) { NatNode node = grid.GetGridObject(x, y); node.Gcost = int.MaxValue; node.cameFromNode = null; node.CalculerFcost(); } } // Executer l'algorithme A-Star. List <NatNode> nodePath = ExecuteAStar(start, goal); //nodePath.Reverse(); return(nodePath); }
public void SetGridObject(int x, int y, NatNode value) { if (x >= 0 && y > 0 && x < largeur && y < hauteur) { listNode[x, y] = value; } }
public void SetGridObject(Vector3 worldPosition, NatNode value) { int x, y; GetXY(worldPosition, out x, out y); SetGridObject(x, y, value); }
// Permet de calculer la distance entre deux node pour calculé // sont coût de déplacement d'une node à une autre. private int CalculerLaDistanceEntreNode(NatNode nodeA, NatNode nodeB) { int DistanceX = Mathf.Abs(nodeA.x - nodeB.x); int DistanceY = Mathf.Abs(nodeA.y - nodeB.y); int restant = Mathf.Abs(DistanceX - DistanceY); return(COUT_MOUVEMENT_DIAGONAL * Mathf.Min(DistanceX, DistanceY) + COUT_MOUVEMENT_DROIT * restant); }
// Permet d'aller cherhcher toute les nodes // voisines à celle sur laquel on est et // vérifier si on peut y accéder private List <NatNode> GetNeighnourNodes(NatNode node) { List <NatNode> neighbours = new List <NatNode>(); // Vérification de la gauche (Ouest) if (node.x - 1 >= 0) { // Ouest neighbours.Add(grid.GetGridObject(node.x - 1, node.y)); if (node.y - 1 >= 0) { // Sud-Ouest neighbours.Add(grid.GetGridObject(node.x - 1, node.y - 1)); } if (node.y + 1 < grid.GetHauteur()) { // Nord-Ouest neighbours.Add(grid.GetGridObject(node.x - 1, node.y + 1)); } } // Vérification de la droite (Est) if (node.x + 1 < grid.GetLargueur()) { // Est neighbours.Add(grid.GetGridObject(node.x + 1, node.y)); //Sud-Est if (node.y - 1 >= 0) { neighbours.Add(grid.GetGridObject(node.x + 1, node.y - 1)); } // Nord-Est if (node.y + 1 < grid.GetHauteur()) { neighbours.Add(grid.GetGridObject(node.x + 1, node.y + 1)); } } // Vérification du bas (Sud) if (node.y - 1 >= 0) { // Sud neighbours.Add(grid.GetGridObject(node.x, node.y - 1)); } // Vérification du haut (Nord) if (node.y + 1 < grid.GetHauteur()) { // Nord neighbours.Add(grid.GetGridObject(node.x, node.y + 1)); } return(neighbours); }
private NatNode CalculerLePlusBasF(List <NatNode> node) { NatNode fPlusBas = node[0]; for (int i = 0; i < node.Count; i++) { if (node[i].Fcost < fPlusBas.Fcost) { fPlusBas = node[i]; } } return(fPlusBas); }
// Une fois que les nodes sont populés, il // faut lire chaque node précédente et // et construire le chemin private List <NatNode> BuilPath(NatNode node) { List <NatNode> path = new List <NatNode>() { node }; while (node.cameFromNode != null) { path.Add(node.cameFromNode); node = node.cameFromNode; } path.Reverse(); return(path); }
public NatGrid(int n_largeur, int n_hauteur, float n_dimCell, Vector3 n_origine) { largeur = n_largeur; hauteur = n_hauteur; dimCell = n_dimCell; origine = n_origine; listNode = new NatNode[largeur, hauteur]; bool iscollide; colliderList = GameObject.FindGameObjectsWithTag("Obstacle"); for (int x1 = 0; x1 < listNode.GetLength(0); x1++) { for (int y2 = 0; y2 < listNode.GetLength(1); y2++) { listNode[x1, y2] = new NatNode(x1, y2); for (int i = 0; i < colliderList.Length; i++) { GetXY(colliderList[i].transform.position, out int x, out int y); if (x1 == x & y2 == y) { listNode[x, y].obstacle = true; } } } } for (int x = 0; x < largeur; x++) { for (int y = 0; y < hauteur; y++) { Debug.DrawLine(Position(x, y), Position(x + 1, y), Color.white, 100f); Debug.DrawLine(Position(x, y), Position(x, y + 1), Color.white, 100f); } } Debug.DrawLine(Position(0, hauteur), Position(largeur, hauteur), Color.white, 100f); Debug.DrawLine(Position(largeur, 0), Position(largeur, hauteur), Color.white, 100f); }
// Permet de savoir sur quelle node le joueur // est et de connaitre les informations nécéssaires // sur la tuile ou le joueur se tient /* * private Node FindNode(GameObject obj) * { * Collider2D[] collindingObjects = Physics2D.OverlapCircleAll(obj.transform.position, 0.2f); * * foreach (Collider2D collidingObject in collindingObjects) * { * if (collidingObject.gameObject.GetComponent<Node>() != null) * { * // Le joueur est sur cette node * Node tile = collidingObject.gameObject.GetComponent<Node>(); * * // Permet de trouver la node qui contient la tuile * for (int y = 0; y < grid.GetHauteur(); y++) * { * for (int x = 0; x < grid.GetLargueur(); x++) * { * Node node = nodeMap[x, y]; * * if (node.cameFromNode == tile) * { * return node; * } * } * } * } * } * return null; * } */ // Permet d'exécuter l'algorithme principale, // qui sert à trouver le chemin le plus cours // pour attendre le point visé private List <NatNode> ExecuteAStar(NatNode start, NatNode goal) { // Cette list sert à évaluer le potentiel de chaque nodes // pour faire le meilleur chemin et qui devrait être // visitée. On commence toujours à l'origine. List <NatNode> openList = new List <NatNode>() { start }; // Cette liste permet de se souvenir des nodes visitées List <NatNode> closedList = new List <NatNode>(); // Permet d'initialiser la node initiale start.Gcost = 0; start.Hcost = CalculerLaDistanceEntreNode(start, goal); start.CalculerFcost(); // l'algorithme principale while (openList.Count > 0) { // On regarde au début la node qui à le // coût estimé le plus bas pour rejoindre // l'objectif NatNode current = CalculerLePlusBasF(openList); // On regarde si l'objectif est atteint if (current == goal) { return(BuilPath(goal)); } // On s'assure que la node visité ne soit // pas visité de nouveau openList.Remove(current); closedList.Add(current); // On éxécute l'algorithme dans la node voisine //List<Node> neighbours = GetNeighnourNodes(current); foreach (NatNode neighbour in GetNeighnourNodes(current)) { if (closedList.Contains(neighbour)) { // Si la node voisine à été visité, // on l'ignore continue; } if (neighbour.obstacle == true) { closedList.Add(neighbour); continue; } // On calcule une nouvelle valeur pour g et on vérifie // si elle est meilleur que la précédente. int candidateG = current.Gcost + CalculerLaDistanceEntreNode(current, neighbour); //int candidateG = current.Gcost + 1; if (candidateG < neighbour.Gcost) { // Sinon, cela veux dire que l'on a trouvé un meilleur chemin // On initialise les nouvelles valeurs neighbour.Gcost = candidateG; neighbour.Hcost = CalculerLaDistanceEntreNode(current, goal); neighbour.cameFromNode = current; neighbour.CalculerFcost(); if (!openList.Contains(neighbour)) { // Si la node n'a pas été visité, // on peut la considéré comme valide et // la rajouté dans la liste openList.Add(neighbour); } } } } //Il n'y a pas de chemin return(null); }