|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
smile_virus Junior JLI'ler
Alter: 34 Anmeldedatum: 19.08.2004 Beiträge: 64
Medaillen: Keine
|
Verfasst am: 21.06.2005, 17:56 Titel: zeiger und binärdateien |
|
|
Hallo!
Ich programmiere grade einen Map Editor. Neben Informationen zur Landschaft, soll er Informationen über NPCs und andere Gegenstände abspeichern können.
Dazu benutz ich ein dynamisches Array und diese Struktur:
CPP: | struct npc
{
int mapX;
int mapY;
int style;
};
int numOfNPCs;
npc **npcArray;
|
Wird nun im Editor eine solche Einheit erzeugt, wird sie mit new angelegt und im Array gespeichert
CPP: | npcArray = new npc*[numOfNPCs+1];
npcArray[numOfNPCs] = new npc;
npcArray[numOfNPCs]->mapX = MapX;
npcArray[numOfNPCs]->mapY = MapY;
npcArray[numOfNPCs]->style = ChosenStyle;
numOfNPCs++;
|
dann wird auf Knopfdruck die Karte als Binärdatei abgespeichert bzw geladen
und da steck ich fest
Wie speicher und les ich jetz dieses Array richtig?
so funktionierts jedenfalls nich:
CPP: | for(i = 0;i < numOfNPCs;i++)
fwrite(&npcArray[i],12,1,Datei);
|
Zuletzt bearbeitet von smile_virus am 21.06.2005, 19:29, insgesamt einmal bearbeitet |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 21.06.2005, 18:18 Titel: Re: zeiger und binärdateien |
|
|
smile_virus hat Folgendes geschrieben: | CPP: | npcArray = new npc*[numOfNPCs];
npcArray[numOfNPCs] = new npc;
npcArray[numOfNPCs]->mapX = MapX;
npcArray[numOfNPCs]->mapY = MapY;
npcArray[numOfNPCs]->style = ChosenStyle;
numOfNPCs++;
|
|
hm, ich weiß net, ob das so ist, wie du das eigentlich willst. Ich nehme mal an, du willst bei deinem npcArray ein 2D-Array aus npc's erstellen. So ist das 1. ein Zugriff auf eine eigentlich nichtvorhandenes Index im npcArray(in diesem Fall egal, da dynamisch; aber ich glaube net, dass du das willst.) du müsstes wenn schon, CPP: | npcArray[numOfNPCs-1] = new npc; | schreiben. Aber ich glaube auch nicht, dass du immer weiter über die Grenze hinaus gehen willst. Also das ist wie CPP: | long Array[10];
long Array[10] = 2; // access violation
long Array[10 + 1] = 3 // nächste Acces Violation. | Ich glaube du willst eher sowas: CPP: | long IndicesMax = 10;
static long Counter = 0;
long Array[IndicesMax];
Array[Counter] = Counter;
if(Counter < IndicesMax-1)
Counter++; |
Also, es liegt in jedem Fall net an dem binären. Sondern eher am nicht-vorhandenen/initialisierten Zugriff bei fwrite
Gruß DirectXer
Zuletzt bearbeitet von DirectXer am 21.06.2005, 18:24, insgesamt einmal bearbeitet |
|
Nach oben |
|
|
Patrick Dark JLI Master
Anmeldedatum: 25.10.2004 Beiträge: 1895 Wohnort: Düren Medaillen: Keine
|
Verfasst am: 21.06.2005, 18:23 Titel: |
|
|
Mit new und co. bei Dateien zu arbeiten ist eine ganz fiese Sache! Lass da erstmal die Finger von!
Ich hab hier eine sehr elegante Lösung um etwas binär abzuspeichern:
CPP: | #include <iostream>
#include <fstream>
#include <vector>
using namespace std;
int main (void)
{
vector<int> test;
test.push_back (1);
test.push_back (2);
test.push_back (3);
test.push_back (4);
test.push_back (5);
fstream file ("test.txt", ios::binary | ios::out);
file.write ((const char*)&test[0], (int)test.size()*sizeof(int));
file.close ();
// Einlesen
fstream filei ("test.txt", ios::binary | ios::in);
// Vector ausrichten
vector<int> x(test.size());
// Daten in den Vector einfügen
filei.read ((char*)&x[0], (int)test.size()*sizeof(int));
cout << x[0] << endl;
cout << x[1] << endl;
cout << x[2] << endl;
int y;
cin >> y;
return 0;
} |
Anstatt dem Vector mit einem int auszufüllen könntest Du dort Deine Gegnerstruktur hinzufügen.
Tipp: CPP: | class npc
{
public:
npc (int x, int y, int style) : x_(x), y_(y), style_(style) {}
private:
int x_;
int y_;
int style;
}; |
Rocks more
edit: Achja sorry wegen den C-Casts! Der Code hat schon seine Jahre da gehört natürlich ein reinterpret_cast hin
Vorteil dieser Variante: Keine Zugriffsverletzung möglich, ordentlich und easy _________________ 'Wer der Beste sein will muss nach Perfektion streben und jede Gelegenheit nutzen sich zu verbessern.' - KIA
[ German Game Dev | Boardsuche hilft sehr oft | Google rockt | Wie man Fragen richtig stellt | ICQ#: 143040199 ] |
|
Nach oben |
|
|
smile_virus Junior JLI'ler
Alter: 34 Anmeldedatum: 19.08.2004 Beiträge: 64
Medaillen: Keine
|
Verfasst am: 21.06.2005, 18:56 Titel: |
|
|
Du hattest Recht DirectXer,
hab aber nur falsch abgetippt (sollte eigentlich heißen ... = new npc*[numOfNPCs+1] (habs editiert))
Zitat: |
Mit new und co. bei Dateien zu arbeiten ist eine ganz fiese Sache! Lass da erstmal die Finger von!
|
hm zu spät...
beim abspeichern der Landschaft hab ichs genauso gemacht....
CPP: | fwrite(map[0],sizeof(map[0][0]),1,Datei);
for(i = 0;i < width;i++)
fwrite(&map[i][0],sizeof(map[0][0]),height,Datei);
|
Und danke für den Tipp
Wenn ichs eilig hab mach ichs halt so simpel wie möglich... |
|
Nach oben |
|
|
Patrick Dark JLI Master
Anmeldedatum: 25.10.2004 Beiträge: 1895 Wohnort: Düren Medaillen: Keine
|
Verfasst am: 21.06.2005, 19:04 Titel: |
|
|
Achja bevor ich es vergesse:
Kann is Auge gehen wenn Du mit Pointern arbeitest. Da könnte es passieren das die Dinger die Formatierung verlieren und so die Größe nicht mehr richtig bestimmt werden kann!
Ergo: Nach abhilfe fragen
z.B. Das hier ist sehr gut für 2D Arrays CPP: | namespace ttl
{
// Dynamisches 2D Array
template<typename T> class array2d
{
public:
// C'tor und D'tor rows = Zeilen, cols = Spalten
array2d (unsigned long rows, unsigned long cols) : rows_(rows), cols_(cols)
{
// 2-Dimensionales Array auf 1-Dimensionales abbilden
data_ = new T[rows_*cols_];
}
~array2d (void)
{ delete [] data_; }
// Zugriffsoperator
inline T* operator[] (unsigned long line)
{
// Array liegt "zeilenweise" im Speicher
return (&data_[line * cols_]);
}
// Diverse Getter
inline unsigned long getRows (void) { return (rows_); }
inline unsigned long getCols (void) { return (cols_); }
inline unsigned long getSize (void) { return (rows_*cols_); }
private:
// Datenarray sowie Größenangaben
T* data_;
unsigned long rows_;
unsigned long cols_;
};
// Statisches 2D Array
template<typename T, unsigned long rows, unsigned long cols> class array2d_static
{
public:
// C'tor und D'tor
array2d_static (void) {}
~array2d_static (void) {}
// Zugriffsoperator
inline T* operator[] (unsigned long line)
{ return (&data_[line * cols]); }
// Diverse Getter
inline unsigned long getRows (void) { return (rows); }
inline unsigned long getCols (void) { return (cols); }
inline unsigned long getSize (void) { return (rows*cols); }
private:
// Datenarray
T data_[rows*cols];
};
// Ein 1D Array das statisch ist
template<typename T, unsigned long size> class array_static
{
public:
// C'tor und D'tor
array_static (void) {}
~array_static (void) {}
// Zugriffsoperator
inline T* operator[] (unsigned long id)
{ return (&data_[id]); }
// Diverse Getter
inline unsigned long getSize (void) { return (size); }
private:
// Datenarray
T data_[size];
};
} // Namespace: ttl - Tiny Template Lib (c) Patrick Ullmann |
Ordentlich, Schnell, Sauber, Fehlerfrei und Sicher
- Patrick, sauber und diskreet _________________ 'Wer der Beste sein will muss nach Perfektion streben und jede Gelegenheit nutzen sich zu verbessern.' - KIA
[ German Game Dev | Boardsuche hilft sehr oft | Google rockt | Wie man Fragen richtig stellt | ICQ#: 143040199 ] |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 21.06.2005, 19:18 Titel: |
|
|
smile_virus hat Folgendes geschrieben: | Du hattest Recht DirectXer,
hab aber nur falsch abgetippt (sollte eigentlich heißen ... = new npc*[numOfNPCs+1] (habs editiert)) |
nee, ich meinte ja net nur das. Les dir meinen Text nochmal durch. Oder willst du wirklich nur das letzte Element initialisieren? Glaub ich net..
Außerdem, gibts da bei fwrite ja Zugrif auf net initialisierten Speicher. Da gibts auch nix, was der speichenrn soll
Gruß DirectXer |
|
Nach oben |
|
|
smile_virus Junior JLI'ler
Alter: 34 Anmeldedatum: 19.08.2004 Beiträge: 64
Medaillen: Keine
|
Verfasst am: 21.06.2005, 19:41 Titel: |
|
|
DirectXer hat Folgendes geschrieben: |
Oder willst du wirklich nur das letzte Element initialisieren? Glaub ich net..
|
Doch will ich
Die anderen Elemente werde ja vorher schon intialisiert
-: Knopfdruck :- array[x] = new int; x++;
-: Knopfdruck :- array[x] = new int; x++;
usw.
DirectXer hat Folgendes geschrieben: |
Außerdem, gibts da bei fwrite ja Zugrif auf net initialisierten Speicher. Da gibts auch nix, was der speichenrn soll
|
Das stimmt nicht
Mal angenommen numOfNPCs wäre 6
Dann wäre der letzte Schleifendurchlauf bei 5
weil 6 schon nicht mehr kleiner als 6 wäre
und bei 5 ist noch keine acces violation
[edit] Aah jetz weiß ich was du mit über die Grenzen gehen meinst
Ich geh ja nich über die Grenzen des Arrays, weil ich die Grenzen des Arrays jedesmal, wenn etwas dazukommt mit new um ein Feld erweitere [/edit] |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 22.06.2005, 15:25 Titel: |
|
|
achso, dann is ja alles gut ...fast alles. Das mit dem NPC in Binärdatei schreiben funktionert so jedefalls net. Guck dir Patricks Lösung an, wenn du damit Probleme hast(gut Patrick, dein Code ist Zitat: | Ordentlich, Schnell, Sauber, Fehlerfrei und Sicher
- Patrick, sauber und diskreet | aber eben für naja, wie soll ich sagen... manche net so direkt zu verstehen.Mit manche mein ich n00bs und so ) kannst du ihn ja fragen
Gruß DirectXer |
|
Nach oben |
|
|
Patrick Dark JLI Master
Anmeldedatum: 25.10.2004 Beiträge: 1895 Wohnort: Düren Medaillen: Keine
|
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
Powered by phpBB © 2001, 2005 phpBB Group Deutsche Übersetzung von phpBB.de
|