PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Was kann ich dafür nutzen?



Nuke
06-12-2003, 08:34
Hi.

Ich programmiere zur Zeit ein kleines OpenGL-Spiel. Drückt der Anwender nun die linke Maustaste, dann soll er ein Objekt durch den Raum schicken.
Nunja. Ich müsste ja nun eine Liste anlegen. Für jeden Mausklick das Objekt, bzw. die Koordinaten an den ich das Objekt zeichnen muss (damit ich mehrere Objekte gleichzeitig erstellen kann). Diese muss ich dann durchlaufen, die Werte auslesen und einen Zähler für jedes Objekt hochsetzen. Das wären dann 6 Float-Werte (X,Y,Z,XWinkel,YWinkel,Zähler) die sich in der Liste befinden müssten.

Nun wollte ich fragen wie ich das am besten mache!?! So wie ich durch die Suchen-Funktion erfahren habe, brauche ich dazu eine verkettete Liste. Aber ich habe auch gelesen das ein vector das selbe sein soll.

Einzelne Einträge müssten dann auch aus der Liste entfernt werden wenn der Zähler überlaufen ist (damit er das Objekt nicht in die Ewigkeit zeichnet).

Also nochmal in Kurz:

Ich klicke und ein Objekt soll durch den Raum fliegen. Klicke ich ein weiteres mal dann soll noch ein Objekt durch den Raum fliegen. Alle unabhängig voneinander. Ist ein bestimmer Zählerwert erreicht dann soll das Objekt verschwinden.

Gibt es dafür schon fertige Sachen in ANSI C++?

Danke!

peschmae
06-12-2003, 08:49
ich denke schon, dass sich da Vector anbietet.

Von verketteten Listen halte ich persöhnlich nicht allzu viel. (Die Performance der Java-Implementation von LinkedList ist zu schlecht, ausser ich beschränke mich auf ständiges Hinzufügen und Entfernen...)

MfG Peschmä

Nuke
06-12-2003, 11:09
Hi.

OK! Danke schonmal.

Nur jetzt habe ich ein weiteres Problem.

Wie speichere ich 6 Werte in einem vector?

Ich habe jetzt mal zum testen das hier:



vector<float> a[6];

a[0].push_back(1.0f);
a[0].push_back(2.0f);
a[0].push_back(3.0f);

a[1].push_back(1.0f);
a[1].push_back(2.0f);
a[1].push_back(3.0f);

// ... hier der Rest

for (unsigned int i=0;i<a[0].size();i++)
{
cout << a[0][i] << endl;
cout << "\t" << a[1][i] << endl;
// ... weitere Anzeigen
};


Kann man das so verwenden, oder wäre da etwas nicht so toll? Ich denke das Durchlaufen der Liste ist nicht so richtig, oder?

Wie kann man das besser machen?

Und eine Frage noch. Wie lösche ich nun einzelne Einträge?

Leider kapiere ich dieses erase nicht. Was muss man dem Übergeben, das ich einen Eintrag entfernen kann? Ich müsste mir beim Durchlaufen der Liste den Eintrag merken und am Schluss die gemerkten Einträge entfernen. Ein Eintrag wäre ja z.B. die 2.0f in a[0],a[1],a[2],a[3],a[4] und a[5], oder?

Wie mache ich das?

Danke!

peschmae
06-12-2003, 11:18
so wie ich das verstanden habe, machst du am besten eine Klasse, die die 6 Werte aufnimmt.
Im Vector speicherst du dann Objekte dieser Klasse.

MfG Peschmä

P.S. bei der Implementierung werde ich dir nicht helfen können, bin im Moment selbst noch am C++-lernen :)

Nuke
06-12-2003, 22:54
Hi.

Ich habe jetzt mal etwas zusammengeschustert. Bis jetzt ist es schonmal in etwa so etwas was ich will. Nur fehlt mir noch die Lösch-Funktion für bestimmte Projektile. So wie es jetzt ist, ist es unbrauchbar. Aber es hilft dabei die Liste erstmal nicht überlaufen zu lassen.

Eine Frage hätte ich noch. In der Methode "NeuerSchuss" übergebe ich ja alle Koordinaten, die in anderen Variablen liegen. Ich habe mal gelesen das man das auch irgendwie Speicherschonender übergeben kann. Weiß einer wie, oder ist das so wie ich das mache schon OK so?



// Klasse für den Laser-Schuss
class KSchuss
{
private:
vector<float> XPunkt; // X-Koordinate
vector<float> YPunkt; // Y-Koordinate
vector<float> ZPunkt; // Z-Koordinate
vector<float> XWinkel; // X-Winkel
vector<float> YWinkel; // Y-Winkel
unsigned int Anzahl; // Anzahl der Einträge

public:
KSchuss(); // Konstruktor
~KSchuss(); // Destruktor
void NeuerSchuss(float x, float y, float z, float ywink, float xwink);
void EntferneSchuss();
void ZeichneLaser();
void ErhoeheWerte();
unsigned int LeseAnzahl();
};

KSchuss::KSchuss()
{
KSchuss::Anzahl = 0;
}

KSchuss::~KSchuss()
{
KSchuss::XPunkt.clear();
KSchuss::YPunkt.clear();
KSchuss::ZPunkt.clear();
KSchuss::YWinkel.clear();
KSchuss::XWinkel.clear();
}

void KSchuss::NeuerSchuss(float x, float y, float z, float ywink, float xwink)
{
KSchuss::XPunkt.push_back(x);
KSchuss::YPunkt.push_back(y);
KSchuss::ZPunkt.push_back(z);
KSchuss::YWinkel.push_back(ywink);
KSchuss::XWinkel.push_back(xwink);
KSchuss::Anzahl = KSchuss::Anzahl+1;
}

void KSchuss::EntferneSchuss()
{
KSchuss::XPunkt.pop_back();
KSchuss::YPunkt.pop_back();
KSchuss::ZPunkt.pop_back();
KSchuss::YWinkel.pop_back();
KSchuss::XWinkel.pop_back();
KSchuss::Anzahl = KSchuss::Anzahl-1;
}

void KSchuss::ZeichneLaser()
{
if (KSchuss::Anzahl > 0)
{
glDisable(GL_TEXTURE_2D);
glPushMatrix();
for(unsigned int i=0;i<KSchuss::Anzahl;i++)
{
glPushMatrix();
glTranslatef(-KSchuss::XPunkt[i],-KSchuss::YPunkt[i],-KSchuss::ZPunkt[i]);
glCallList(Laser);
glPopMatrix();
};

if ((KSchuss::XPunkt[0] >= Raumgroesse*2) || (KSchuss::XPunkt[0] <= -Raumgroesse*2))
{
KSchuss::EntferneSchuss(); // Nicht perfekt und völlig falsch hier.
};

glPopMatrix();
glEnable(GL_TEXTURE_2D);
};
}

void KSchuss::ErhoeheWerte()
{
if (KSchuss::Anzahl > 0)
{
for(unsigned int i=0;i<KSchuss::Anzahl;i++)
{
KSchuss::XPunkt[i] -= sin(KSchuss::YWinkel[i]*bog)*AnimaBremse*100.0f;
KSchuss::ZPunkt[i] += cos(KSchuss::YWinkel[i]*bog)*AnimaBremse*100.0f;
};
};
}

unsigned int KSchuss::LeseAnzahl()
{
return KSchuss::Anzahl;
}

//Schussobjekt
KSchuss *Schuss= new KSchuss();