Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Wie Items in einem RPG speichern? (https://www.delphipraxis.net/46047-wie-items-einem-rpg-speichern.html)

Master_RC 17. Mai 2005 13:50


Wie Items in einem RPG speichern?
 
hi leutz!

Ich bin mal wieder da - heißt gleichzeitig, dass ich ein Problem habe ;)

yo...
Zwecks meines RPG brauch ich ja Items.
Jetzt hab ich mir gedacht, dass ich die während der Laufzeit generieren lasse, damit es eben nicht langweilig wird :)
Das klappt ja alles...

Nur... wie speichere ich die Items?
Gut... jeder Charakter, den man erstellt, hat einen eigenen Ordner, was heißt, dass ich in diesen jedes Item abspeichern könnte (meinetwegen in nem Unterordner)
Nur wird das dann ziemlich doof, weil man ja dann jedes Item einzeln editieren könnte...

Wie speichere ich es also ab?

Habt ihr eine Idee?
Also ein Item sieht so aus:
Delphi-Quellcode:
TItem = record
     name: string[255];        // Der Name des Items
     kind: string[255];        // Der Typus des Gegenstandes
     picture: string[255];     // Bild des Gegenstandes
     hands: integer;           // Anzahl der benötigten Hände (z.B. für Waffen)
     dmg: integer;             // +Schaden, den der Gegenstand gibt
     def: integer;             // +Verteidigung, die der Gegenstand gibt
     life,mana: integer;       // +max Leben / +max Mana
     strength: integer;        // +Stärke
     defense: integer;         // +Verteidung (Charakterwert)
     agility: integer;         // +Tempo
     wisdom: integer;          // +Weisheit
     charisma: integer;        // +Charisma
     needstrength: integer;    // gebrauchte Stärke zum Anlegen des Gegenstandes
     needdefense: integer;     // gebrauchte Verteidigung zum Anlegen des Gegenstandes
     needagility: integer;     // gebrauchtes Tempo zum Anlegen des Gegenstandes
     needwisdom: integer;      // gebrauchte Weisheit zum Anlegen des Gegenstandes
     needcharisma: integer;    // gebrauchtes Charisma zum Anlegen des Gegenstandes
     onlytype: string[255];    // Für charakterspezifische Gegenstände
     special1: string[255];    // evtl. Spezial-Sache des Gegenstandes
     special2: string[255];    // evtl. Spezial-Sache des Gegenstandes
    end;
Könnt ihr mir da ein wenig helfen?
(super wäre es ja mit codierung ;) eine XOR reicht aus! :) )

Fingolfin 17. Mai 2005 14:29

Re: Wie Items in einem RPG speichern?
 
Oha, da ist ja noch was wegen Speichern. :)

Wie gesagt, Streams oder DBs sind deine Freunde. Bei Streams kannst du u.a. beliebig viele Daten in eine Datei schreiben.

Abgesehen davon, solltest du dir mal etwas über OOP duchlesen und etwas abstrakter rangehen. Anstatt z.B. jeden Attributsmodifikator direkt in deinem Record zu definiern, wäre es vielleicht sinnvoller, eine abstrakte Liste von Attributen zu verwalten. So kannst du dann später auch einfach weitere hinzufügen.

Also stark vereinfacht eher sowas:

Delphi-Quellcode:
TAttribModi = class
private
  FAttrib: TAttrib;
  FModi: Integer;
public
  property Attrib: TAttrib read FAttrib write FAttrib;
  property Modi: Integer read FModi write FModi;
end;

TAttribModiList = class(TObjectList)
public
  Items[ind: Integer]: TAttribModi read GetAttribModi write SetAttribModi;
end;

TItem = class
private
  FName: string;
  FAttribModiList: AttribModiList;
public
  property Name: string read FName write FName;
  property AttribModiList: TAttribModiList read FAttribModiList write FAttribModiList;
end;
Wenn das jetzt alles totales Kauderwelsch sein sollte, suche einfach mal nach OOP-Tutorials. Über kurz oder lang wird dich der Code sonst in den Irrsinn treiben. ;)

alcaeus 17. Mai 2005 14:36

Re: Wie Items in einem RPG speichern?
 
Hallo Master_RC,

fuer die Speicherung hat sich bei mir die dpCollection bewaehrt. Du findest sie hier, und wenn du im Forum suchst findest du auch einige Beispiele zur Verwendung. Damit sparst du dir die Laengenbegrenzung von Strings auf ShortString (=255 Zeichen), und du kannst auch Unterobjekte abspeichern.

Greetz
alcaeus

Master_RC 17. Mai 2005 15:20

Re: Wie Items in einem RPG speichern?
 
danke an euch beide, nur...

ich weiß immernoch nicht, was nun ein Stream ist... :(

speichert ein stream auch "verschlüsselt" ab, also wenigstens unleserlich?
wenn ja, könnt ihr mir ein sehr knappen beispiel geben, wie ich es denn dann abspeichere/lade?


PS:
alle Items sind bei mir zur Zeit in einem Array abgespeichert, wie "Items:array of Items"

malo 17. Mai 2005 15:25

Re: Wie Items in einem RPG speichern?
 
Zitat:

Zitat von Master_RC
ich weiß immernoch nicht, was nun ein Stream ist... :(

:roll:

Master_RC 17. Mai 2005 15:40

Re: Wie Items in einem RPG speichern?
 
ja, jetz weiß ich es schon :p

nur zurück zum thema, wie speichere ich dann alle items ab?

malo 17. Mai 2005 15:48

Re: Wie Items in einem RPG speichern?
 
Zitat:

Zitat von Master_RC
ja, jetz weiß ich es schon :p

nur zurück zum thema, wie speichere ich dann alle items ab?

Ähm, jedes Item per Streams in eine Datei speichern, wie im Tutorial erklärt wird. Du solltest jedoch eventuell ein wenig Erfahrung mit Arrays (bzw. TList oder TObjectList-Objekten) und For-Schleifen haben ;)

Master_RC 17. Mai 2005 15:53

Re: Wie Items in einem RPG speichern?
 
kannst du mir ein beispiel geben?
büdde... ;)

denn... wie erkenne ich, dass das item, das ich laden will, genau das ist, was ich will?
oder wie lösche ich welche?

Fingolfin 17. Mai 2005 16:31

Re: Wie Items in einem RPG speichern?
 
Das genau ist der Knackpunkt mit der OOP. Wenn du eine irgendwie geartete Liste hast, lädt die alle Items, die sie in dem Stream findet. Du hast dann also alle Daten in der Liste, kannst in ihr löschen, ändern sonstwas. Wenn du fertig bist, speicherst du einfach wieder alle vorhandenen Items ab, die gelöschten sind dann ja nicht mehr vorhanden, werden also auch nicht erneut gespeichert.

Im Tutorial wird das Speichern eigentlich gut erklärt. Sag uns doch lieber, was genau du nicht verstehst.

Master_RC 17. Mai 2005 18:00

Re: Wie Items in einem RPG speichern?
 
k, ich hab gerade von alcaeus ein tuto bekommen, elches ich mir erst durchlese :)

nochmal dankie an euch, weitere fragen folgen ;)

alcaeus 17. Mai 2005 18:15

Re: Wie Items in einem RPG speichern?
 
Zitat:

Zitat von Master_RC
k, ich hab gerade von alcaeus ein tuto bekommen, elches ich mir erst durchlese :)

Bevor Fragen auftauchen warum ich es nicht hier gepostet habe, erklaere ich es: ich arbeite noch dran (es ist ein Collection-Tutorial), und ich habe es ihm nur geschickt, weil er es relativ dringend braucht. Nach meinem Urlaub werde ich es so schnell wie moeglich hier posten :)

Greetz
alcaeus

barf00s 19. Mai 2005 09:13

Re: Wie Items in einem RPG speichern?
 
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

barf00s 19. Mai 2005 09:18

Re: Wie Items in einem RPG speichern?
 
achja nochwas...
falls es einige stört das ich TMemoryStream verwende (solche Leute soll es ja geben)
man kann auch JEDEN andere Streamklasse benützen, oder man stellt sichs auf windoww.FileWrite/Read um oder BlockRead/Write ... wie auch immer...


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:02 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