Einzelnen Beitrag anzeigen

barf00s
(Gast)

n/a Beiträge
 
#12

Re: Wie Items in einem RPG speichern?

  Alt 19. Mai 2005, 09:13
nochmal zu dem dingen "Stream(s)" ...
kurzgesagt 'n Stream isn "Strom" an/von Daten ... kann man jeweils als Lesestrom oder als Schreibstrom betrachten, je nachdem wie man es braucht...

naja und wie man die Items in so einem Stream verstaut (und später vllt auch in einer Datenbank - innem blob oder so)
schreib ich dir mal eben hier hin

Delphi-Quellcode:
TItem = record
     name: string; // Der Name des Items
     kind: string; // Der Typus des Gegenstandes
     picture: string; // Bild des Gegenstandes
     { ... die ganzen integer teile hier ... }
     onlytype: string; // Für charakterspezifische Gegenstände
     special1: string; // evtl. Spezial-Sache des Gegenstandes
     special2: string; // evtl. Spezial-Sache des Gegenstandes
    end;
um platz in der späteren datei zu sparen hab ich aus den string[255] (das währen ja für jeden string jedesmal 256 zeichen) ein einfachen string gemacht, die lade & speicher "routinen" kümmern sich automatisch um deren größe...

Delphi-Quellcode:
procedure SaveStringToStream(xStream: TStream; const sText: string);
begin
{
  länge des nachfolgenden strings speichern,
  4 = SizeOf(Integer) = Anzahl an Bytes die ein Integer im Speicher "verbraucht"
}

  xStream.Write(Length(sText), 4);
  xStream.Write(sText[1], Length(sText));
{
  oder xStream.Write(Pointer(sText)^, Length(sText));
}

end;

procedure LoadStringFromStream(xStream: TStream; var sText: string);
var
  iLength: integer;

begin
// länge des nachfolgenden strings wieder auslesen
  xStream.Read(iLength, 4);
// länge des texts setzen
  SetLength(sText, iLength);
// und letztendlich den text aus dem stream lesen
  xStream.Read(sText[1], iLength);
// oder wieder xStream.Read(Pointer(sText)^, iLength);
end;

procedure SaveItem(const sFileName: string; xItem: TItem);
var
  xMS: TMemoryStream;

begin
  xMS := TMemoryStream.Create;
  with xItem do begin
    SaveStringToStream(xMS, name);
    SaveStringToStream(xMS, kind);
    SaveStringToStream(xMS, picture);
    xMS.Write(XYZ, 4); // < XYZ steht für alle deine xItem items vom typ integer, ich war zu faul hier alle hinzuschreiben :)
    SaveStringToStream(xMS, onlytype);
    SaveStringToStream(xMS, special1);
    SaveStringToStream(xMS, special1);
  end;
  xMS.SaveToFile(sFileName);
  FreeAndNil(xMS);
end;

function LoadItem(const sFileName: string; xItem: TItem): boolean;
var
  xMS: TMemoryStream;

begin
  Result := False;
  if not FileExists(sFileName then
    Exit;
  xMS := TMemoryStream.Create;
  xMS.LoadFromFile(sFileName);
  with xItem do begin
    ReadStringToStream(xMS, name);
    ReadStringToStream(xMS, kind);
    ReadStringToStream(xMS, picture);
    xMS.Read(XYZ, 4); // < XYZ steht für alle deine xItem items vom typ integer, ich war zu faul hier alle hinzuschreiben :)
    ReadStringToStream(xMS, onlytype);
    ReadStringToStream(xMS, special1);
    ReadStringToStream(xMS, special2);
  end;
  FreeAndNil(xMS);
  Result := True;
end;
was noch ginge, wenn du dein record so belässt wies war also du die strings mit string[von 0 bis 255 irgendwas] definierst (oder halt mit shortstring wie alceus bemerkt hat

kannst dein Item mit noch weniger code speichern

Delphi-Quellcode:
procedure SaveItem(const sFileName: string; xItem: TItem);
var
  xMS: TMemoryStream;

begin
  xMS := TMemoryStream.Create;
  xMS.Write(xItem, SizeOf(xItem)); // SizeOf(xItem) = 15 * SizeOf(Integer) = 15 * 4 = 60 ... + 6 * SizeOf(shortstring) = 6 * 256 = 1536 = 60 + 1536 = 1596 Bytes ... deine Datei müsste also 1596 Bytes PRO Item belegen, wenn ich mich jetz nich verrechnet hab
  xMS.SaveToFile(sFileName);
  FreeAndNil(xMS);
end;

function LoadItem(const sFileName: string; xItem: TItem): boolean;
var
  xMS: TMemoryStream;

begin
  Result := False;
  if not FileExists(sFileName) then
    Exit;
  xMS := TMemoryStream.Create;
  xMS.LoadFromFile(sFileName);
  xMS.Read(xItem, SizeOf(xItem));
  FreeAndNil(xMS);
end;
hoffe das hat ein wenig geholfen
  Mit Zitat antworten Zitat