![]() |
Speichern verschiedener Objekte in einer Datei
Hey,
Ich programmiere gerade ein Spiel, dass Karten benötigt. Auf den Karten gibt es Objekte verschiedener Typen und zusätzlich hat die Karte noch weitere Eigenschaften, wie Hintergrundanimationen etc.. Ich würde gerne all diese Daten in einer Datei speichern, da es viele verschiede Objekte gibt und es sehr unschön wäre, für jeden Objekttypen eine eigene Datei anzulegen. Wie gehe ich vor? Ich könnte für die verschiedenen Objekte ein Record verwenden; der Record-Typ hätte dann ein Attribut, das besagt, um welchen Objekttypen es sich handelt. Allerdings hängen alle weiteren Attribute vom Objekttypen ab, was bedeutet, dass je nach Objekttyp alle nicht benötigten Attribute leer blieben. Eine weitere Möglichkeit wäre die Verwendung einer IniDatei, was ich allerdings für genauso unschön halte. Hier würde der Name der Sektion dann vermutlich als Präfix den Objekttypen deklarieren, was auf unschöne Stringoperationen hinausliefe. Es wäre auch möglich verschiedene Dateien zu benutzen, diese aber in ein Archiv zu packen, aber auch dies wäre ziemlich aufwändig in Bezug auf das Speichern und Laden der Daten. Was empfehlt ihr mir? Bietet sich die Verwendung einer Datenbank an? Die Eigenschaften der Karte könnte ich - sofern nicht anders möglich - auch in einer zusätzlichen Ini-Datei speichern, aber die Objekte hätte ich schon lieber in einer Datei. |
Re: Speichern verschiedener Objekte in einer Datei
Wie wäre es mit einer XML-Datei. Dann hast Du auch keine Probleme falls später mal weitere zu speichernde Infos dazu kommen.
|
Re: Speichern verschiedener Objekte in einer Datei
Eine Möglichkeit wäre eine
![]() |
Re: Speichern verschiedener Objekte in einer Datei
Ist es auch möglich, ein Record zu nehmen, in welchem Arrays vom Typen der verschiedenen Objekte sind?
Beispiel:
Delphi-Quellcode:
Dann würde die "file of GameObject" nur ein "GameObject" besitzen, in dem alle restlichen Objekte stünden;
GameObject = record
objects1 = array of TObject1; objects2 = array of TObject2; {...} property1: Boolean; {...} end; zusätzlich enthielte es auch die weiteren Eigenschaften der Karte. Ich finde diese Variante unkomplizierter, was möglicherweise auch daran liegt, dass ich mich schon ziemlich an Records gewohnt habe. Dagegen spricht nichts, oder? Würde man das als "unschönen Programmierstil bezeichnen"? //Edit: Statt der Arrays kann ich sogar TObjectListen verwenden, was das ganze noch komfortabler macht. |
Re: Speichern verschiedener Objekte in einer Datei
Zitat:
|
Re: Speichern verschiedener Objekte in einer Datei
Delphi-Quellcode:
Das sollte
GameObject = record
objects1 = array of TObject1; objects2 = array of TObject2; {...} property1: Boolean; {...} end; 1. Kein record sein sondern eine Klasse und 2. Das Array sollte dann eine SubCollection sein und dann sollte das gehen ;) (TCollection ist Quasi ein Array of TCollectionItem - da muss man dann aber auch mit Klassen arbeiten ;)) |
Re: Speichern verschiedener Objekte in einer Datei
Zitat:
Dann mach ich ein Array mit einer Länge von 500 und arbeite das soweit ab, bis der Inhalt leer ist! =P Das gleiche mit den Strings. ;) Spaß beiseite, ich versuch mal mit den Collections zurecht zu kommen. |
Re: Speichern verschiedener Objekte in einer Datei
Hey, die Verwendung der Collections ist weit aus unkomplizierter, als ich erwartet habe!
Vielen Dank für die Antworten und vor allem Danke an Alcaeus für ![]() |
Re: Speichern verschiedener Objekte in einer Datei
Müssen alle Objekte, die in einer Collection abgespeichert werden von TPersistent abgeleitet sein?
Ich hab jetzt eine Collection mit Namen "Coll", diese enthält wiederum die Subcollection TBrickCollItem, welche die beiden SubSubcollections "TRealCollItem" und "TTargaCollItem" enthält, diese verwende ich anstelle eines "Array of Real" und anstelle eines "Array of TTargaGraphic". Die Subcollection "TRealCollItem" hat das Attribut "RealValue: Real" und "TTargaCollItem" hat "Targa: TTargaGraphic" als Attribut. Beim Speichern der Collection gibt es keinerlei Probleme, aber beim Laden macht die "TTargaCollItem" Probleme. Es treten eine Reihe von Exceptions auf (beim Aufruf von Coll.LoadFromFile(filename)): 1. "Ungültiger Pfad für Eigenschaft", 2. "Fehler beim Lesen von TTargaCollItem.Targa.Data: Ungültiger Pfad für Eigenschaft" 3. "Fehler beim Lesen von TBrickCollItem.TargaCollItems: Fehler beim Lesen von TTargaCollItem.Targa.Data: Ungültiger Pfad für Eigenschaft". Mach ich da irgendetwas falsch, beim Speichern oder beim Laden - oder kann man das nicht sagen oder kann ich generell kein TTargaGraphic (was übrigens aus GraphicEx stammt) in einer Collection speichern? |
Re: Speichern verschiedener Objekte in einer Datei
*push*
|
Re: Speichern verschiedener Objekte in einer Datei
Okay, ich poste mal die gesamte Unit, die für das Speichern der Objekte verantwortlich ist. Der restliche Code befindet sich in anderen Units, dieser ist hier aber nicht relevant.
Ist ganz schön lang, ich wäre aber sehr dankbar, wenn ihr mal drüber schauen könntet, da ich wirklich ein wenig auf dem Schlauch stehe. Es geht darum, eine Objektlist ("BrickPrototypes"), die mit Objekten vom Typen "TBrickPrototype" gefüllt ist zu speichern und zu laden. Um den Vorgang des Speicherns und Ladens vom restlichen Programm strickt zu trennen, speichere ich die Klasse "TBrickPrototype" nicht direkt, sondern gehe den Umweg über die Klasse "TBrickCollItem", die von TPersistent abgeleitet ist. Außer den beiden Arrays habe ich alle restlichen Parameter weggelassen, da diese problemlos funktionieren. Die Klasse "TFileControler" ist die Klasse, die meine Objektlist "BrickPrototypes" als Collection speichert und aus der Datei wiederherstellt. Mein Problem findet ihr zwei Posts weiter oben. Aber ich wiederhole meine Frage nochmal: Hab ich da irgendwas falsch verstanden und kann das folglich so gar nicht funktionieren, oder ist da nur irgendwo ein kleiner Fehler drin? Wäre auch für sonstige Verbesserungsvorschläge dankbar.
Delphi-Quellcode:
type
//Objektlist mit Objekten dieses Typs soll gespeichert werden!! TBrickPrototype = class(TObject) {aus anderer Unit} private public textures: array of TTargaGraphic; animationVelocities: array of Real; end; //Subcollections: TRealCollItem = class(TCollectionItem) private fRealValue: Real; public procedure Assign(Source: TPersistent); override; published property RealValue: Real read fRealValue write fRealValue; end; TTargaCollItem = class(TCollectionItem) private fTarga: TTargaGraphic; public procedure Assign(Source: TPersistent); override; published property Targa: TTargaGraphic read fTarga write fTarga; end; //Maincollection: TBrickCollItem = class(TCollectionItem) private fTargaCollItems: TJSCollection; fRealCollItems: TJSCollection; public constructor Create(Collection: TCollection); override; destructor Destroy; override; procedure Assign(Source: TPersistent); override; published property TargaCollItems: TJSCollection read fTargaCollItems write fTargaCollItems; property RealCollItems: TJSCollection read fRealCollItems write fRealCollItems; end; //Administration: TFileControler = class(TOBject) private public procedure LoadBricks; //Bricks from File -> global TObjectList procedure SaveBricks; end; implementation uses UBrickEditor_Main; { TRealCollItem } procedure TRealCollItem.Assign(Source: TPersistent); begin inherited; if Source is TRealCollItem then fRealValue := TRealCollItem(Source).RealValue else inherited Assign(Source); end; { TTargaCollItem } procedure TTargaCollItem.Assign(Source: TPersistent); begin inherited; if Source is TRealCollItem then fTarga := TTargaCollItem(Source).Targa else inherited Assign(Source); end; { TBrickCollItem } constructor TBrickCollItem.Create(Collection: TCollection); begin inherited Create(Collection); fTargaCollItems := TJsCollection.Create(TTargaCollItem); fRealCollItems := TJsCollection.Create(TRealCollItem); end; destructor TBrickCollItem.Destroy; begin fTargaCollItems.free; fRealCollItems.free; inherited Destroy; end; procedure TBrickCollItem.Assign(Source: TPersistent); begin inherited; if Source is TBrickCollItem then begin fTargaCollItems.Assign(TBrickCollItem(Source).fTargaCollItems); fRealCollItems.Assign(TBrickCollItem(Source).fRealCollItems); end else inherited Assign(Source); end; { TFileControler } procedure TFileControler.LoadBricks; var Coll: TmxJSCollection; tempBrickPrototype: TBrickPrototype; i, j: integer; begin Coll := TmxJSCollection.Create(TBrickCollItem); Coll.LoadFromFile(filename); BrickPrototypes.Clear; for i:=0 to Coll.Count-1 do begin for j:=0 to TBrickCollItem(Coll.Items[i]).TargaCollItems.Count-1 do begin setlength(tempBrickPrototype.textures, length(tempBrickPrototype.textures)+1); tempBrickPrototype.textures[high(tempBrickPrototype.textures)] := TTargaCollItem(TBrickCollItem(Coll.Items[i]).TargaCollItems).Targa; end; {} for j:=0 to TBrickCollItem(Coll.Items[i]).RealCollItems.Count-1 do begin setlength(tempBrickPrototype.animationVelocities, length(tempBrickPrototype.animationVelocities)+1); tempBrickPrototype.animationVelocities[high(tempBrickPrototype.animationVelocities)] := TRealCollItem(TBrickCollItem(Coll.Items[i]).RealCollItems).RealValue; end; BrickPrototypes.Add(tempBrickPrototype); end; {for i...} Coll.free; end; procedure TFileControler.SaveBricks; var Coll: TmxJSCollection; i,j : integer; begin coll := TmxJSCollection.Create(TBrickCollItem); for i:=0 to BrickPrototypes.Count-1 do begin with Coll.add as TBrickCollItem do begin for j:=0 to high(TBrickPrototype(BrickPrototypes[i]).textures) do with TargaCollItems.add as TTargaCollItem do Targa := TBrickPrototype(BrickPrototypes[i]).textures[j]; for j:=0 to high(TBrickPrototype(BrickPrototypes[i]).animationVelocities) do with RealCollItems.add as TRealCollItem do RealValue := TBrickPrototype(BrickPrototypes[i]).animationVelocities[j]; end; {with Coll.add...} end; {for i...} Coll.SaveToFile(filename); Coll.free; end; end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:35 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz