Pracuję nad tą metodą sztucznej inteligencji przez jakiś czas. Zasadniczo ma on int
dla każdego kierunku, w którym mógłby iść przeciwnik, gdyby ściana blokowała mu drogę do gracza. To nie działa w większości przypadków. Czasami wróg przejdzie przez szczeliny, przez które nie może się zmieścić. Innym razem utknie na ścianach, które mają w sobie oczywiste luki. Dołączę mój kod, ale jeśli wygląda na zbyt nieefektywny lub po prostu nie sposób go rozwiązać, nie jestem przeciwny zmianie podejścia. Chciałbym tylko wiedzieć, jak te rzeczy są wykonywane normalnie, tak, że mogę wdrożyć je w lepszy (i działający!) Sposób.Oprogramowanie do gier ai: skalowanie ścian, aby znaleźć gracza?
Mój kod:
public void update(ArrayList<Wall> walls, Player p){
findPlayer(p.getX(), p.getY());
boolean isCollision = false;
System.out.println(isCollision);
//if movement straight towards the player is blocked, move along the walls
for(Wall w : walls){
if(Helper.isBoundingBoxCollision((int)(x + vectorToPlayer.getDX() * SPEED), (int)(y + vectorToPlayer.getDY() * SPEED), width, height, w.getX(), w.getY(), w.width, w.height)){
isCollision = true;
if(Math.abs(vectorToPlayer.getDX()) > Math.abs(vectorToPlayer.getDY())){
if(vectorToPlayer.getDX() > 0)
WALL_COLLISION = 3;
else
WALL_COLLISION = 1;
}
else if(Math.abs(vectorToPlayer.getDX()) < Math.abs(vectorToPlayer.getDY())){
if(vectorToPlayer.getDY() > 0)
WALL_COLLISION = 0;
else
WALL_COLLISION = 2;
}
}
}
//System.out.println(isCollision);
//set the direction to the straight on vector, to be reset if there is a collision on this path
direction = vectorToPlayer;
if(isCollision){
//reset the variable, don't mind that what this is named is completely opposite = PIMPIN'
isCollision = false;
//scale dem walls son, and see when the path is clear
for(Wall w : walls){
if(WALL_COLLISION == 0 && !Helper.isBoundingBoxCollision(x + SPEED, y, width, height, w.getX(), w.getY(), w.width, w.height)){
WALL_COLLISION = 3;
isCollision = true;
}
else if(WALL_COLLISION == 1 && !Helper.isBoundingBoxCollision(x, y + SPEED, width, height, w.getX(), w.getY(), w.width, w.height)){
WALL_COLLISION--;
isCollision = true;
}
else if(WALL_COLLISION == 2 && !Helper.isBoundingBoxCollision(x - SPEED, y, width, height, w.getX(), w.getY(), w.width, w.height)){
WALL_COLLISION--;
isCollision = true;
}
else if(WALL_COLLISION == 3 && !Helper.isBoundingBoxCollision(x, y - SPEED, width, height, w.getX(), w.getY(), w.width, w.height)){
WALL_COLLISION--;
isCollision = true;
}
}
//if there is NOT a wall on the designated side, set the vector accoridingly
if(isCollision){
if(WALL_COLLISION == 0)
direction = new NVector(0, 1);
else if(WALL_COLLISION == 1)
direction = new NVector(1, 0);
else if(WALL_COLLISION == 2)
direction = new NVector(0, -1);
else if(WALL_COLLISION == 3)
direction = new NVector(-1, 0);
}
}
x += Math.round(direction.getDX()*SPEED);
y += Math.round(direction.getDY()*SPEED);
}
Jak mówi Eric B, sterowanie z wykrywaniem kolizji nie gwarantuje dotarcia do miejsca docelowego. Problem z przejściem do algorytmu odnajdywania ścieżek, zgodnie z sugestią, będzie mniejszy w implementacji (algorytm "A *" jest udokumentowany w wielu miejscach), ale w tworzeniu dyskretnego świata, aby taki algorytm działał. Z twoich połączeń isBoundingBoxCollision() Podejrzewam, że próbujesz wykorzystać silnik, by znaleźć ściany. Wiele gier zwiększa geometrię poziomu za pomocą siatki ruchu, która jest łatwa do wyszukiwania w systemie ruchu w celu uniknięcia złożoności parsowania geometrii. – Godeke
OK, dziękuję za wyjaśnienia. – ceptno