A*

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

Farbfinsternis

Betreff: A*

BeitragMi, Jul 26, 2006 17:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe mir mal das Tutorial von http://www.policyalmanac.org/g...al_de.html reingezogen und wollte mal selbst eine Implementation von A* in BMax basteln.

-- Ja, ich weiß dass es zahlreiche Basic-Quelltexte gibt die das tun, ich will es aber selbst schaffen --

Meine Frage nun: Wie bekomme ich heraus dass es gar keinen Weg zum Ziel gibt? Wenn ich nämlich rekursiv rumschraube hängt sich die Kiste irgendwann auf weil sie ewig an der letzten Wand rumfrickelt. Bisher löse ich es so dass Wände nicht als "nicht begehbar" gelten, sondern dass sie einen sehr hohen Wegkosten-Wert besitzen und so ab einem bestimmten Wert einfach übersprungen werden. Ist zwar nicht so schick, aber wenigsten hängt sich das Programm nicht auf.


Bin dankbar für jede Idee!
Farbfinsternis.tv
 

Ava

Gast

BeitragMi, Jul 26, 2006 18:38
Antworten mit Zitat
Wenn Du den A* richtig umsetzt, kann es eigentlich zu keiner Endlosschleife kommen, da Du ja jedem Feld die Wegkosten übergibst und es nur betrittst, wenn Du einen kürzeren Weg findest. Deshalb endet es irgendwann ganz automatisch, selbst wenn kein Weg gefunden werden kann - was dann allerdings unter Umständen ganz schön viel Rechenzeit in Anspruch nimmt.

Alternativ kannst Du zusätzlich auch die Map vorweg per "Füllroutinen" in Gebiete einteilen. Also Gebiete, die voneinander komplett abgertennt und unereichbar sind. Dann checkst Du zu Beginn Deines Pahtfindings, ob Start- und Endpunk im selben Gebiet liegen, denn ansonsten ist das Zeil nicht erreichbar und du kannst Dir den A* sparen.

Dazu musst Du dann aber (und solltest Du ohnehin!) die Mauern auf "unpassierbar" einstellen.

So .... das mal als kleinen Denkanstoss. Smile

Farbfinsternis

BeitragDo, Jul 27, 2006 8:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn ich A* "richtig umsetze"? Ich muss gestehen dass ich mir keine wissenschaftlichen Abhandlungen zu diesem Thema angetan habe, aber meine oben gepostete Quelle scheint immer davon auszugehen dass es eine Lösung gibt denn das Ende lautet: "Until start_x = end_x".
Hmm, muss ich mir wohl doch noch kompliziertere Erläuterungen reinziehen.
Farbfinsternis.tv

BladeRunner

Moderator

BeitragDo, Jul 27, 2006 9:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Wie Ava schon anmerkte erkennt A* selbstständig ob es einen Weg gibt. Leider ist das auch der Hauptnachteil von A* - wenn es keinen Weg gibt werden alle begehbaren Felder abgesucht bis der Abbruch erfolgt.
Insofern muss Dein Implementationsansatz verkehrt sein. Bei A* ist es so dass nicht begehbare Felder nicht hohe Wegkosten haben, sondern als nicht begehbar markiert werden.
Ich würde auch den Ansatz präferieren schon beim erstellen der Karte einzelne Zonen abzugrenzen welche voneinander getrennt sind, denn dann ersparst Du dir die langwierige Suche nach nicht verbundenen Feldern. Mit etwas Weitblick lassen sich auch Sonderfälle wie durch Türen getrennte Bereiche etc. ohne Probleme lösen.
Sehr interessant ist auch der Ansatz die Karte sowieso in Bereiche zu untergliedern deren Exits du vorgibst. Dann kann sich a* von Exit zu Exit hangeln und du sparst dir eine Menge Berechnungszeit.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

Farbfinsternis

BeitragDo, Jul 27, 2006 17:42
Antworten mit Zitat
Benutzer-Profile anzeigen
So ... da ich mit der Materie irgendwie garnicht so recht klar kam, habe ich einfach TheShadows Code nach BMax konvertiert.

Funktioniert soweit ganz gut, allerdings mit einem Schönheitsfehler: Der Pfad schlägt komische Haken.

Ich wäre sehr erfreut wenn sich jemand mal die Sache ansehen könnte der sich damit auskennt. Da der Code zuviel wäre um ihn hier zu posten habe ich ein Archiv mit Quelltext und vorkompiliertem Sample auf meinen Space gepackt:

http://www.makegame.de/downloads/AStar.zip (ca. 52kb)

Danke schonmal für jeden hilfreichen Hinweis!
Farbfinsternis.tv

BladeRunner

Moderator

BeitragDo, Jul 27, 2006 20:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Was hier hilft (ohne mir den Code genua durchgesehen zu haben) ist es eine Richtungsänderung zu "bestrafen".
D.h. Du prüfst ob der neue Wegpunkt in eine andere Richtung liegt als der aktuelle. 'Wenn ja addierst du eine kleine Strafsumme zu den Kosten. Somit wird der "geradlinige" Weg bevorzugt.
Allerdings führt das gerne zu recht unnatürlichen Wegen mit wenigen aber scharfen Kurven. Da wäre dann über eine Kurvenglättung mittels Spline nacnhzudenken. Hier kommt es drauf an wieviel Rechenzeit Du opfern kannst.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

Farbfinsternis

BeitragDo, Jul 27, 2006 21:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, dieses Prinzip ist mir bekannt. Allerdings ist es merkwürdig dass in TheShadows original Code dieses Verhalten nicht vorkommt. Ich habe tatsächlich nur seinen Code auf BMax umgeschrieben. Klar musste ich viele Sachen "umoperieren", z.B. das Type-Listen Verhalten von BB. Aber im Prinzip ist mein Code exakt der von TheShadow.

Hmm ... sehr, sehr merkwürdig.
Farbfinsternis.tv
 

Dreamora

BeitragDo, Jul 27, 2006 21:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Kenne zwar seinen Code nicht.
Aber wenn irgendwo darin irgendwelche Rundungen von Float nach Int sind, dann musst du die im BM Code ändern und zwar someint = Int(somefloat) wird zu someint = Int(somefloat + 0.5), denn BM rundet bei Int nimmer sondern schneidet alles nach kommastelle ab
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

Farbfinsternis

BeitragFr, Jul 28, 2006 10:03
Antworten mit Zitat
Benutzer-Profile anzeigen
Daran kann es nicht liegen, es werden keine Fließkommazahlen im Quelltext verwendet.
Farbfinsternis.tv

Markus2

BeitragFr, Jul 28, 2006 12:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Ist zwar nicht A* aber vieleicht auch interessant .

https://www.blitzforum.de/foru...hp?t=17966

Byteemoz

BeitragFr, Jul 28, 2006 12:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn Du in der EightPath Function das "If dirz[i] = 1" raus nimmst, funktionierts.

-- Byteemoz

Code: [AUSKLAPPEN]
...

     For Local i:Int = 0 To 7
       Local x:Int = nod.x + dirx[i]
       Local y:Int = nod.y + diry[i]
      
       If x >= 0 And y >= 0 And x < mapwidth And y < mapheight
         If map[x,y] = 0 And nodemap[x,y] = 0
'           If dirz[i] = 1
             If map[x,nod.y] <> 1 And map[nod.x,y] <> 1                
                 tempnode:TNodes      = New TNodes
                 tempnode.parent      = nod
                 tempnode.cost         = nod.cost + 1
                 tempnode.x            = x
                 tempnode.y            = y
                
                 n_open:TOpen         = New TOpen
                 n_open.nod            = tempnode
                 nodemap[x,y]         = 1
                
                 If x = endx And y = endy Then ende = True; Exit
             EndIf
'           EndIf
         EndIf
       EndIf
     Next

...
MaxIDE Community Edition: Summary | Bugs | Feature Requests | CVS Repository | Thread

Farbfinsternis

BeitragFr, Jul 28, 2006 13:09
Antworten mit Zitat
Benutzer-Profile anzeigen
*wow* ... trotzdem habe ich nicht den geringsten Schimmer wie das funktioniert Very Happy
Farbfinsternis.tv

Byteemoz

BeitragFr, Jul 28, 2006 13:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich auch nicht, aber ganz unten in as.bmx befindet sich eine Liste von XYZ-Koordinaten für alle möglichen Richtungen - wobei mit der Z-"Koordinate" zwischen den horizontalen/vertikalen (=0) und diagonalen (=1) Richtungen unterschieden wird.
Mit "If dirz[i] = 1" werden also nur diagonale Ricgtungen erlaubt.
-- Byteemoz
MaxIDE Community Edition: Summary | Bugs | Feature Requests | CVS Repository | Thread

Farbfinsternis

BeitragDi, Aug 01, 2006 18:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe im TM Thread im DigitalArtForum großspurig behauptet dass mein A* Algo funktioniert ... ich hätte das vor diesem Posting mal mit anderen Start- und Zielkoordinaten testen sollen Embarassed

Kurz: Die Shice funktioniert nicht.
Also habe ich das Tutorial und einige weitere bis zu 20 Mal gelesen. Logisch ist das Ganze kein Problem, programmiertechnisch aber schon. Zudem musste ich feststellen dass TheShadows System, welches er unter http://www.blitzbase.de/artikel/path_1.htm anbietet einige Fehler beinhaltet oder zumindest unvollständig beschrieben ist. Sein Quelltext ist (dank fehlender Kommentare) für Einsteiger so sinnvoll wie eine Diätenerhöhung für unsere Flachzange Nummer Eins namens Merkel.

Was ich will? Nun, ich würde es gern sehen wenn ich hier eine Diskussion über die Implementierung des A* Algorithmus in BMax lostreten könnte. Im Folgenden beschreibe ich mal wie ich es angegangen und gescheitert bin:

Ich definiere eine Map cdata:int[width, height] in der ich nicht begehbare Felder mit einer 1 markiere. Ich lege die Start- und Zielkoordinaten in entsprechenden Variablen fest.

    Beginnend bei start_x:Int und start_y:Int
  • Schreibe den Startpunkt in eine Liste welche die fertig behandelten Nodes beinhaltet
  • Überprüfe alle 8 umliegenden Felder auf die geringsten Wegkosten. Horizontale Felder bekommen einen Basiskostenwert von 10, diagonale einen von 14. Ich addiere also diesen Basiskostenwert mit der heuristischen Entfernung zum Ziel (naiv mit Abs(start_x-ziel_x)+Abs(start_y-ziel_y)), trage alle Felder in eine offene Liste (ToDo) ein und ernenne das Feld mit den geringsten Kosten zum nächsten Navigationspunkt.
  • Der neue Navigationspunkt (Node) wird in die geschlossene Liste eingetragen und aus der offenen entfernt.
  • Ich wiederhole Punkt 2, ignoriere dabei alle Nodes die sich bereits in der offenen oder geschlossenen Liste befinden.
  • Ich mache den Kram solange bis ich das Ziel erreicht habe, oder die offene Liste leer ist. In letzterem Fall müssten sich sämtliche Felder der Map in der geschlossenen Liste befinden und hier vermute ich auch einen Denkfehler.
  • Nach obigem Prozedere müsste ich theoretisch in der geschlossenen Liste einen nicht optimierten Pfad haben, sollten es einen geben. Aber es funktioniert nicht ... die Kiste rödelt sich fest und kommt keine Node weiter.

Falls mein Geschreibsel verständlich ist, würde ich mich über eine Diskussion und Lösungsvorschläge sehr freuen.
Farbfinsternis.tv

TheShadow

Moderator

BeitragFr, Aug 04, 2006 22:16
Antworten mit Zitat
Benutzer-Profile anzeigen
hm was für fehler sind im tutorial?

der kerncode ist im prinzip so simpel, dass eine kommentierung fast schon sinnlos ist... außerdem ist im tutorial vieles beschrieben...
AMD64 3500+ | GeForce6600GT 128MB | 1GB DDR | WinXPsp2

BladeRunner

Moderator

BeitragSo, Aug 06, 2006 13:11
Antworten mit Zitat
Benutzer-Profile anzeigen
So, hier dann nun mein Senf zu der AStar-Wurst.
Unoptimiert, aber es läuft.

Kommentare sind reichlich drin, anhand derer der Ablauf zu verstehen sein sollte.

Wie aus dem Test am Ende des Quellcodes ersichtlich ist braucht man eine TMap mit den Daten und die TNode.Astar8()-Funktion, ich habe bislang allerdings nur a*8 drin. Die 4er ist aber theoretisch ne Sache von 2 If-thens.
Leckerli ist die Möglichkeit mittels returnnearest den nächsten gefundenen Punkt zurückgeben zu lassen, wenn das Ziel nicht erreichbar ist.

~EDIT:~ Für aktuellen Code ins Codearchiv schauen. Habe einen kleineren Bugfix vorgenommen und arbeite noch weiter am Algo.
Code: [AUSKLAPPEN]
Type TMap
   
   'Daten:
   Field Map:Int[1,1,1]    'die Karte: b*h*layer, wobei aus performancegründen l,h,w gespeichert wird, da
   Field width:Int         'dann die einzelnen Layerdaten hintereinander im Speicher stehen.
   Field height:Int
   Field layer:Int
   
   'Globale Daten:
   Global Lmap:TList = CreateList()
   
   'Funktionen:
   Function Create:Tmap(w:Int,h:Int,l:Int)
      'erstellt eine neue Karte in den angegebenen Dimensionen. Sie wird in Lmap gespeichert.
      Local instanz:tmap = New tmap
      instanz.map = New Int[l,h,w]
      instanz.width = w
      instanz.height = h
      instanz.Layer = l
      ListAddLast lmap,instanz
      Return instanz
   End Function
   
   'Methoden:
   Method resize(w:Int,h:Int,l:Int)
      'redimensioniert eine Karte. Der Inhalt wird soweit möglich erhalten.
      Local copyi:Int,copyj:Int,copyk:Int
      If w >= self.width Then
         copyi = self.width
         Else
         copyi = w
      EndIf
      If h >= self.height Then
         copyj = self.height
         Else
         copyj = h
      EndIf
      If l >= self.layer Then
         copyk = self.layer
         Else
         copyk = l
      EndIf            
      Local tempmap:Int[copyk,copyj,copyi]

      For Local i:Int = 0 To copyi -1
         For Local j:Int = 0 To copyj -1
            For Local k:Int = 0 To copyk-1
               tempmap[k,j,i]=self.map[k,j,i]
            Next
         Next
      Next
         
      self.map = New Int[l,h,w]
      self.width = w
      self.height = h
      self.Layer = l
      
      For i:Int = 0 To copyi -1
         For j:Int = 0 To copyj -1
            For k:Int = 0 To copyk-1
               self.map[k,j,i]=tempmap[k,j,i]
            Next
         Next
      Next
   
   End Method
   
   Method getvalue(w:Int,h:Int,l:Int)
      'liesst den Wert aus der angegebenen Zelle
      If (w >=0) And (w < self.width) And (h >=0) And (h <self.height) And (l >=0) And (l<self.layer) Then
         Return self.map(l,h,w)
      Else
         RuntimeError "Unable to perform 'Read' on 'Map':Index out of Bounds"
      EndIf
      
   End Method
   
   Method setvalue(w:Int,h:Int,l:Int,value:Int)
      'setzt den Wert in die angegebene Zelle
      If (w >=0) And (w < self.width) And (h >=0) And (h <self.height) And (l >=0) And (l<self.layer) Then
         self.map(l,h,w) = value
      Else
         RuntimeError "Unable to perform 'Write' on Map:Index out of Bounds"
      EndIf
   End Method
   
   Method fill(value:Int)
      'füllt die Map mit einem Wert
      For Local i:Int = 0 To self.width -1
         For Local j:Int = 0 To self.height -1
            For Local k:Int = 0 To self.layer -1
               self.map(k,j,i) = value
            Next
         Next
      Next   
   End Method

   Method filllayer(l:Int,value:Int)
      'füllt einen layer mit einem Wert
      If l < self.layer Then
         For Local i:Int = 0 To self.width -1
            For Local j:Int = 0 To self.height -1
               self.map(l,j,i) = value
            Next
         Next
      EndIf      
   End Method
   
   Method destroy:TMap()
      'zerstört die aktuelle Karteninstanz
      ListRemove lMap,Self
      Return Null
   End Method
   
   Method draw()
      'vorläufige Implementierung für Testzwecke Astar
      Local i:Int,j:Int,k:Int
      For i = 0 To self.width-1
         For j = 0 To self.height-1
            For k = 0 To self.layer-1
               If self.map(k,j,i) = 1 Then
                  SetColor 155+10*k,0,0
               Else
                  SetColor 100+10*k,100+10*k,100+10*k
               EndIf
               DrawRect i*30,j*30,25-(k*3),25-(k*3)
            Next
         Next
      Next   
   End Method
   
End Type
'____________________________________________________________________________________________________

'____________________________________________________________________________________________________
Type TNode
   
   'Daten:
   Field lastnode:TNode
   Field x:Int,y:Int
   Field cost:Float, aprox:Float
   
   'Globale Daten:
   Global LOpen:TList = CreateList()
   Global LClose:TList = CreateList()
   
   'Funktionen:
   Function Create:TNode()
      'erstellt einen neuen Knoten.
      Local instanz:TNode = New TNode
      Return instanz
   End Function
   
   Function clear()
      'löscht die Offene und die geschlossene Liste
      ClearList LOpen
      ClearList LClose
   End Function
   
   Function draw(ldraw:TList)
      'zeichnet den Weg der gefunden wurde ein. Testimplementierung.
      SetColor 0,0,200
      If ldraw = Null Then Return
      For Local drawnode:tnode = EachIn Ldraw
         DrawRect drawnode.x*30+10,drawnode.y*30+10,10,10
      Next
   End Function
   
   Function AStar8:TList(startX:Int,startY:Int,targetX:Int,targetY:Int,map:TMap,layer:Int = 0,block:Int = 1,Returnnearest:Int = False)
      'Der AStar-Algo für 8 Richtungen. Block gibt an welcher Karteneintrag für blockerte Wege
      'gilt, Map ist die Karte die für die Wegfindung benutzt wird.
      
      TNode.clear()   'die Listen werden gesäubert
      Local Start:Tnode= TNode.create()   'Der Startpunkt wird erschaffen
      start.setcoords(startx,starty)      'Die Startkoorinaten werden eingetragen
      start.addopen()                  'und der Startpunkt wird auf die offene Liste gesetzt.
      start.cost = 0

      Target:Tnode = TNode.create()      'das Ziel wird erschaffen
      Target.setcoords(targetX,targety)   'und mit Koordinaten versehen
      start.aprox = Sqr((target.x-start.x)^2+(target.y-start.y)^2)   'Kostenschätzung Startfeld
      
      Local search:Tnode = start   'nun beginnt der Reigen: Start ist der erste untersuchte Knoten
      Local done:Int = False      'Noch kein Ziel gefunden
      Local donenode:tnode      'Nodeinstanz für das Zielfeld
      While (Not done) And (Not ListIsEmpty(LOpen)) 'solange es noch offene Knoten zum untersuchen gibt
         search.close()   'die aktuelle Node wird bearbeitet und ist daher geschlossen
         For Local x = -1 To 1   'untersuche die umliegenden Felder
            For Local y = -1 To 1
               Local tempx:Int = search.x+x
               Local tempy:Int = search.y+y
               If tempx = target.x And tempy = target.y Then   'Ziel gefunden ?
                  done = True 'Ziel gefunden !
                  donenode = tnode.create()   'nun wird donenode erschaffen
                  donenode.lastnode=search   'und der letzte schritt dort hin gespeichert
                  donenode.setcoords(tempx,tempy)
               EndIf
               If (tempx >=0) And (tempx < map.width) And (tempy>=0) And (tempy<map.height) Then   'gültige Kartenposition?
                  If (x + 2*y) Then 'falls nicht der Mittelpunkt (ist nur 0 wenn beide Komponenten es sind)
                     Local tempfound:Int = False   'das untersuchte Feld ist noch nicht in der Liste der offenen Felder ?
                     For Local secsearch:Tnode = EachIn LOpen
                        If (secsearch.x = tempx) And (Secsearch.y=tempy) Then
                           tempfound = True 'doch, ist es
                        EndIf
                     Next
                     For secsearch:Tnode = EachIn LClose   'und bei den geschlossenen vielleicht ?
                        If (secsearch.x = tempx) And (Secsearch.y=tempy) Then   
                           tempfound = True   'doch, ist es
                        EndIf
                     Next
                     If (tempfound = False) And (map.getvalue(tempx,tempy,layer) <> block) Then   'wenn der Knoten noch nicht bekannt war
                        Local node:Tnode = TNode.create()   'dann ist er es jetzt
                        Node.setcoords(tempx,tempy)   'wo ist er
                        node.lastnode = search   'von wo wurde er erreicht ?
                        node.addopen()   'ab auf die Liste der zu bearbeitenden Knoten
                        node.cost = search.cost +Sqr(Abs(x)+Abs(y))   'wie teuer war es her zu kommen (es werden für Diagonalen mehr berechnet.) ?
                        node.aprox = Sqr((target.x-node.x)^2+(target.y-node.y)^2)   'wie lautet die Schätzung für den Rest der Strecke ?
                     EndIf
                  EndIf
               EndIf
               
            Next
         Next
         Local mincost:Float =$7fffffff   'setze die Kosten auf ein maximum   
         For secsearch:Tnode = EachIn LOpen'nun suche in der Offenen Liste nach dem Knoten mit den geringsten zu erwartenden Gesamtkosten
            If secsearch.cost + secsearch.aprox < mincost Then
               search = secsearch   'dieser ist dann der nächste Suchknoten für Astar und wird beim nächsten durchlauf auf die geschlossene gesetzt.
               mincost = secsearch.cost+secsearch.aprox
            End If
         Next   
      Wend
      'dieser Teil wird abgearbeitet wenn: a) der Zielknoten erreicht wurde oder
                                 'b) kein offener Knoten mehr existiert, d.h. das Ziel nicht
                                 'erreicht werden kann.
      If (Returnnearest = True) And (done = False)  Then   'soll der nächstmöglichste Punkt zurückgegeben werden ?
         mincost= $7fffffff
         For secsearch:Tnode = EachIn LClose   'dann suche in der geschlossenen Liste den Punkt mit den niedrigsten geschätzten Restkosten
            If secsearch.aprox < mincost Then
               donenode = secsearch
               mincost = secsearch.aprox
            End If
         Next
      EndIf   
      
      If donenode <> Null Then   'wenn es ein Ziel gibt, erstelle die Liste mit den Wegpunkten
         Local Lreturn:TList = CreateList()
         Local loop:TNode = Donenode
         Repeat
            ListAddFirst Lreturn,loop
            loop = loop.lastnode
         Until loop = start
         ListAddFirst Lreturn,loop   'optional, so wird der Sartpunkt auch als wegpunkt übergeben.
         Return LReturn
      Else                  'wenn es kein Ziel gibt, gebe eine undefinierte Liste zurück
         Return Null
      EndIf
      
   End Function
   
   'Methoden:
   Method Addopen()
      'fügt die Instanz der Suchliste hinzu.
      ListAddLast LOpen, Self
   End Method
   
   Method Close()
      'entfernt die Instanz von der Offenen Liste und setzt sie auf die geschlossene Liste
      If ListContains (LOpen,Self) Then
         ListRemove LOpen,Self
         ListAddLast LClose,Self
      EndIf      
   End Method
   
   Method setcoords(x:Int,y:Int)
      'Koordinaten einer Node festlegen
      self.x = x
      self.y = y
   End Method
   
End Type

'___________________________________________________________________________________________________

'Rem TESTCODE
   test:tmap = tmap.create(15,15,1)
   AppTitle="A* Demo V1.0 ~t~~BladeRunner~~"
   Graphics 640,480
   
   Repeat
      Local mx:Int = MouseX()
      Local my:Int = MouseY()
      mbl:Int = MouseHit(1)
      mbr:Int = MouseHit(2)
      If mbl Then
         test.setvalue(mx/30,my/30,0,1)
      EndIf
      If mbr Then
         test.setvalue(mx/30,my/30,0,0)
      EndIf
      
      ldraw:TList=Tnode.astar8(0,0,3,14,test,,,True)
      test.draw()
      TNode.draw(ldraw)
      DrawText GCMemAlloced(),500,460
      Flip
      Cls
   Until KeyHit(KEY_ESCAPE) Or AppTerminate()   
'EndRem

Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

Farbfinsternis

BeitragMo, Aug 07, 2006 8:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey, danke Bladerunner ... das muss ich mir mal genauer angucken.
Farbfinsternis.tv

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group