Wegpunkte speichern... Warum geht das nicht?

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

M0rgenstern

Betreff: Wegpunkte speichern... Warum geht das nicht?

BeitragMi, Mai 05, 2010 18:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey Leute.

Ich habe gestern Abend schon meine Wegpunkte erweitert. Es gibt jetzt einen Typen mehr.
Ich kann das ganze auch schon im Mapeditor nutzen und die Map auch abspeichern.
Das speichern funktioniert auch ohne Probleme.
Nur wenn ich eine Map laden will erhalte ich folgenden Fehler:

Zitat:
Unhandled Exception:Error reading from stream


Eine Zeile dazu wird mir aber nicht gezeigt, da er noch weitere Fehlermeldungen bringt, dass irgendein original Source Code fehlen würde.

Ich weiß, dass dieser Fehler im Prinzip bedeutet, dass er versucht irgendwas aus einer Datei zu lesen, was aber nicht vorhanden ist.
Wenn ich nur die normalen Waypoints in der Map habe, dann kommt der Fehler nicht. Sobald ich aber einen oder mehrere dieser neuen Waypoints einfüge erscheint diese Fehlermeldung beim laden.
Das speichern funktioniert nach wie vor.

Mein Code erscheint mir total logisch.
An den Stellen an denen ich Casten muss tue ich es und dort wo es meiner Meinung nach nicht nötig ist, lasse ich es.
Ich verstehe nicht, warum er Probleme hat die Datei auszulesen.

Hier hab ich mal den Code der die Wegpunkte speichert:

BlitzMax: [AUSKLAPPEN]
	'Anzahl der Wegpunkte, die kein Startpunkt sind:
Local iAmount:Int = 0

For Local WP:TWaypoint = EachIn TWaypoint.TLAllWaypoints
If Not TStartpoint(WP) Then
iAmount:+1 'Ja, würde auch über .Count() funktionieren, habs von vorher übernommen
EndIf
Next

WriteInt Datei, iAmount 'ind Datei schreiben

'Alle Wegpunktdaten die dazu gehören in die Datei schreiben:
For Local WP:TWaypoint = EachIn TWaypoint.TLAllWaypoints
If Not TStartpoint(WP) Then
WriteInt Datei, WP.iX
WriteInt Datei, WP.iy
WriteInt Datei, WP.id
EndIf
Next

'Die Startpunkte zählen:
iAmount = 0

For Local WP:TWaypoint = EachIn TWaypoint.TLAllWaypoints
If TStartpoint(WP) Then
iAmount:+1
EndIf
Next

WriteInt Datei, iAmount 'In Datei schreiben
Local StartP:TStartpoint

'Alle Startpunktdaten in Datei schreiben:
For Local WP:TWaypoint = EachIn TWaypoint.TLAllWaypoints
If TStartpoint(WP) Then
StartP = TStartpoint(WP) 'Objekt casten
WriteInt Datei, StartP.iX
WriteInt Datei, StartP.iy
WriteInt Datei, StartP.iwavetime
WriteInt Datei, StartP.iEnemyamount
WriteInt Datei, StartP.iWaveamount
WriteInt Datei, StartP.id
EndIf
Next


'Die Verbindungen aller Wegpunkte durchgehen und speichern
'Hier ist es egal, ob es ein Startpunkt oder Wegpunkt ist, das ist für alle gleich
For Local WP:TWaypoint = EachIn TWaypoint.TLAllWaypoints

'Erst die Anzahl der verbundenen Wegpunkte zählen:
WriteInt Datei, wp.id
Local iConnAmount:Int = 0

For Local WPConn:TWaypoint = EachIn WP.tlConnected
iConnAmount:+1
Next

WriteInt Datei, iConnAmount 'in Datei schreiben

'Dann die ID von jedem Wegpunkt der verbunden ist in die Datei schreiben
For Local WPConn:TWaypoint = EachIn WP.tlConnected
WriteInt Datei, WPConn.id
Next

Next


Und hier ist der Code der sie laden sollte:

BlitzMax: [AUSKLAPPEN]
'Anzahl der Wegpunkte auslesen:
Local iAmountWP:Int = ReadInt(Datei)

'So viele Wegpunkte wie angegeben erstellen:
For Local index:Int = 0 Until iAmountWP
Local ix:Int = ReadInt(Datei)
Local iy:Int = ReadInt(Datei)
Local iID:Int = ReadInt(datei)
TWaypoint.Create(iX, iy, iID)
Next

'Anzahl der Startpunkte auslesen:
iAmountWP = ReadInt(Datei)

'So viele Startpunkte wie angegeben erstellen
For Local index:Int = 0 Until iamountwp
Local ix:Int = ReadInt(Datei)
Local iy:Int = ReadInt(Datei)
Local pwavetime:Int = ReadInt(Datei)
Local penemyamount:Int = ReadInt(Datei)
Local pwaveamount:Int = ReadInt(Datei)
Local pid:Int = ReadInt(Datei)
TStartpoint.CreateMe(ix, iy, pwavetime, penemyamount, pwaveamount, pid)
Next

'Verbundene Wegpunkte in die Listen einfügen
For Local WP:TWaypoint = EachIn TWaypoint.TLAllWaypoints

Local wpID:Int = ReadInt(Datei) 'ID Des Wegpunktes auslesen
Local iConnAm:Int

'Wenn der Wegpunkt die ausgelesene ID hat
If wp.ID = wpid Then
iConnAm = ReadInt(Datei)'Anzahl der verbundenen Wegpunkte auslesen
End If

'Anzahl der verbundenen Wegpunkte durchgehen:
For Local index:Int = 0 Until iConnAm
Local ID:Int = ReadInt(Datei) 'ID des verbundenen Wegpunktes auslesen

'Jeden wegpunkt durchgehen:
For Local WPCon:TWaypoint = EachIn TWaypoint.TLAllWaypoints

If WPCon.ID = ID Then WP.tlConnected.AddLast(WPCon) 'Wenn die ID
'dieses Wegpunkts gleich der ausgelesenen ist, ihn in die Liste einfügen

Next
Next

Next


Kleine Anmerkung zu den Wegpunkten: Jeder wegpunkt hat als Attribut eine Liste in der die Referenz auf alle Wegpunkte gespeichert ist, die mit diesem verbunden sind.

Bitte helft mir, ich versteh nicht, warum das nicht geht.

Lg, M0rgenstern

Midimaster

BeitragMi, Mai 05, 2010 23:11
Antworten mit Zitat
Benutzer-Profile anzeigen
als erstes solltest du herausfinden, zu welchem Zeitpunkt der Fehler auftritt.

Ich würde auf jeden Fall einen ganzen Stapel DebugLogs einfügen.

Geh dabei systematsich vor und füge zunächst einige...

PRINT "Codepunkt xyz erreicht"

... zwischen die Codeblöcke der Laderoutine ein.


Wenn dann eine dieser Meldungen nicht mehr erscheint, weisst du, in welchem Block das Prpblem auftritt. Dann fügst Du dort einige weitere PRINTs ein. Beispiel:

BlitzMax: [AUSKLAPPEN]
	'Verbundene Wegpunkte in die Listen einfügen	
For Local WP:TWaypoint = EachIn TWaypoint.TLAllWaypoints

Local wpID:Int = ReadInt(Datei) 'ID Des Wegpunktes auslesen
Local iConnAm:Int

Print " Wegpunkt ID " + wpID + "gefunden"

'Wenn der Wegpunkt die ausgelesene ID hat
If wp.ID = wpid Then
iConnAm = ReadInt(Datei)'Anzahl der verbundenen Wegpunkte auslesen
End If

'Anzahl der verbundenen Wegpunkte durchgehen:
For Local index:Int = 0 Until iConnAm
Local ID:Int = ReadInt(Datei) 'ID des verbundenen Wegpunktes auslesen
Print " verbundene Wegpunkt ID " + ID + "gefunden"

'Jeden wegpunkt durchgehen:
For Local WPCon:TWaypoint = EachIn TWaypoint.TLAllWaypoints



u.s.w.

Alfadur

BeitragDo, Mai 06, 2010 5:53
Antworten mit Zitat
Benutzer-Profile anzeigen
Also, was der Fehler sagt, ist ja das er aus dem Stream nix mehr lesen kann, weil Ende und Aus! Also speicherst du scheinbar weniger als du einliest...
Ich hab jetzt mal nur kurz drübergeschaut, aber wenn du z.B. 0 Startpunkte hast, und die 0 einspeicherst... und er die 0 läd...dann macht er eine for schleife von 0 bis 0 ... und da wird wenigstens einmal gelesen ...

Code: [AUSKLAPPEN]

For Local i:Int = 0 To 0
   DebugLog "hello"
Next


...geschrieben hast du aber vermutlich nix.


Midimaster hat schon recht... ich würde mir JEDEN Wert den du ausliest per debuglog anzeigen lassen und schauen ob er dem entspricht was ich erwarte. Deshalb vllt erstmal nich mit dem kompletten System testen, sondern mit ein oder zwei Wegpunkten und dann echt jeden Wert anschauen... so wirds was!
A Cray is the only computer that runs an endless loop in less than four hours.

M0rgenstern

BeitragDo, Mai 06, 2010 13:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey, danke.
Hat schon viel geholfen.
Hab jetzt den Übeltäter entlarvt:
Die Anzahl der "normalen" Wegpunkte speichert er richtig ab (in diesem Falle 0).
Aber die Anzahl der Startpunkte ermittelt er falsch.

Ich hab das ganze extra mal in den Editor selbst eingefügt.

Wenn ich folgenden Code benutze, um die Startpunkte zu zählen, dann zeigt er mir immer zwei mehr an als es eigentlich sind:
Code: [AUSKLAPPEN]
Local iAmount:Int = 0

For Local WP:Twaypoint = EachIn twaypoint.tlallwaypoints
      If Tstartpoint(WP) Then
         iAmount:+1
      End If
   Next

   DrawText("Anzahl Startpunkte: " + iAmount, 30, 70)


Foglender Code für die normalen Waypoints jedoch funktioniert problemlos:

BlitzMax: [AUSKLAPPEN]
Local iamount2:Int = 0

For Local WP:Twaypoint = EachIn twaypoint.tlallwaypoints
If Not Tstartpoint(WP) Then
iamount2:+1
EndIf
Next
DrawText("Anzahl Wegpunkte: " + iamount2, 30, 90)


Jetzt stellt sich mir die Frage: Warum bekomme ich, selbst wenn ich wirklich nur einen einzigen Startpunkt und sonst keine (auch keine Wegpunkte) auf der Karte habe, immer angezeigt es wären 2 Startpunkte vorhanden?

Mach ich das mit dem Casten etwa falsch?

Lg, M0rgenstern

mpmxyz

BeitragDo, Mai 06, 2010 18:42
Antworten mit Zitat
Benutzer-Profile anzeigen
@Alfadur
Es gibt in BlitzMax "Until" als Alternative zu "To". Im Gegensatz zu "To", zählt "Until" nicht bis einschließlich des Endes weiter, sondern hört vor dem Erreichen des Endes auf.

Wie viele Einträge hat TWaypoint.TLAllWaypoints?
Lasse dir mal mit Hilfe von Debugmethoden eine detailierte Liste der Einträge von dieser Liste ausgeben.
Eventuell stimmt dort etwas nicht.
Gehe mal das Programm Schritt für Schritt durch. (DebugStop)
Der Fehler scheint ziemlich tief zu sitzen; sonst wäre er schon gefunden.

mfG
mpmxyz
P.S.: Ich konnte dir gestern nicht antworten, da ich etwas beschäftigt war.
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

robotx

BeitragDo, Mai 06, 2010 19:25
Antworten mit Zitat
Benutzer-Profile anzeigen
EDIT: Ok, alles Quatsch von mir, siehe Post unten von mpmxyz.

In der Ladefunktion verwendest du die falsche Zählvariable, sodass die Schleife immer einmal zu viel einliest.
Du speicherst z.B. 3 Wegpunkte. Beim Laden zählst du aber von
Code: [AUSKLAPPEN]
For Local index:Int = 0 Until iAmountWP
wobei iAmountWP ja 3 ist.
Das sind also von 0 bis 3 -> 4 Schleifendurchgänge, obwohl nur drei in der Datei stehen.
Da du bei normalen Waypoints 0 hast, fällt der Fehler dort nicht direkt auf, ist jedoch auch vorhanden.


Und wieder hat robotx was neues gelernt Smile
  • Zuletzt bearbeitet von robotx am Do, Mai 06, 2010 19:39, insgesamt einmal bearbeitet

mpmxyz

BeitragDo, Mai 06, 2010 19:30
Antworten mit Zitat
Benutzer-Profile anzeigen
So... Zum zweitem Mal:
In BlitzMax gibt es nicht nur "To" sondern auch "Until".
Durch "Until" wird vor dem Erreichen des Ende-Wertes die Schleife beendet. (0 Until 3 >> 0,1,2 und keine 3)
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

M0rgenstern

BeitragDo, Mai 06, 2010 19:39
Antworten mit Zitat
Benutzer-Profile anzeigen
@ RobotX:

Eigentlich müsste der Fehler den du beschreibst auch bei den Waypoints dann auftreten.
Denn dann würde er pro Schleifendurchlauf mindestens einmal versuchen Daten zu lesen, die nicht vorhanden sind.
Außerdem: Da steht until. Und Afaik wären das dann genau 3 Schleifendurchgänge, wenn iAmountWp = 3 ist.
Deshalb nutze ich ja das Until.

Wegen dem Problem:
Ich habe jetztmal folgenden Code eingefügt in den Editor:

BlitzMax: [AUSKLAPPEN]
Local iAmount3:Int = 0
For Local WP:TWaypoint = EachIn TWaypoint.tlallwaypoints
iAmount3:+1
Next
DrawText("Anzahl Waypoints (Gesamt): " + iAmount3, 30, 110)


Und tatsächlich: Auch dort werden die Startpunkte doppelt gezählt.

Ich hab mir als ich das gesehen habe gedacht, dass das fast so aussieht, als würde der Startpunkt zweimal in die Liste eingefügt werden, was ja eigentlich nicht sein dürfte.
Hab dann mal in der Klasse nachgeguckt und mir ist folgendes aufgefallen:

Ich habe in der Parentklasse (Twaypoint) folgende Funktion:

BlitzMax: [AUSKLAPPEN]
Method New()
TLAllWaypoints.AddLast(Self)
End Method


Die Liste TLAllWaypoints ist global sowohl für Wegpunkte als auch für Startpunkte.

In der Klasse TStartpoint (Extended von TWaypoint) habe ich wieder folgende Funktion:

BlitzMax: [AUSKLAPPEN]
	Method New()
TLAllWaypoints.AddLast(Self)
End Method


UNd im "Konstruktor der Startpointklasse steht zu Beginn folgendes:

BlitzMax: [AUSKLAPPEN]
Function CreateMe:TStartpoint(px:Int, py:Int, pWavetime:Int, pEnemyamount:Int, pwaveamount:Int, pID:Int = 0)
Local Wayp:TStartpoint = New TStartpoint


Also scheint er die Methode New() zweimal aufzurufen für einen Startpunkt.
Ich habe die Newmethode jetzt mal aus der Startpoint Klasse auskommentiert. Jetzt werden die Punkte auch nicht mehr doppelt gezählt.

Also, der Fehler ist behoben.

Vielen vielen Dank für eure Hilfe.

Aber mal ehrlich: Soll das so sein? Im Prinzip habe ich doch dadurch die Methode überschrieben, oder nicht?
Warum wird die denn bitte doppelt aufgerufen?

Lg, M0rgenstern

robotx

BeitragDo, Mai 06, 2010 19:42
Antworten mit Zitat
Benutzer-Profile anzeigen
War es nicht so, dass BMax keine Überschreibung von Methoden kennt und im Falle des Konstruktors nur die beiden Methoden New () der jeweiligen Klassen "verbindet" ?
www.botbomb.robotzgames.de
www.robotzgames.de

M0rgenstern

BeitragDo, Mai 06, 2010 19:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Also, BMax kennt auf jeden Fall die ÜBerschreibung von Methoden.
Verwechselst du das vielleicht mit dem Befehl BlitzMax: [AUSKLAPPEN]
Super
?
Damit kann man die entsprechende Methode der Parentklasse zu einem bestimmten Zeitpunkt aufrufen und davor bzw danach was anderes in der Funktion machen.

Also, Beispiel:

Sagen wir eine Klasse BlitzMax: [AUSKLAPPEN]
TDrucker
und eine Klasse BlitzMax: [AUSKLAPPEN]
TErweiterterDrucker Extends TDrucker


Dann hat TDrucker folgende Methode:

BlitzMax: [AUSKLAPPEN]
Method Print(x:Int, y:Int)
DrawText("Hallo, ich bin ein Drucker",x,y)
End Method


Ausgabe:
Zitat:
Hallo, ich bin ein Drucker


Und TErweiterter Drucker hat folgdene Methode:

BlitzMax: [AUSKLAPPEN]
Method Print(x:Int,y:Int)
DrawText("# # # #",x,y-5)
Super.Print(x,y)
DrawText("# # # #",x,y+10


Ausgabe:
Zitat:
# # # #
Hallo, ich bin ein Drucker
# # # #


Wenn du das Super.Print weglässt, dann druckt er nur noch die Rauten.

Lg, M0rgenstern

mpmxyz

BeitragDo, Mai 06, 2010 19:50
Antworten mit Zitat
Benutzer-Profile anzeigen
BlitzMax kennt schon das Überschreiben von Methoden. Rolling Eyes
Die New-Methoden sind aber als Ausnahme so miteinander verknüpft, dass sie sich nur ergänzen.
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group