Wegfindung für "Pacman" -> Problem mit Berechnu

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

M0rgenstern

Betreff: Wegfindung für "Pacman" -> Problem mit Berechnu

BeitragDi, Apr 20, 2010 19:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey Leute.

Ich hab grade ein kleines Problem bei meinem Nebenprojekt.
Es ist im Prinzip Pacman, bisher nichts wirklich extras drin.

Es geht jetzt drum, meinen Geistern eine neue Richtung zu geben, wenn sie an eine Mauer stoßen.
Das Problem ist, dass sie sich pixelweise bewegen und deshalb hängen bleiben, sobald sie was anderen machen sollen, als sich hoch und runter zu bewegen.
Der Code fürs Bewegen der Geister sieht momentan so aus:

BlitzMax: [AUSKLAPPEN]
Method Move()
Local iTileX:Int = fx / itilesize
Local iTileY:Int = fy / itilesize
Local fnewX:Float = fx
Local fNewY:Float = fy
Local iSet:Int = 0

Local iTileX1:Int
Local iTileX2:Int
Local iTileY1:Int
Local iTIleY2:Int


Select iDirection
Case 1 'Hoch

fNewY = fy - fSpeed

iTileX1 = fx / iTilesize
iTileY1 = (fNewY - itilesize / 2) / iTilesize

If iGameMap[iTileX1, iTileY1, 1] = 0 Then
iSet = 1
fy = fNewY
EndIf



Case 2 'Runter

fNewY = fy + fSpeed

iTileX1 = fx / iTilesize
iTileY1 = (fNewY + itilesize / 2) / iTilesize

If iGameMap[iTileX1, iTileY1, 1] = 0 Then
iSet = 1
fy = fNewY
End If



Case 3 'Links

fx = fx - fSpeed

iTileY1 = fy / iTilesize
iTileX1 = (fnewX - itilesize / 2) / iTilesize

If iGameMap[iTileX1, iTileY1, 1] = 0 Then
iSet = 1
fx = fnewX
End If

Case 4 'Rechts

fx = fx + fSpeed

iTileY1 = fy / iTilesize
iTileX1 = (fnewX + itilesize / 2) / iTilesize

If iGameMap[iTileX1, iTileY1, 1] = 0 Then
iSet = 1
fx = fnewX
End If

End Select

If iSet = 0 Then
GetDirection()
End If

End Method


Und der Code für die Funktion GetDirection() sieht folgendermaßen aus:

BlitzMax: [AUSKLAPPEN]
Method GetDirection()
Local iOldDirection:Int = idirection
Local iTries:Int = 0
Local iNewDirection:Int = 0

If iDirection = 1 Then
iDirection = 2
ElseIf iDirection = 2 Then
iDirection = 3
ElseIf iDirection = 3 Then
iDirection = 4
ElseIf iDirection = 4 Then
iDirection = 1
EndIf



' Repeat
' iDirection = Rand(1, 4)
' iTries:+1
' If (iDirection <> iOldDirection) Then iNewDirection = 1
' Until ((iNewDirection = 1) Or (iTries > 20))
End Method


Der Geist bewegt isch am Anfang super nach unten.
Abe wenn er dann an die Wand unten kommt, dann bewegt er sich gar nicht mehr.

Kann mir bitte jemand sagen, wie ich das besser berechne?
Also, irgendwie ne Toleranz oder so einbaue, bzw was ich am besten da mache?

Lg, M0rgenstern

Midimaster

BeitragDi, Apr 20, 2010 20:53
Antworten mit Zitat
Benutzer-Profile anzeigen
tausch doch mal so durch:

BlitzMax: [AUSKLAPPEN]
		If iDirection = 1 Then
iDirection = 3
ElseIf iDirection = 2 Then
iDirection = 4
ElseIf iDirection = 3 Then
iDirection = 2
ElseIf iDirection = 4 Then
iDirection = 1
EndIf


dann biegt er an einer Wand immer um 90° ab.

Chrise

BeitragDi, Apr 20, 2010 20:56
Antworten mit Zitat
Benutzer-Profile anzeigen
BlitzMax: [AUSKLAPPEN]
Select iDirection
Case 1
iDirection=2
Case 2
iDirection=4
Case 3
iDirection=2
Case 4
iDirection=1
End Select


wäre es so nicht sogar noch effizienter und übersichtlicher? Wink
Llama 1 Llama 2 Llama 3
Vielen Dank an Pummelie, der mir auf seinem Server einen Platz für LlamaNet bietet.

M0rgenstern

BeitragDi, Apr 20, 2010 21:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Oh verdammt.
Da hab ich mich total vertan mit den Zahlen.
Danke dafür.
Tut mir echt leid.

Lg M0rgenstern

Edit: aber selbst wenn ich statt diesem code den auskommentierten code in getdirection benutze hängt der geist sich auf.
Da muss eher irgendwas bei der Kollisionsberechnung in der Methode Move sein.
Das meinte ich eigentlich.

Lg M0rgenstern.

Midimaster

BeitragMi, Apr 21, 2010 7:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Eigentlich müsste er wenigstens rückwärts wieder rauskönnen.


Beziehen sich deine Koordinaten Fx und Fy auf die Mitte deiner Spielfigur oder auf die linke obere Ecke?

Denn nur, wenn sie sich auf die Mitte beziehen, stimmt das mit dem jeweiligen Dazurechnen/Abziehen von iTileSize/2.

Möglicherweise ist ja seine 1. X-Position schon zu nahe an einer linken Wand. Da er ja aber abwärtsgeht, wird immer die Tile bei...
Zitat:
Fx, Fy+iTileSize/2

...geprüft. Dann dreht er und nun prüft er...
Zitat:
Fx -iTileSize/2, Fy

...und das reicht halt auch nicht mehr...

Aber was mich eben wundert, ist, dass er dann nicht wieder hochlaufen kann, denn hier gilt ja:
Zitat:
Fx, Fy-iTileSize/2

...und der Weg ist auf jeden Fall frei.


Bau doch mal ein paar DEBUGLOG ein, damit Du siehst, weshalb er hier nicht mehr weiterkommt:

BlitzMax: [AUSKLAPPEN]
Method GetDirection()
Local iOldDirection:Int = idirection
Local iTries:Int = 0
Local iNewDirection:Int = 0

DebugLog " Direction vorher" + iDirection

If iDirection = 1 Then
iDirection = 2
ElseIf iDirection = 2 Then
iDirection = 3
ElseIf iDirection = 3 Then
iDirection = 4
ElseIf iDirection = 4 Then
iDirection = 1
EndIf
DebugLog Felder um Spieler herum:
DebugLog " Ich=" + iGameMap[Fx/iTileSize, Fy/iTileSize, 1]

DebugLog " Oben=" + iGameMap[Fx/iTileSize, (Fy-fSpeed-iTileSize/2)/iTileSize, 1]
DebugLog " Unten=" + iGameMap[Fx/iTileSize, (Fy+fSpeed+iTileSize/2)/iTileSize, 1]
DebugLog " Links=" + iGameMap[(Fx-fSpeed-iTileSize/2)/iTileSize, Fy/iTileSize, 1]
DebugLog "Rechts=" + iGameMap[(Fx+fSpeed+iTileSize/2)/iTileSize, Fy/iTileSize, 1]

DebugLog " Direction nachher" + iDirection
End Method
  • Zuletzt bearbeitet von Midimaster am Do, Apr 22, 2010 15:39, insgesamt einmal bearbeitet

M0rgenstern

BeitragDo, Apr 22, 2010 13:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Hm,
Also das ist echt seltsam.
Ich hab die Sache mit dem Debuglog jetzt mal eingefügt und richtig abgeändert (Bei unten und Links muss es + itilesize/2 heißen).
Wird auch alles angezeigt.

Aber: Sobald er an eine Stelle kommt, wo er eine neue Richtung bekommen soll, bekommt er die noch zugeweisen, bewegt sich aber ab dann nicht mehr.
Also, es ist, als würde die der Befehl Move nicht mehr aufgerufen werden.
Denn er hängt nicht nur an der Stelle. Der Debuglog bleibt auch immer der gleiche.
Also, das ganze wird einmal angezeigt aber dann kommt nie mehr etwas hinzu.

Die Koordinaten des Gegner beziehen sich auf den BIldmittelpunkt.

Lg, M0rgenstern

Midimaster

BeitragDo, Apr 22, 2010 15:38
Antworten mit Zitat
Benutzer-Profile anzeigen
um sicher zu gehen, dass es nicht nurso aussieht als ob der DEBUGGER steht, fügst du eine Millisecs() an die letzte Debug-Zeile:

BlitzMax: [AUSKLAPPEN]
        DebugLog " Direction nachher" + iDirection + " bei Zeit=" + MilliSecs()



Danke für den Hinweis zu -iTileSize/2. Da hatte ich einen Tippfehler!


Welche Werte druckt er denn aus im Debugger, wenn er ganz unten angekommen ist?

Vielleicht sollten wir in die Debugger-Zeilen noch mehr Information packen:

BlitzMax: [AUSKLAPPEN]
        
locX%=Fx/iTileSize
locY%=(Fy-fSpeed-iTileSize/2)/iTileSize)
DebugLog " Oben bei (" + locX +"/" + locY + ")...Inhalt=" + iGameMap[locX, locY, 1]


...entsprechend auch für die anderen Zeilen....

würde dann sowas ergeben:

Zitat:
DEBUG: Oben bei (5,13)...Inhalt=1


Theoretisch müßten ja immer 3 Werte=0 sein und nur der nach unten wäre auf 1

mich würde jetzt dabei interessieren, ob er wirklich die richtigen Felder betrachtet. Ausgehend vom Spielerfeld in 4 Himmelsrichtungen.

M0rgenstern

BeitragDo, Apr 22, 2010 17:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Also.
Es werden immer die richtigen Felder betrachtet und es kommt im Debuglog nichts neues hinzu.
Das sieht man alleinschon, weil er nie länger wird. Und die Zeit ändert sich auch nie.

Hier der auszug:

Zitat:
DebugLog: Direction vorher 2 bei Zeit=1094531
DebugLog:Felder um Spieler herum:
DebugLog: Ich bei: (24/16)...Inhalt=0
DebugLog: Oben bei: (24/15)...Inhalt=0
DebugLog: Unten bei: (24/17)...Inhalt=1
DebugLog: Links bei: (23/16)...Inhalt=0
DebugLog:Rechts bei: (25/16)...Inhalt=1
DebugLog: Direction nachher: 3


Und dass rechts und unten belegt sind stimmt auch, denn der Geist steht in einer Ecke, also folgedermaßen:

Zitat:

|
G|
----


Ist jetzt vielleicht nicht so gut zu erkennen, aber ich hoffe, das Prinzip ist klar.
Kann auch nen Sreenshot von machen, wenn gewünscht.

Ich versteh das ganze wirklich nicht.

LG, M0rgenstern

ComNik

BeitragDo, Apr 22, 2010 17:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hab nicht alles gelesen,
aber du könntest in den Select Block je nach Richtung eine
kleine Positionsveränderung einfügen z.B bei einer Wand link ein paar Pixel nach rechts.
Wie gesagt, ich könnt mir vorstellen dass das hilft.

lg
ComNik
WIP: Vorx.Engine

M0rgenstern

BeitragDo, Apr 22, 2010 17:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Öhm, das hilf eher nicht, denn sobald er eine Kollision erkennt ruft er die Funktion GetDirection() auf. UNd genau in dieser ist die Sache mit dem Debuglog.
Das heißt, wenn es daran liegen würde, dass er irgendwo nicht wegkommt müsste diese Funktion öfter aufgerufen werden, was aber einfach nicht der Fall ist.

Lg, M0rgenstern

EDIT:
Okay, hab das Problem gelöst.
Hatte zwei Variablennamen in der Move() Methode noch auf der alten Version.
Deshalb hat er sich nicht bewegt.
Tut mir leid.

Vielen Dank für eure Hilfe.
Klappt jetzt.

Lg, M0rgenstern

Midimaster

BeitragDo, Apr 22, 2010 19:15
Antworten mit Zitat
Benutzer-Profile anzeigen
muss dir nicht leid tun...

wie biste jetzt draufgekommen?

haben die DEBUGLOGs dabei geholfen, dann kannst du sie zukünftig ja intensiver einsetzen.

M0rgenstern

BeitragDo, Apr 22, 2010 19:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Naja, ich bin dadruch drauf gekommen, dass er nichtmal versucht hat sich nach Links zu bewegen und hab dann mal nachgeguckt, ob ich da vielleicht irgendeinen Blödsinn stehen habe.

Bin Debuglogs grade schon bei nem anderen Prolbem seeehr intensiv am Nutzen und bekomme genau wegen denen Programmabstürze^^

Lg, M0rgenstern.

Vielen Dank nochmal.

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group