# Einem A*-Pfad folgen



## Eichelhäer (28. Feb 2017)

Hallo,

mal wieder geht's um den A* nach sehr langer Arbeit daran, habe ich ihn jetzt endlich fertiggestellt.

Leider hat sich wieder ein neues Problem aufgetan.
Ich möchte nun, dass sich Einheiten ( mir reicht auch schon mal eine einzige ) als eine Art Figur, entlang des ermittelten Pfades bewegen.

Das ist allerdings alles nicht so einfach wie ich dachte. Zwar möchte ich schon wissen wie das funktioniert, allerdings tauchen mehrere Probleme auf.

1. Wie genau muss das Spielfeld aufgebaut sein, um Einheiten überhaupt wie gewohnt mit der üblichen Formel zu bewegen?
2. Mein A* verwendet Nachbarn, die genau 1x1 sind. Wie verhindert man dann Performanceprobleme bei größeren Spielfeldern?
3. (Analog zu 2 ) Gibt es noch andere Ansätze die zum Erfolg führen?

Nun nochmal etwas konkreteres:

Ich habe meinen Pfad in einer Liste, der via Mausklick auf das Spielfeld generiert und gezeichnet wird.

Das heißt ich kann auf jedes Element der Pfadliste zugreifen.
Natürlich weiß ich, dass ich nun meiner Einheit einfach nur die Position von den Elementen aus dem Pfad zuweisen müsste, allerdings klappt das nicht so ganz.
Denn, nachdem die Einheit das Ende des ersten Pfadelements der Liste erreicht hat, stürzt das gesamte Programm ab, ohne Fehlermeldung in der Konsole, aber mit Fehlermeldung von Windows.
Normalerweise lernt man ja aus Fehlern, aber wenn man nicht weiß, was genau der Fehler ist, wird es schwierig.

Also nochmal zusammengefasst:

In einer Methode move() soll eine Einheit entlang des ermittelten Pfades grafisch bis zum Ziel bewegt werden. Wie erreicht man das?

Hier mal meine fehlerhafte move()-Methode:

```
public void move(){
       
        if(Mouse.right){
            int startx = x / size;
            int starty = y / size;
            int endx = (Mouse.mousex-(Mouse.mousex%size))/size;
            int endy = (Mouse.mousey-(Mouse.mousey%size))/size;
           
            path = findPath(startx,starty,endx,endy);
        }
       
       
        if(path!=null){
            if(path.size() > 0){
                Node node = path.get(path.size()-1);
                x = node.i*size;
                y = node.j*size;
               
            }
        }
    }
```

Wie ordnet man die Positionen des Pfades besser den Positionen der Einheit zu und warum stürtzt das gesamte Programm ab?

Gruß Eichelhäer


----------



## VfL_Freak (28. Feb 2017)

Moin,


Eichelhäer hat gesagt.:


> warum stürtzt das gesamte Programm ab?


was heißt das ??
http://www.java-forum.org/forum-faq-beitraege/7407-man-fragen-richtig-stellt.html

Sind denn überhaupt x, y, path, size in der Methode "move" bekannt ??

Gruß Klaus


----------



## Eichelhäer (28. Feb 2017)

X,Y,path und size sind global deklarierte und initialisierte Variablen dieser Klasse, also ich kann in jeder Methode der Klasse darauf zugreifen.


----------



## VfL_Freak (28. Feb 2017)

Eichelhäer hat gesagt.:


> X,Y,path und size sind global deklarierte und initialisierte Variablen dieser Klasse, also ich kann in jeder Methode der Klasse darauf zugreifen.


ok, konnten wir ja nicht wissen +

Und was stürzt nun wo (in welcher Zeile) ab?
Poste mal den gesamten Stacktrace (und den entspechenden Codeteil) !

Gruß Klaus


----------



## Eichelhäer (28. Feb 2017)

Das ist ja das Problem. Es kommt keine Fehlermeldung in Eclipse auch nicht beim Debugging, sondern WINDOWS beendet die JVM.

Das ist der entsprechende Codeteil. Erst wenn ich versuche den x-bzw y-Werten die Pfadkoordinaten zuzuweisen stürzt alles ab. Ohne das läuft alles prima.


----------



## Eichelhäer (28. Feb 2017)

Wenn Sie mir wirklich helfen wollen, werde ich ihnen den Code (3 Dateien) persönlich senden, ABER nicht hier posten. Geben Sie mir hierfür eine E-Mail Adresse oder Skype Namen.


----------



## VfL_Freak (28. Feb 2017)

Moin,


Eichelhäer hat gesagt.:


> werde ich ihnen den Code (3 Dateien) persönlich senden, ABER nicht hier posten


ok, aber so funktioniert dies Forum nicht!!

Mal ganz davon abgesehen, dass die meisten User hier in ihrer Freizeit oder neben der Arbeit aktiv sind ...
_* Es sollen ALLE Leser etwas davon haben !!*_

Im Notfall kannst es ja noch hier:
http://www.java-forum.org/forum/private-stellangebote-und-stellensuche-von-usern.97/
versuchen !!

Gruß Klaus


----------



## mrBrown (28. Feb 2017)

Als was sind x und y denn deklariert?
Benutzt du irgendein Framework?
Welche Fehlermeldung kommt von Windows?


----------



## Eichelhäer (28. Feb 2017)

Hallo nochmal,
ich weiß jetzt woran es liegt.
Hier mal die überarbeitete move()-Methode:

```
path = findPath(0,0,14,14);
       
        
  endx = (Mouse.mousex-(Mouse.mousex%size))/size;
  endy = (Mouse.mousey-(Mouse.mousey%size))/size;

        if(path!=null){
            if(path.size() > 0){
                Collections.reverse(path);
                Node node = path.get(k);
                if(node.j*size > y)y++;
                if(node.j*size < y)y--;
                if(node.i*size > x)x++;
                if(node.i*size < x)x--;
                if(y == node.j*size && x == node.i*size)k++;
                if(k == path.size())k=path.size()-1;
                System.out.println(k);
            }
           
        }
```

Das läuft optimal. Die Einheit folgt dem Pfad wie gewünscht.
Das Problem liegt bei den Einheitskoordinaten.
Ich möchte nämlich per Mausklick bestimmen können, wo sich die Einheit hinbewegen soll.
Nun hat das Spielfeld, das als 2-dimensionales Array definiert ist, 15 Spalten und 15 Zeilen.
Der path möchte nur Kachelkoordinaten, während die Koordinaten der Einheit absolut sind.
Ich möchte sowas in der Art machen, dass ich dem path die Koordinaten der Einheit gebe, sodass sich die Länge des Pfades verkürzt, sobald ich das jeweils nächste Element aus path passiere, um ausgehend vom gerade passierten Pfadelement einen neuen Pfad berechnen zu können, eben wie man es aus diversen Spielen kennt.
Dazu muss ich für den path die Koordinaten der Einheit zur Laufzeit umrechnen in Kachelkoordinaten, sonst bekomme ich eine OutOfBoundsException, da das Spielfeld nur Werte zwischen 0 und 15 annehmen kann.
Wie macht man das?

Gruß Eichelhäer


----------



## VfL_Freak (28. Feb 2017)

Moin,


Eichelhäer hat gesagt.:


> Wie macht man das?


Keine Ahnung 

Aber was mir in Deinem Text auffällt:


Eichelhäer hat gesagt.:


> 2-dimensionales Array definiert ist, 15 Spalten und 15 Zeilen





Eichelhäer hat gesagt.:


> bekomme ich eine OutOfBoundsException, da das Spielfeld nur Werte zwischen 0 und 15 annehmen kann


bei jeweils 15 Spalten und Zeilen darf das Spieldfeld aber nur Werte zwischen 0 und _*14*_ (!!) annehmen, daher vermutlich die OoB-Exception ...

Gruß Klaus


----------



## Eichelhäer (28. Feb 2017)

Ja das ist natürlich korrekt, aber selbst wenn das Array 15 Werte annehmen könnte würde es nicht gehen, da die Kacheln auf meinem Spielfeld 32x32 groß sind und wenn ich dem path die absolute Koordinate der Einheit geben würde, wäre bei 1 Schluss, denn path meint die nächste Kachel, während die Einheit absolute Koordinaten hat.


----------



## mrBrown (28. Feb 2017)

Eichelhäer hat gesagt.:


> ich weiß jetzt woran es liegt.


Und woran liegt es, das die JVM ohne Fehlermeldung abstürzt?



Eichelhäer hat gesagt.:


> Ja das ist natürlich korrekt, aber selbst wenn das Array 15 Werte annehmen könnte würde es nicht gehen, da die Kacheln auf meinem Spielfeld 32x32 groß sind und wenn ich dem path die absolute Koordinate der Einheit geben würde, wäre bei 1 Schluss, denn path meint die nächste Kachel, während die Einheit absolute Koordinaten hat.


Wenn eine Kachel 32x32 ist, dann einfach die absoluten werte durch 15 teilen, dann hast du die Kachel. Von Kachel zu Koordinaten dann mal 15.


----------



## Eichelhäer (28. Feb 2017)

Ok, ich weiß leider nicht exakt was in der JVM passiert, so gut kenne ich mich auch wieder nicht aus, aber was im Quellcode passiert schon eher.
Also gehen wir mal kurz die von mir gepostete Methode move() durch:

1. Zeile: der Pfad wird ausgehend von der startx-bzw. startyposition 0 bis zur endx-bzw. endyposition ermittelt und gezeichnet. Im Prinzip ist es bei mir schlicht und ergreifend so, dass mein Spielfeld ein zweidimensionales Array ist, mit 15 Spalten und 15 Zeilen und nur beim Zeichnen die einzelnen Element auf 32x32, durch Multiplikation, gebracht werden und ich eigentlich nur ein 15x15 Pixel großes Spielfeld habe, bei dem der A* praktisch nur die einzelnen Pixel verwendet. Ich skaliere dieses kleine Spielfeld beim Zeichnen einfach nur.

2. Zeile: mithilfe der beiden Variablen endx bzw. endy rechne ich zur Laufzeit die absoluten Mauskoordinaten um in Kachelkoordinaten. Die size-Variable bezieht sich auf die 32x32 großen Kacheln.

3. Zeile: hier überprüfe ich einfach nur ob ein Pfad existiert und
4. Zeile: ob eine Laufvariable k kleiner ist als die Länge des Pfades. Also if(k<path.size())... .
5.Zeile: hier drehe ich die Liste um, also ich fange nicht beim Index path.size()-1 an sondern, was denke ich einfacher ist aber im Endeffekt keine Rolle spielt, bei 0.
6.Zeile: jetzt hole ich mir mithilfe der Laufvariablen k das erste Element der Liste und
7. 8. 9. 10. Zeile: überprüfe z.B. ob der x-Wert dieses Elements größer ist als der x-Wert der bewegten Einheit, wenn dem so ist erhöhe ich die absolute Position in Pixeln um eins und, wenn
11. Zeile: diese Position dann genau so groß ist wie der x-Wert des k-ten Elements der path-Liste dann erhöhe ich k um eins. Das geschieht eben solange wie eben k < die Länge der pathListe ist.  

Da mein Ziel nun eigentlich ist beliebig oft auf dem Spielfeld umherzulaufen, habe ich mir gedacht, dass direkt vor der Erhöhung von k, der Pfad um ein Element kleiner wird, bis die startposition genau die endposition ist, sodass ich den Pfad immer wieder und beliebig oft berechnen kann.
*UND HIER LIEGT MEIN PROBLEM,*
Bisher habe ich versucht startx- bzw. starty abhängig von der absoluten Position der Einheit zu verändern und genau da müsste ich von der absoluten- in die Kachelkoordinate umrechnen und jeder meiner Versuche das zu tun führte zum Absturz der JVM mit dem Windowsfehler usw. . 

Also, jetzt habe ich alles, so hoffe ich, gut erklärt und frage nochmal:

Wie muss man die startposition abhängig von den bereits gegebenen Variablen anpassen ?


----------



## mrBrown (28. Feb 2017)

Eichelhäer hat gesagt.:


> Also gehen wir mal kurz die von mir gepostete Methode move() durch:
> 
> 1. Zeile: der Pfad wird ausgehend von der startx-bzw. startyposition 0 bis zur endx-bzw. endyposition ermittelt und gezeichnet. Im Prinzip ist es bei mir schlicht und ergreifend so, dass mein Spielfeld ein zweidimensionales Array ist, mit 15 Spalten und 15 Zeilen und nur beim Zeichnen die einzelnen Element auf 32x32, durch Multiplikation, gebracht werden und ich eigentlich nur ein 15x15 Pixel großes Spielfeld habe, bei dem der A* praktisch nur die einzelnen Pixel verwendet. Ich skaliere dieses kleine Spielfeld beim Zeichnen einfach nur.
> 
> ...



Das ist nicht der von dir gepostete Code.
In deinem Code gibt es keine Schleifen mit Laufvariable k




Eichelhäer hat gesagt.:


> Bisher habe ich versucht startx- bzw. starty abhängig von der absoluten Position der Einheit zu verändern und genau da müsste ich von der absoluten- in die Kachelkoordinate umrechnen und jeder meiner Versuche das zu tun führte zum Absturz der JVM mit dem Windowsfehler usw. .


Was hast du denn versucht?
Mit einfachem Rechner bringt man die JVM nicht zum Absturz...


----------



## Eichelhäer (28. Feb 2017)

Ahh ok sorry,

```
int k = 0;
public void move(){
       
        if(Mouse.right){
            endx = (Mouse.mousex-(Mouse.mousex%w))/w;
            endy = (Mouse.mousey-(Mouse.mousey%h))/h;
        }
       
        path = findPath(startx,starty,endx,endy);
       
        if(path!=null){
           
            if(k < path.size()){
                Node node = path.get(k);
                if(node.j*h > y)y++;
                if(node.j*h < y)y--;
                if(node.i*w > x)x++;
                if(node.i*w < x)x--;
                if(x == node.i*w && y == node.j*h){
                    k++;
                }
            }
        }
    }
```

Das ist jetzt der aktualisierte Code. Sorry nochmal.
Zu meinen Versuchen:
Zum einen habe ich versucht abhängig von der Einheitenposition startx bzw. starty zu erhöhen bzw. zu vermindern und zum anderen kurz vor der Erhöhung von k, das passierte Element der path-List mittels remove zu entfernen.
Beides ging schief und alles stürzte ab.


----------



## Eichelhäer (28. Feb 2017)

startx und starty global deklariert und mit 0 initialisiert.


----------



## mrBrown (28. Feb 2017)

Eichelhäer hat gesagt.:


> Zum einen habe ich versucht abhängig von der Einheitenposition startx bzw. starty zu erhöhen bzw. zu vermindern und zum anderen kurz vor der Erhöhung von k, das passierte Element der path-List mittels remove zu entfernen.
> Beides ging schief und alles stürzte ab.


Und wie sah der Code dazu aus?


----------



## Eichelhäer (28. Feb 2017)

Ach ja noch was vergessen:
Ich muss die Liste jetzt nicht mehr umdrehen das hat sich erledigt.
Und außerdem habe ich gerade was verstanden und erfolgreich umgesetzt, nämlich wie man ein Spielfeld performant umsetzt, deshalb stehen jetzt hier w und h drin. Die beiden Variablen werden abhängig von der Fenstergröße und den Spalten und Zeilen des Spielfeldes berechnet. Das heißt je größer die Werte der Spalten bzw. Zeilen sind, desto kleiner sind die Kacheln, die gezeichnet auf dem Bildschirm erscheinen.


----------



## Eichelhäer (28. Feb 2017)

Der erste Codeversuch:

```
public void move(){
       
        if(Mouse.right){
            endx = (Mouse.mousex-(Mouse.mousex%w))/w;
            endy = (Mouse.mousey-(Mouse.mousey%h))/h;
        }
       
        path = findPath(startx,starty,endx,endy);
       
        if(path!=null){
           
            if(k < path.size()){
                Node node = path.get(k);
                if(node.j*h > y)y++;
                if(node.j*h < y)y--;
                if(node.i*w > x)x++;
                if(node.i*w < x)x--;
                if(x == node.i*w && y == node.j*h){
                    startx = node.i;
                    starty = node.j;
                    k++;
                }
            }
        }
    }
```

Führt dazu, dass sich die Einheit auf das erste Element des Pfades bewegt und sich dann nicht mehr weiter bewegt. Kein Windows Fehler.

Zweiter Versuch:

```
public void move(){
       
        if(Mouse.right){
            endx = (Mouse.mousex-(Mouse.mousex%w))/w;
            endy = (Mouse.mousey-(Mouse.mousey%h))/h;
        }
       
        path = findPath(startx,starty,endx,endy);
       
        if(path!=null){
           
            if(k < path.size()){
                Node node = path.get(k);
                if(node.j*h > y)y++;
                if(node.j*h < y)y--;
                if(node.i*w > x)x++;
                if(node.i*w < x)x--;
                if(x == node.i*w && y == node.j*h){
                    path.remove(k);
                    k++;
                }
            }
        }
    }
```

Es passiert nix d.h. kein Element des Pfades wird gelöscht und
Hhhhhhh ich muss grad lachen, weil ich es jetzt nicht mehr schaffe gewollt diesen Totalabsturz herbeizuführen, ich weiß nicht mehr was ich da gemacht hatte, aber es lag an startx und starty soviel ist sicher.
Egal.


----------



## Eichelhäer (28. Feb 2017)

Soviel zu meinen Versuchen. Aber ich bleib dran.


----------



## Eichelhäer (1. Mrz 2017)

Sooo, ich poste jetzt hier mal den gesamten Code. Es sind zwei relevante Klassen:


```
package main;

import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Level{
   
    public int x;
    public int y;
   
    public int k;
   
    public int w;
    public int h;
   
    public int cols = 50;
    public int rows = 50;
   
    public int startx;
    public int starty;
   
    public Node[][] grid = new Node[cols][rows];
   
    List<Node> openList = new ArrayList<Node>();
    List<Node> closedList = new ArrayList<Node>();
    List<Node> path = new ArrayList<Node>();
   
    Node start;
    Node end;
    Node node;
   
    public Level(int WIDTH,int HEIGHT){

        w = WIDTH / cols;
        h = HEIGHT / rows;
       
        for(int i = 0;i<cols;i++){
            for(int j = 0;j<rows;j++){
                grid[i][j] = new Node(i,j);
            }
        }
       
        for(int i = 0;i<cols;i++){
            for(int j = 0;j<rows;j++){
                grid[i][j].addNeighbours(grid);
            }
        }
    }
   
    public ArrayList<Node> findPath(int sx,int sy,int ex,int ey){
       
        start = grid[sx][sy];
        end = grid[ex][ey];
       
        openList.add(start);
       
        while(openList.isEmpty()==false){
           
            int winner = 0;
            for(int i = 0;i <openList.size();i++){
                if(openList.get(i).f < openList.get(winner).f){
                    winner = i;
                }
            }
           
            Node current = openList.get(winner);
            openList.remove(current);
            closedList.add(current);
           
            if(current == end){
                ArrayList<Node> path = new ArrayList<Node>();
                Node tmp = current;
                path.add(tmp);
                while(tmp.previous!=null){
                    path.add(tmp.previous);
                    tmp = tmp.previous;
                }
                openList.clear();
                closedList.clear();
                Collections.reverse(path);
                return path;
            }
           
            List<Node> neighbours = current.neighbours;
           
            for(Node neighbour : neighbours){
                int cost = current.g + heuristic(current,neighbour);
                if(openList.contains(neighbour) && cost < neighbour.g){
                    openList.remove(neighbour);
                }
                if(closedList.contains(neighbour) && cost < neighbour.g){
                    closedList.remove(neighbour);
                }
                if(openList.contains(neighbour) == false && closedList.contains(neighbour) == false && neighbour.obstacle == false){
                    neighbour.g = cost;
                    openList.add(neighbour);
                    neighbour.f = neighbour.g + neighbour.h;
                    neighbour.previous = current;
                }
            }
        }
       
        return null;
    }
   
    public void render(Graphics g){
        if(Mouse.right){
        int endx = (Mouse.mousex-(Mouse.mousex%w))/w;
        int endy = (Mouse.mousey-(Mouse.mousey%h))/h;
       
        path = findPath(0,0,endx,endy);
        }
        if(path!=null){
            if(path.size() > k){
                node = path.get(k);
                if(node.j*h > y)y++;
                if(node.j*h < y)y--;
                if(node.i*w > x)x++;
                if(node.i*w < x)x--;
                if(x == node.i*w && y == node.j*h){
                    k++;
                }
            }
        }
       
        for(int i = 0;i<cols;i++){
            for(int j = 0;j<rows;j++){
               
                if(grid[i][j].obstacle){
                    g.setColor(Color.BLACK);
                    g.fillRect(grid[i][j].i*w,grid[i][j].j*h,w,h);
                }
                if(!grid[i][j].obstacle){
                    g.setColor(Color.BLACK);
                    g.drawRect(grid[i][j].i*w,grid[i][j].j*h,w,h);
                }
            }
        }
       
        for(int i = 0;i<openList.size();i++){
            g.setColor(Color.GREEN);
            g.fillRect(openList.get(i).i*w,openList.get(i).j*h,w,h);
        }
       
        for(int i = 0;i<closedList.size();i++){
            g.setColor(Color.RED);
            g.fillRect(closedList.get(i).i*w,closedList.get(i).j*h,w,h);
        }
       
        for(int i = 0;i<path.size();i++){
            g.setColor(Color.BLUE);
            g.fillRect(path.get(i).i*w,path.get(i).j*h,w,h);
        }
       
        g.setColor(Color.CYAN);
        g.fillRect(x,y,w,h);
    }
   
    public int heuristic(Node A,Node B){
        // 4-Direction-Manhattendistance
        int dx = Math.abs(A.i-B.i);
        int dy = Math.abs(A.j-B.j);
        return 1 * (dx + dy);
       
        // 8-Direction-Chebyshevdistance
        //int dx = Math.abs(A.i-B.i);
        //int dy = Math.abs(A.j-B.j);
        //return 1 * (dx + dy) + ( 1 - 2 * 1) * Math.min(dx,dy);
       
        // 8-Direction-Octiledistance
        //int dx = Math.abs(A.i-B.i);
        //int dy = Math.abs(A.j-B.j);
        //return 1 * (dx + dy) + ( Math.sqrt(2) - 2 * 1) * Math.min(dx,dy);
       
        // Euclidiandistance
        //int dx = Math.abs(A.i-B.i);
        //int dy = Math.abs(A.j-B.j);
        //return 1 * Math.sqrt(dx * dx + dy * dy);
    }
}
```


package main;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Node{
 public int i;
 public int j;
 public int g;
 public int h;
 public int f;
 public List<Node> neighbours;
 public Node previous;
 public boolean obstacle;
 public Random random = new Random();

 public Node(int i,int j) {
  this.i = i;
  this.j = j;
  this.g = 0;
  this.h = 0;
  this.f = 0;
  this.previous = null;
  this.obstacle = false;
  this.neighbours = new ArrayList<Node>(); 

  if(random.nextInt(100) < 10){
   this.obstacle = true;
  }
 }

 public List<Node> addNeighbours(Node[][] grid){

  int i = this.i;
  int j = this.j;

  if(i < 50 - 1){
   neighbours.add(grid[i+1][j]);
  }
  if(i > 0){
   neighbours.add(grid[i-1][j]);
  }  
  if(j < 50 - 1){
   neighbours.add(grid_[j+1]);
  }
  if(j > 0){
   neighbours.add(grid[j-1]);
  }

  return neighbours;

 }
}

Dieser Code ist z.B. in ECLIPSE ausführbar.
Jetzt nochmal zu dem Totalabsturz:
Wenn man in der render Methode der Level Klasse die bestehende Zeile durch:

path = findPath(x,y,endx,endy);

ersetzt, kommt z.B. ein Totalabsturz.

Und noch was: Bevor jemand fragen sollte warum ich den A* in der render - Methode aufrufe, kann ich nur sagen, dass das für diese kleine Testapplikation völlig ausreichend ist und ich erst später ein vernünftigeres GameLoop implementieren werde. Es geht mir hierbei erstmal nur rein um die Funktionalität des Algorithmus.

Nochmal zu meiner ursprünglichen Frage, wie erreiche ich, dass wenn ich ein Feld anklicke die Einheit dorthin "fährt" und während der "Fahrt" ein durch erneutem Klick ein neuer Pfad ermittelt werden kann und das beliebig oft und die Einheit stets den aktuell erzeugten neuen Pfad "abfährt" ??????????_


----------



## mrBrown (1. Mrz 2017)

Eichelhäer hat gesagt.:


> _Und noch was: Bevor jemand fragen sollte warum ich den A* in der render - Methode aufrufe, kann ich nur sagen, dass das für diese kleine Testapplikation völlig ausreichend ist und ich erst später ein vernünftigeres GameLoop implementieren werde. Es geht mir hierbei erstmal nur rein um die Funktionalität des Algorithmus.
> 
> Nochmal zu meiner ursprünglichen Frage, wie erreiche ich, dass wenn ich ein Feld anklicke die Einheit dorthin "fährt" und während der "Fahrt" ein durch erneutem Klick ein neuer Pfad ermittelt werden kann und das beliebig oft und die Einheit stets den aktuell erzeugten neuen Pfad "abfährt" ??????????_



Indem du die Pfadberechnung jetzt schon auslagerst, und nicht erst später 

Du berechnest beim Klicken den aktuellen Pfad, speicherst den, und alle x ms bewegst du die Figur auf das nächste Feld des Pfades.
Beim Klicken auf ein neues Feld einfach nur den Pfad neu berechnen und speichern.


----------



## VfL_Freak (1. Mrz 2017)

Habe mir jetzt den ganzen Code reingezogen, weil er (neben der Formatierung) aufgrund fehlender Kommentare kaum nachvollziehbar ist.
Aber was mir spontan dazu einfällt:


Eichelhäer hat gesagt.:


> findPath(x,y,endx,endy);


stellst Du hier sicher, dass x uny kleiner als endx und endy ist ??

Gruß Klaus


----------



## Eichelhäer (1. Mrz 2017)

Aha, der Vfl_Freak kann auch normal kommunizieren... Egal. ....
Der Code den du zitiert hast führt ja zu dem relativ krassen Fehler. Wenn du nun die eigentliche Bewegung betrachtest stellst du fest, dass die einzelnen Elemente des Pfades im Prinzip bloß die Kachelpositionen des grids darstellen, während x und y die absoluten Pixelkoordinaten sind. So. Nun passiert bei dem Fehler folgendes: Die findPath Methode ist abhängig vom grid und will deshalb nur Kachelkoordinaten, mit x und y übergebe ich aber absolute Koordinaten. Die findPath Methode erhält nach der Erhöhung von x bzw. y den Wert 1 für x bzw. y und meint dann damit aber tatsächlich die Kachelposition (hier: 1,0) . Das wäre alles nicht so schlimm wenn ich meine drawRect Methode anpassen würde. Wenn ich das NICHT tue, dann kommt es zu einem Konflikt zwischen absoluten und Kachelkoordinaten und genau das löst den Fehler beim Zeichnen aus und ich habe tatsächlich keine Ahnung wie die drawRect Methode intern arbeitet. 

Ich hoffe du verstehst was ich da versucht habe zu erklären.
Wennnicht frag einfach nochmal.


----------



## mrBrown (1. Mrz 2017)

Es stürzt also ab, wenn du drawRect Koordinaten außerhalb des sichtbaren Bereichs übergibst?


----------



## Eichelhäer (1. Mrz 2017)

Ach und noch was prinzipielles an die Adresse von Vfl_Freak:
Wenn du etwas an meiner Frage nicht verstehst, ist das kein Problem, aber tatsächlich hast du fünf mal geantwortet und hast mir damit auf überhaupt keine Art und Weise irgendwie weiterhelfen können.
Im Grunde genommen waren deine fünf zu diesem Thema gegebenen Antworten für mich total überflüssig
und alles andere als konstruktiv für mein Thema.
Also, für das nächste Mal: Erst lesen dann denken und dann posten.


----------



## Eichelhäer (1. Mrz 2017)

An MrBrown:
Hmm... . Eigentlich nicht. Denn x wird z.B. eins und offensichtlich befindet sich der Wert eins im sichtbaren Bereich denke ich.
Also:
x und y sind 0 der path wird erzeugt k ist 0 , k wird erhöht, das Element des Pfades wird mit der absoluten Position x bzw. y verglichen und x wird inkrementiert. x wird an drawRect übergeben dann Absturz.


----------



## Eichelhäer (2. Mrz 2017)

Hallo,
ich mache es kurz, ich habe es so wie ich wollte.
Es lag daran, dass das Spielfeld zur Laufzeit bekannt sein muss und das ist alles.
Damit ist dieses Thema geschlossen.


----------

