Fehler in Code (KI-Navigation)

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

Firstdeathmaker

Betreff: Fehler in Code (KI-Navigation)

BeitragMi, Dez 22, 2004 0:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich finde den Fehler einfach nicht. Wenn ihr den Code mal ausprobiert, genau mit diesen Parametern, dann werdet ihr feststellen das das "Raumschiff" irgendwann nur noch Schlangenlinien fliegt und nicht mehr auf die Navigationspunkte zu. Ich weis einfach nicht woran das liegen kann...



Code: [AUSKLAPPEN]
;Code by Christian Geißler

SCREEN_X=800
SCREEN_Y=600
Graphics SCREEN_X,SCREEN_Y,16,2
SetBuffer BackBuffer()

Type nav_point
Field x
Field y
Field action;0=ende, 1= next point, 2= Single Point Target
End Type

Type ship
Field x#
Field y#
Field winkel#
Field max_turn#
Field speed#
Field nav_point.nav_point
Field nav_x
Field nav_y
Field auto_route
End Type

ship.ship=New ship
ship\x#=SCREEN_X/2
ship\y#=SCREEN_Y/2
ship\winkel#=0
ship\max_turn#=5.9
ship\speed#=3.5
ship\auto_route=1


ship\nav_point.nav_point=New nav_point
ship\nav_point\x=SCREEN_X/2
ship\nav_point\y=50
ship\nav_point\action=1

tmp.nav_point=New nav_point
tmp\x=600
tmp\y=300
tmp\action=1

For i=0 To 10
tmp.nav_point=New nav_point
tmp\x=Rand(0,SCREEN_X)
tmp\y=Rand(0,SCREEN_Y)
tmp\action=1
Next

tmp.nav_point=New nav_point
tmp\x=100
tmp\y=100
tmp\action=0


Repeat
Cls

For ship.ship=Each ship

If ship\nav_point<>Null


   dif_x=ship\nav_point\x-ship\x
   dif_y=ship\nav_point\y-ship\y
   
   ziel#=ATan2(dif_y,dif_x)
   
   Text 10,50,ship\winkel-ziel
   Text 10,60,ziel
   
   aenderung#=ship\winkel-ziel
   
   If aenderung>ship\max_turn
      aenderung=ship\max_turn
   ElseIf aenderung<-ship\max_turn
      aenderung=-ship\max_turn
   EndIf

   
   
   ship\winkel=ship\winkel-aenderung

   
   
   ship\x=ship\x+(Cos(ship\winkel)*ship\speed)
   ship\y=ship\y+(Sin(ship\winkel)*ship\speed)
   
   
   

   If ship\x<ship\nav_point\x+1 And ship\x>ship\nav_point\x-1
      If ship\y<ship\nav_point\y+1 And ship\y>ship\nav_point\y-1
         Select ship\nav_point\action
            Case 1
               ship\nav_point=After ship\nav_point
            Case 0
               ship\nav_point=Null
         End Select
      EndIf
   EndIf
   

      



EndIf
      
      Text 10,30,Int(ship\x)+"/"+Int(ship\y)
      
      Rect ship\x,ship\y,5,5
      
            
Next

For tmp.nav_point=Each nav_point
   Rect tmp\x,tmp\y,1,1
Next
Flip


Until KeyHit(1)
End
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon
Gewinner des BCC #57 User posted image
 

noir

BeitragMi, Dez 22, 2004 0:35
Antworten mit Zitat
Benutzer-Profile anzeigen
schreib ma was dein fliegender punkt genau machen sollte, wenn es ginge, denn ich habe jedenfalls keine lust herauszufinden was du eigentlich machen möchtest..

Firstdeathmaker

BeitragMi, Dez 22, 2004 0:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Der fliegende Punkt soll die anderen Punkte abgrasen, die in seiner Navigationsschleife liegen (also alle .nav_punkt), wobei er einen bestimmten Mindestwenderadius besitzt.
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon
Gewinner des BCC #57 User posted image

Ctuchik

BeitragMi, Dez 22, 2004 1:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Das Schiff hat manchmal den Weg nicht gefunden, weil es sich in die falsche Richtung gedreht hat! Hab das jetzt einfach mal umgeschrieben, es geht jetzt, obwohl ich keine Ahnung hab, was ich da eigentlich gemacht hab Very Happy Falls es sich anders besser lösen lässt möge jemand bescheid sagen! Wink

Code: [AUSKLAPPEN]

;Code by Christian Geißler

SCREEN_X=800
SCREEN_Y=600
Graphics SCREEN_X,SCREEN_Y,16,2
SetBuffer BackBuffer()

Type nav_point
Field x
Field y
Field action;0=ende, 1= next point, 2= Single Point Target
End Type

Type ship
Field x#
Field y#
Field winkel#
Field max_turn#
Field speed#
Field nav_point.nav_point
Field nav_x
Field nav_y
Field auto_route
End Type

ship.ship=New ship
ship\x#=SCREEN_X/2
ship\y#=SCREEN_Y/2
ship\winkel#=0
ship\max_turn#=5.9
ship\speed#=3.5
ship\auto_route=1


ship\nav_point.nav_point=New nav_point
ship\nav_point\x=SCREEN_X/2
ship\nav_point\y=50
ship\nav_point\action=1

tmp.nav_point=New nav_point
tmp\x=600
tmp\y=300
tmp\action=1

For i=0 To 10
tmp.nav_point=New nav_point
tmp\x=Rand(0,SCREEN_X)
tmp\y=Rand(0,SCREEN_Y)
tmp\action=1
Next

tmp.nav_point=New nav_point
tmp\x=100
tmp\y=100
tmp\action=0


Repeat
Cls


For ship.ship=Each ship

If ship\nav_point<>Null


dif_x=ship\nav_point\x-ship\x
dif_y=ship\nav_point\y-ship\y

ziel#=ATan2(dif_y,dif_x)

Text 10,50,ship\winkel-ziel
Text 10,60,ziel

aenderung#=ship\winkel-ziel                             ;Hier wurden Änderungen vorgenommen, damit das Schiff immer den richtigen Weg findet!
If aenderung# > 180 Or aenderung# < -180
aenderung# = (aenderung# + 360) Mod 180
End If

If Abs(aenderung#) > ship\max_turn#
  aenderung# = ship\max_turn# * Sgn(aenderung#)
End If

ship\winkel=ship\winkel-aenderung

ship\x=ship\x+(Cos(ship\winkel)*ship\speed)
ship\y=ship\y+(Sin(ship\winkel)*ship\speed)

dist = (ship\x - ship\nav_point\x)*(ship\x - ship\nav_point\x)+(ship\y - ship\nav_point\y)*(ship\y - ship\nav_point\y)
If dist <= 9 ;Hier wurde eine größere Toleranz für das Treffen des Wegpunktes eingestellt, sonst ist es zu oft vorbeigeflogen! Der Abstand ist quadriert, also momentan 3 pixel maximale Entfernung vom Wegpunkt, damit er aktiviert wird!
Select ship\nav_point\action
Case 1
ship\nav_point=After ship\nav_point.navpoint
Case 0
ship\nav_point=Null
End Select
EndIf

EndIf

Text 10,30,Int(ship\x)+"/"+Int(ship\y)
Rect ship\x,ship\y,5,5

Next

For tmp.nav_point=Each nav_point
Rect tmp\x,tmp\y,1,1
Next
Flip

Until KeyHit(1)
End
Zu den Nebenwirkungen gehören trockener Mund, Übelkeit, Erbrechen, Harnstau, schmerzhafter rektaler Juckreiz, Halluzinationen, Demenz, Psychose, Koma, Tod und Mundgeruch!
Magie eignet sich nicht für alle!
Fraget euren Arzt oder Apotheker!

Firstdeathmaker

BeitragMi, Dez 22, 2004 8:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok, funktioniert (und ich kapiere auch warum: Warscheinlich war der minimalradius zu groß um in die 2-Breite Zone zu kommen die ich definiert hatte als genügend genau zu sein um das Ziel zu treffen. Naja, vielen Dank!


edit: Ist immer noch ein Fehler drin. Ich hab mal mehrere Punkte erstellt um zu testen ob das auch im Dauerbetrieb funktioniert, aber irgendwann geht der nur noch in y-Richtung weiter:

Code: [AUSKLAPPEN]
;Code by Christian Geißler

SCREEN_X=800
SCREEN_Y=600
Graphics SCREEN_X,SCREEN_Y,16,2
SetBuffer BackBuffer()

Type nav_point
Field x
Field y
Field action;0=ende, 1= next point, 2= Single Point Target
End Type

Type ship
Field x#
Field y#
Field winkel#
Field max_turn#
Field speed#
Field nav_point.nav_point
Field nav_x
Field nav_y
Field auto_route
End Type

ship.ship=New ship
ship\x#=SCREEN_X/2
ship\y#=SCREEN_Y/2
ship\winkel#=0
ship\max_turn#=7.9
ship\speed#=10.5
ship\auto_route=1


ship\nav_point.nav_point=New nav_point
ship\nav_point\x=SCREEN_X/2
ship\nav_point\y=50
ship\nav_point\action=1

tmp.nav_point=New nav_point
tmp\x=600
tmp\y=300
tmp\action=1

For i=0 To 100
tmp.nav_point=New nav_point
tmp\x=Rand(0,SCREEN_X)
tmp\y=Rand(0,SCREEN_Y)
tmp\action=1
Next

tmp.nav_point=New nav_point
tmp\x=100
tmp\y=100
tmp\action=0


Repeat
Cls


For ship.ship=Each ship

If ship\nav_point<>Null


dif_x=ship\nav_point\x-ship\x
dif_y=ship\nav_point\y-ship\y

ziel#=ATan2(dif_y,dif_x)

Text 10,50,ship\winkel-ziel
Text 10,60,ziel

aenderung#=ship\winkel-ziel ;Hier wurden Änderungen vorgenommen, damit das Schiff immer den richtigen Weg findet!
If aenderung# > 180 Or aenderung# < -180
aenderung# = (aenderung# + 360) Mod 180
End If

If Abs(aenderung#) > ship\max_turn#
aenderung# = ship\max_turn# * Sgn(aenderung#)
End If

ship\winkel=ship\winkel-aenderung

ship\x=ship\x+(Cos(ship\winkel)*ship\speed)
ship\y=ship\y+(Sin(ship\winkel)*ship\speed)

dist = (ship\x - ship\nav_point\x)*(ship\x - ship\nav_point\x)+(ship\y - ship\nav_point\y)*(ship\y - ship\nav_point\y)
If dist <= ship\max_turn ;Hier wurde eine größere Toleranz für das Treffen des Wegpunktes eingestellt, sonst ist es zu oft vorbeigeflogen! Der Abstand ist quadriert, also momentan 3 pixel maximale Entfernung vom Wegpunkt, damit er aktiviert wird!
Select ship\nav_point\action
Case 1
ship\nav_point=After ship\nav_point.navpoint
Case 0
ship\nav_point=Null
End Select
EndIf

EndIf

Text 10,30,Int(ship\x)+"/"+Int(ship\y)
Rect ship\x,ship\y,5,5

Next

For tmp.nav_point=Each nav_point
Rect tmp\x,tmp\y,1,1
Next
Flip

Until KeyHit(1)
End
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon
Gewinner des BCC #57 User posted image

Ctuchik

BeitragMi, Dez 22, 2004 16:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok, ich bin das Problem nochmal durch nachdenken angegangen und hab die Lösung gefunden, jetzt sollte es hoffentlich immer funktionieren:

Code: [AUSKLAPPEN]

;Code by Christian Geißler

SCREEN_X=800
SCREEN_Y=600
Graphics SCREEN_X,SCREEN_Y,16,2
SetBuffer BackBuffer()

Type nav_point
Field x
Field y
Field action;0=ende, 1= next point, 2= Single Point Target
End Type

Type ship
Field x#
Field y#
Field winkel#
Field max_turn#
Field speed#
Field nav_point.nav_point
Field nav_detect_stuck[3]
Field nav_shipturning
Field nav_x
Field nav_y
Field auto_route
End Type

ship.ship=New ship
ship\x#=SCREEN_X/2
ship\y#=SCREEN_Y/2
ship\winkel#=0
ship\max_turn#=7.9
ship\speed#=10.5
ship\auto_route=1
ship\nav_shipturning = 0

ship\nav_point.nav_point=New nav_point
ship\nav_point\x=SCREEN_X/2
ship\nav_point\y=50
ship\nav_point\action=1

tmp.nav_point=New nav_point
tmp\x=600
tmp\y=300
tmp\action=1

For i=0 To 100
tmp.nav_point=New nav_point
tmp\x=Rand(0,SCREEN_X)
tmp\y=Rand(0,SCREEN_Y)
tmp\action=1
Next

tmp.nav_point=New nav_point
tmp\x=100
tmp\y=100
tmp\action=0

Repeat
Cls


For ship.ship=Each ship

If ship\nav_point<>Null

If KeyHit(57) Then Stop

If ship\nav_shipturning Then

dif_x=ship\nav_point\x-ship\x
dif_y=ship\y-ship\nav_point\y

ziel#=ATan2(dif_y,dif_x) ;Ziel Winkel: -180 bis 180 Grad
If (ziel > 0 And ziel < 90) Then ship\nav_detect_stuck[0] = 1
If (ziel > 90) Then ship\nav_detect_stuck[1] = 1
If (ziel > -90 And ziel < 0) Then ship\nav_detect_stuck[2] = 1
If (ziel < -90) Then ship\nav_detect_stuck[3] = 1

aenderung#=ship\winkel-ziel
If aenderung# > 180 Or aenderung# < -180
aenderung# = (360 - Abs(aenderung#)) * Sgn(aenderung#) * -1
End If

If Abs(aenderung#) > ship\max_turn#
aenderung# = ship\max_turn# * Sgn(aenderung#)
End If

ship\winkel=ship\winkel-aenderung
If (ship\winkel + 180) > 360
  ship\winkel = ((ship\winkel + 180) Mod 360) - 180
ElseIf (ship\winkel -180) <= -360
  ship\winkel = ((ship\winkel - 180) Mod 360) + 180
End If

End If

ship\x=ship\x+(Cos(ship\winkel)*ship\speed)
ship\y=ship\y-(Sin(ship\winkel)*ship\speed)

dist = (ship\x - ship\nav_point\x)^2+(ship\y - ship\nav_point\y)^2
If dist <= (ship\speed^2 / 4)
  Select ship\nav_point\action
  Case 1
  ship\nav_point=After ship\nav_point.navpoint
  Case 0
  ship\nav_point=Null
  End Select
  For a=0 To 3
    ship\nav_detect_stuck[a] = 0
  Next
  ship\nav_shipturning = True
Else
  stuck = 1
  For a=0 To 3
    If (ship\nav_detect_stuck[a] = 0) Then stuck = 0
  Next
  If stuck Then
    ship\nav_shipturning = False
    For a=0 To 3
      ship\nav_detect_stuck[a] = 0
    Next
  End If
  If dist > 50000 Then ship\nav_shipturning = True
EndIf


EndIf

Text 10,30,Int(ship\x)+"/"+Int(ship\y)
Text 10,70,ship\winkel
Text 10,60,ziel
Rect ship\x,ship\y,5,5

Next

For tmp.nav_point=Each nav_point
Rect tmp\x,tmp\y,1,1
Next
Flip

Until KeyHit(1)
End


Folgendes zu diesem Code:
- Wenn der Zielwinkel z.B. 170 und der Schiffwinkel -170 ist wird jetzt korrekt erkannt in welche Richtung sich das Schiff drehen muss!
- Der Winkel des Schiffs wird immer auf einen Wert zwischen -179,999 und +180 gesetzt, damit obiges richtig funktioniert!
- Mir ist aufgefallen, dass das Schiff manchmal, um einen Punkt im Kreis geflogen ist, weil es sich nicht stark genug drehen konnte und dann am Zeil vorbeischoss! Um das zu verhindern wurden zwei neue Variablen eingefügt:
1. ship\nav_detect_stuck[3] (Ein Array, mit 4 Feldern) : Darin wird anhand der Winkel des Schiffs zum Zielpunkt überprüft, ob das Schiff in eine Schleife geraten ist und immer um den Punkt kreist!
2. ship\nav_shipturning (Werte: True oder False) : Gibt an, ob das Schiff sich drehen darf oder nicht, wenn es erkennt dass es um einen Punkt kreist, dann wird nav_shipturning auf True gesetzt und das Schiff fliegt wieder ein Stück geradeaus vom Punkt weg (bis auf 500 Pixel abstand), um ihn mit einem neuen Winkel wieder anfliegen zu können!

edit:: Wenn man Leertaste drückt hab ich ein Stop eingebaut, das kannst du wieder rausschmeissen, war nur aus Gründen der Fehlersuche!

edit2: Mann, ich seh grad, dass ich da fast ne dreiveirtelstunde dran saß Very Happy
Zu den Nebenwirkungen gehören trockener Mund, Übelkeit, Erbrechen, Harnstau, schmerzhafter rektaler Juckreiz, Halluzinationen, Demenz, Psychose, Koma, Tod und Mundgeruch!
Magie eignet sich nicht für alle!
Fraget euren Arzt oder Apotheker!

Firstdeathmaker

BeitragMi, Dez 22, 2004 20:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Vielen vielen Dank!

Endlich funktioniert es! Very Happy
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon
Gewinner des BCC #57 User posted image

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group