Tipp 0319
|
Path-Finder
|
 |
|
Autor/Einsender: Datum: |
|
Alexander Csadek 17.03.2003 |
|
Entwicklungsumgebung:
DirectX-Version: |
|
VB 6
DirectX 7 |
|
|
Mit einem Path-Finder kann man einem Spiel ein bisschen etwas von einer künstlichen Intelligenz geben. Er hilft dabei, Spielfiguren einen Weg zu einem bestimmten Ziel zu finden, egal wie viele Hindernisse dazwischen liegen. So ist ein Path-Finder sehr hilfreich, um einem Feind die Möglichkeit zu geben, den Weg zum Spieler auf dem Spielfeld zu finden, oder damit die Spielfiguren den Weg zu einem Zielpunkt von alleine zu finden.
|
Als erstes sucht der Path-Finder die Position von Start und Ziel. Natürlich muss man dies nicht machen, wenn beide Positionen schon bekannt sind, dann braucht man diese beiden Punkte nur zu setzen. Als nächstes prüft der Path-Finder, ob überhaupt ein Ziel- und Startpunkt existiert. Wenn eines von den beiden fehlt, gibt es auch keinen Pfad zu finden.
|
Ein Pfad-Array wird ausgefüllt, der Startpunkt bekommt 0, alle Hindernisse einen sehr hohen Wert, z.B. 999. Alle anderen, inkl. dem Zielpunkt, werden auf -1 gesetzt. Jetzt hat man ein Array in dem alle nicht begehbaren Felder (Hindernisse) den Wert 999, und alle begehbaren, inkl. dem Zielpunkt, den Wert -1
haben, der Startpunkt hat 0.
|
Der Path-Finder durchsucht im nächsten Schritt das Pfad-Array nach begehbaren Feldern und deren Nachbarschaft. Ist es begehbar und noch nicht markiert worden, dann wird es jetzt markiert. Die Nachbarfelder bekommen einen höheren Wert als das Ausgangsfeld. So haben dann z.B. alle Felder rund um den Startpunkt mit dem Wert 0 einen Wert von 1. Dies geschieht solange bis keine Felder mehr frei sind, also den Wert -1 haben.
|
Der Path-Finder geht den Weg nun mehr oder weniger zurück und schaut, welches Feld in der Nachbarschaft einen kleineren
Wert hat . Und zwar solange bis es das Ziel erreicht hat. Hat er das Ziel nicht erreicht, gibt es keinen Pfad.
|
|
|
Option Explicit
Sub Pathfinder()
Dim X As Integer, Y As Integer
Dim nX As Integer, nY As Integer
Dim ptStart As strcPoint
Dim ptZiel As strcPoint
Dim ptPunkt As strcPoint
Dim bolGefunden As Boolean
Dim LowValue As Integer
ptStart.X = -1
ptZiel.X = -1
For Y = 0 To MAPHEIGHT
For X = 0 To MAPWIDTH
If MAP(X, Y) = TileStart Then
ptStart.X = X
ptStart.Y = Y
End If
If MAP(X, Y) = TileZiel Then
ptZiel.X = X
ptZiel.Y = Y
End If
If MAP(X, Y) = TilePunkt Then MAP(X, Y) = TileLeer
Next X
Next Y
If ptStart.X = -1 Then
lbl_Pfad.Caption = "keinen Startpunkt gefunden !"
Exit Sub
End If
If ptZiel.X = -1 Then
lbl_Pfad.Caption = "keinen Zielpunkt gefunden !"
Exit Sub
End If
For Y = 0 To MAPHEIGHT
For X = 0 To MAPWIDTH
Select Case MAP(X, Y)
Case TileStart: Path(X, Y) = 0
Case TileBlock: Path(X, Y) = 999
Case TileLeer: Path(X, Y) = -1
Case Else: Path(X, Y) = -1
End Select
Next X
Next Y
Do
bolGefunden = False
For Y = 0 To MAPHEIGHT
For X = 0 To MAPWIDTH
MARK(X, Y) = False
If Path(X, Y) = -1 Then
For nY = Y - 1 To Y + 1
For nX = X - 1 To X + 1
If (nX >= 0 And nY >= 0) And _
(nX <= MAPWIDTH And nY <= MAPHEIGHT) And _
Not (nX = X And nY = Y) Then
If Path(nX, nY) >= 0 And Path(nX, nY) <> 999 Then
MARK(X, Y) = True
bolGefunden = True
End If
End If
Next nX
Next nY
End If
Next X
Next Y
For Y = 0 To MAPHEIGHT
For X = 0 To MAPWIDTH
If MARK(X, Y) Then
LowValue = 999
For nY = Y - 1 To Y + 1
For nX = X - 1 To X + 1
If (nX >= 0 And nY >= 0) And _
(nX <= MAPWIDTH And nY <= MAPHEIGHT) Then
If Path(nX, nY) >= 0 Then
If Path(nX, nY) < LowValue Then _
LowValue = Path(nX, nY)
End If
End If
Next nX
Next nY
Path(X, Y) = LowValue + 1
End If
Next X
Next Y
Loop While bolGefunden
If Path(ptZiel.X, ptZiel.Y) <> -1 Then
ptPunkt = ptZiel
LowValue = Path(ptZiel.X, ptZiel.Y)
Do While LowValue > 0
bolGefunden = False
Do
Do
nX = Rnd() * 2 - 1
nY = Rnd() * 2 - 1
Loop While ((nX = 0 And nY = 0) Or _
(ptPunkt.X + nX) < 0 Or _
(ptPunkt.X + nX) > MAPWIDTH Or _
(ptPunkt.Y + nY) < 0 Or _
(ptPunkt.Y + nY) > MAPHEIGHT)
If Path(ptPunkt.X + nX, ptPunkt.Y + nY) < LowValue Then
bolGefunden = True
MAP(ptPunkt.X, ptPunkt.Y) = TilePunkt
ptPunkt.X = ptPunkt.X + nX
ptPunkt.Y = ptPunkt.Y + nY
LowValue = Path(ptPunkt.X, ptPunkt.Y)
End If
Loop While Not bolGefunden
Loop
MAP(ptZiel.X, ptZiel.Y) = TileZiel
lbl_Pfad.Caption = "Pfad gefunden !"
Else
lbl_Pfad.Caption = "Keinen Pfad gefunden !"
End If
End Sub
|
|
|
|
Im Code-Ausschnitt ist nur die Path-Finder-Routine dargestellt, die auch
ohne
DirectX verwendet werden kann.
|
Um dieses Beispiel ausführen zu können, wird die DirectX 7
for Visual Basic Type Library
benötigt (siehe dazu die Erläuterungen in der DirectX-Rubrik).
|
|
Windows-Version |
95 |
 |
|
98/SE |
 |
|
ME |
 |
|
NT |
 |
|
2000 |
 |
|
XP |
 |
|
Vista |
 |
|
Win
7 |
 |
|
|
VB-Version |
VBA 5 |
 |
|
VBA 6 |
 |
|
VB 4/16 |
 |
|
VB 4/32 |
 |
|
VB 5 |
 |
|
VB 6 |
 |
|
|
|
Download (7,3 kB)
|
Downloads bisher: [ 1345 ]
|
|
|