| Autor |
Beitrag |
Jann1k
      
Beiträge: 866
Erhaltene Danke: 43
Win 7
TurboDelphi, Visual Studio 2010
|
Verfasst: So 24.12.06 12:25
also folgendes: in meinem sidescroller wollte ich jetzt eine Save/LOad Funktion einbauen mit der man spielstände laden bzw. speichern kann, problem hierbei ist das speichern/laden der listen, in denen gegner, geschosse und items gespeichert sind.
beschränken wir uns auf die liste für die gegner: dort sind objekte der klasse tenemy gespeichert, in dem ich mithilfe einer schleife alle attribute von den einzelnen instanzen von tenemy (position, art des gegners, flugrichtung etc...) speicher und filestream.write(tenemy(enemys[I].X),sizeof(tenemy(enemys[I].X))) benutze.
beim laden les ich zunächst die anzahl der gespeicherten gegner ein (vorher gespeichert), erstelle dann einen gegner mit "leeren" attributen und lese die daten mit filestream.read(tempenemy.X,sizeof(tempenemy.X)) ein, dann wird der gegner in die liste gespeichert.
Problem: einige gegner besitzen falsche daten und nach dem laden stürzt das spiel binnen weniger sekunden ab
pls help....
wer genauere infos braucht einfach bescheid sagen...
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: So 24.12.06 12:40
Jup. Ein wenig Quelltext deiner Routinen, sowie die Deklaration der Attribute X, ... die du einliest.
Schon mal vorweg: Implementier nicht DIE Methode zum Laden und Speichern, sondern lass die Gegener sich selber aus einem FileStream Lesen bzw. sich dorthinein speichern ...
Das Speichern wäre dann:
Delphi-Quelltext 1: 2: 3:
| Stream.WritBuffer(FoeCount, SizeOf(FoeCount); For X := 0 TO Foes.Count - 1 do Foes[X].SaveToStream(Stream); |
Wobei jeder Gegner sich dann einfach in den Strem an die aktuelle Position schreibt ...
DasLaden analog dazu ...
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Jann1k 
      
Beiträge: 866
Erhaltene Danke: 43
Win 7
TurboDelphi, Visual Studio 2010
|
Verfasst: So 24.12.06 13:11
jeden gegner sich selbst speichern lassen? gute idee werdich mal gleich ausprobieren hier der relevante teil meines quelltextes;
deklaration von tenemy:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| TEnemy =class(TObject) private public art:string; boss:boolean; X,Y,alive,way, reflek, b,h,s,c:integer; rect:Trect; constructor create(px,py,palive,pway,preflek,pb,ph,ps:integer; part:string; pboss:boolean); procedure setrect; end; |
speichern der gegner
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| filestream.write(enemys.count,sizeof(enemys.count)); for I:=0 to enemys.count-1 do begin; filestream.write(Tenemy(enemys[I]).art,sizeof(Tenemy(enemys[I]).art)); filestream.write(Tenemy(enemys[I]).X,sizeof(Tenemy(enemys[I]).X)); filestream.write(Tenemy(enemys[I]).Y,sizeof(Tenemy(enemys[I]).Y)); filestream.write(Tenemy(enemys[I]).alive,sizeof(Tenemy(enemys[I]).alive)); filestream.write(Tenemy(enemys[I]).way,sizeof(Tenemy(enemys[I]).way)); filestream.write(Tenemy(enemys[I]).reflek,sizeof(Tenemy(enemys[I]).reflek)); filestream.write(Tenemy(enemys[I]).b,sizeof(Tenemy(enemys[I]).b)); filestream.write(Tenemy(enemys[I]).h,sizeof(Tenemy(enemys[I]).h)); filestream.write(Tenemy(enemys[I]).s,sizeof(Tenemy(enemys[I]).s)); filestream.write(Tenemy(enemys[I]).c,sizeof(Tenemy(enemys[I]).c)); filestream.write(Tenemy(enemys[I]).boss,sizeof(Tenemy(enemys[I]).boss)); filestream.write(Tenemy(enemys[I]).rect,sizeof(Tenemy(enemys[I]).rect)); end; |
laden der gegner
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| filestream.read(J,sizeof(j)); for I:=0 to J-1 do begin tempE:=tenemy.create(0,0,0,0,0,0,0,0,'',false); filestream.read(tempe.art,sizeof(tempe.art)); filestream.read(tempe.X,sizeof(tempe.X)); filestream.read(tempe.Y,sizeof(tempe.Y)); filestream.read(tempe.alive,sizeof(tempe.alive)); filestream.read(tempe.way,sizeof(tempe.way)); filestream.read(tempe.reflek,sizeof(tempe.reflek)); filestream.read(tempe.b,sizeof(tempe.b)); filestream.read(tempe.h,sizeof(tempe.h)); filestream.read(tempe.s,sizeof(tempe.s)); filestream.read(tempe.c,sizeof(tempe.c)); filestream.read(tempe.boss,sizeof(tempe.boss)); filestream.read(tempe.rect,sizeof(tempe.rect)); enemys.add(tempE); end; |
|
|
jakobwenzel
      
Beiträge: 1889
Erhaltene Danke: 1
XP home, ubuntu
BDS 2006 Prof
|
Verfasst: So 24.12.06 13:19
Mach mal aus dem Typ von Art nen ShortString.
Grund: Normale Strings sind nur Zeiger, die dann auf ungültige Bereiche zeigen.
_________________ I thought what I'd do was, I'd pretend I was one of those deaf-mutes.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: So 24.12.06 13:28
Der Fehler liegt daran, dass Du einen String direkt in den Stream speicherst ...
Versuch's mal damit:
Delphi-Quelltext 1: 2: 3: 4: 5:
| var X: Integer; X := Length(StrVar); Stream.Write(X, SizeOf(X)); If X <> 0 Then Stream.Write(StrVar[1], X); |
Lesen nahezu analog:
Delphi-Quelltext 1: 2: 3: 4: 5:
| var X: Integer; Stream.Read(X, SizeOf(X)); SetLength(StrVar, X); If X <> 0 Then Stream.Read(StrVar[1], X); |
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Jann1k 
      
Beiträge: 866
Erhaltene Danke: 43
Win 7
TurboDelphi, Visual Studio 2010
|
Verfasst: So 24.12.06 13:32
also großes großes thx problem is gelöst das scheint jetzt zu funktionieren, ich teste es noch paar mal, aber sieht sehr swehr gut aus, versteh zwar nicht wieso die umwandlung von string in shortstring alles ändert aber egal danke danke danke
is wohl das schönste weihanchtsgeschenk ^^
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: So 24.12.06 13:45
Strings sind im Speicher nur Pointer ... Du hast also in deinem ersten Source nur ne Adresse im Speicher gespeichert und beim Wiederherstellen, hast Du dann "Wil drauf los gepointert", ohne wissen zu können, ob der Pointer so stimmt. Mit der letztgenannten Methode wandelst Du nicht den String in nen ShortString um, sondern Speicherst die Daten des Strings (und nicht den Zeiger auf den String).
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Jann1k 
      
Beiträge: 866
Erhaltene Danke: 43
Win 7
TurboDelphi, Visual Studio 2010
|
Verfasst: So 24.12.06 14:03
okay danke für die erklärung, das umwandeln string->shortstring bezog sich aber nicht auf deine methode, sondern auf den tipüp davor in der deklaration aus art:string --> art:shortstring zu machen, das hat nämlich auch geklappt. trotzdem danke für diene bemühungen und frohes fest
|
|
|