JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=101cb608ed1ad5e45842e2ee37897ca6Medaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Problem beim Löschen aus Vector
Gehe zu Seite Zurück  1, 2, 3
 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
LeeDiGer
Super JLI'ler



Anmeldedatum: 31.08.2003
Beiträge: 366
Wohnort: Duisburg
Medaillen: Keine

BeitragVerfasst am: 24.01.2008, 21:50    Titel: Antworten mit Zitat

Danke für die Blumen Wink

Hier mal ein Beispiel für das erstellen eines Schusses:

CPP:
if(InputManager.LMaus){
   //Schuss erstellen
   m_SWeapon* Temp = new m_SWeapon;
   Temp->Billboard = new CBillboard();

   ...

   listWeapon.push_back(Temp); //Schuss in die Waffenliste einfügen
   listBillboard.push_back(Temp->Billboard); //Billboard in die Billboardliste einfügen
}


Wie man sieht, wird nicht nur der Schuss selbst einer Liste zugeordnet, sondern auch das dazugehörige Billboard. In der Waffenliste werden alle Rechenoperationen für Bewegungen etc. verarbeitet. In der Billboardliste nur das sortieren nach Tiefe und das Rendern.

Und jetzt kommts:
Wenn ich dieses Billboard nicht in eine Separate Liste einfüge und das Rendern in der Waffenliste übernehme, dann gibts keine Zugriffsfehler Wink

Und falls jetzt keiner sowas mal probiert oder ne Idee hat, warum das jetzt nicht gehen kann, was ich vorhabe....wie habt ihr das Scene Management für Billboards mit Alphablending gelöst?

Ist man gezwungen, alle Objekte, die Alphablending benutzen, in eine Liste zu packen und zu sortieren, damit der Z-Buffer keine Probleme bekommt oder hat da jemand eine geschickte Lösung, um die Objekte doch in mehrere Listen zu separieren?
_________________
Kein Rückzug! Kein Aufgeben!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 24.01.2008, 23:55    Titel: Antworten mit Zitat

Wenn du deine Waffe löschst wird dann auch das billboard gelöscht?

So in der Art?
CPP:
m_SWeapon::~m_SWeapon()
{
  ...
  if (Billboard != NULL)
    delete Billboard;
}


Wenn ja würde dies den Fehler erklären.

(Habe nur ab dieser Seite angefangen zu lesen.)
_________________
"I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse."
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
LeeDiGer
Super JLI'ler



Anmeldedatum: 31.08.2003
Beiträge: 366
Wohnort: Duisburg
Medaillen: Keine

BeitragVerfasst am: 25.01.2008, 19:20    Titel: Antworten mit Zitat

Ich glaub, ich benutz nie wieder dynamische Liste. Da geht irgendwie so einiges nicht Wink

Es gibt viele Stellen, wo sich ein Objekt mehrere andere Objekte merken soll: z.B. soll eine Rakete sich ein Ziel merken (ein Raumschiff).
Dafür wird ein Zeiger auf ein Raumschiff gespeichert.
Und das Problem:
Sobald ich aus einer Dynamischen Liste für Raumschiff zufällt das Raumschiff lösche, dass sich die Rakete als Ziel gemerkt hat, wird der Zeiger nicht automatisch auf NULL gesetzt, so dass ich das als Kriterium nehmen kann, sich evt. ein Neues Ziel zu suchen => an der Stelle würde Das Programm einfach abstürzen, weil das Raumschiff nicht als gelöscht erkannt wird.


Und bei dem versuchten Konzept bisher mit der Verknüpfung 2er Liste gibt es entweder Zugriffsfehler oder Buffer Overruns.
Ich glaub ich werd an dieser Stelle auf Arrays umsteigen....auch ,wenn man immer ne Obergrenze für die Anzahl der Elemente hat Wink
_________________
Kein Rückzug! Kein Aufgeben!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 25.01.2008, 21:05    Titel: Antworten mit Zitat

dass der Zeiger nicht automatisch auf NULL gesetzt wird, liegt nicht an den Listen. Dafür bist du selbst verantwortlich(und dafür hast du Destruktoren). Wie sollen die Listen wissen, ob sie an deinen Elementen rumpfuschen sollen oder nicht, ob es Zeiger sind oder nicht(gut, das geht, hat aber nichts hiermit zu tun, da sie ja nicht zwangsläufig modifiziert werden sollen), usw... Außerdem ist das nicht das Konzept dynamischer Listen. Wenn es da Probleme gibt, solltest du dein Design ändern, wie deviloper schon sagte. Du könntest zum Beispiel eine Wrapper Klasse schreiben, die du in den Vector einfgüst, die das dann im Destruktor macht. Am besten zeigst du mal dein Projekt, wenn es dir nichts ausmacht. Mit so einem Text können wir dir leider nicht weit genug helfen.

Gruß DXer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Jonathan_Klein
Living Legend


Alter: 36
Anmeldedatum: 17.02.2003
Beiträge: 3431
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 26.01.2008, 20:55    Titel: Antworten mit Zitat

Da muss man einfach ein wenig nachdenken und sich eine Lösung überlegen.

Du könntest das Raumschiff als tot markieren, es nicht mehr renden und anzeigen. Die Rakete könnte prüfen ob ihr Ziel noch gültig ist (nicht als tot markiert).
Das Raumschiff könnte sich merken, von welchen Raketen es erfasst wurde, und bei der Zerstörung diesen Raketen bescheid sagen.
Gibt bestimmt noch mehr Lösungen.
_________________
https://jonathank.de/games/
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
LeeDiGer
Super JLI'ler



Anmeldedatum: 31.08.2003
Beiträge: 366
Wohnort: Duisburg
Medaillen: Keine

BeitragVerfasst am: 28.01.2008, 23:01    Titel: Antworten mit Zitat

DirectXer hat Folgendes geschrieben:
dass der Zeiger nicht automatisch auf NULL gesetzt wird, liegt nicht an den Listen. Dafür bist du selbst verantwortlich(und dafür hast du Destruktoren).


Klingt logisch, aber wie soll ich bei dem folgenden Problem den passenden Zeiger auf NULL setzen:


Hab jetzt nur mal was zum Testen gebaut....
"Player" ist ein Zeiger auf ein beliebiges Raumschiff.
CPP:
m_SSpaceship* Player; //Spieler

Sinn und Zweck des "Player"-Zeigers ist, dass auf den die Kamera immer für eine Außenansicht gerichtet werden soll.

Wenn ich Return drücke, dann soll ein Raumschiff aus der Liste entfernt werden.
CPP:
it_Spaceships = List_Spaceships.begin();
while(it_Spaceships != List_Spaceships.end())
{
   delete (*it_Spaceships);
   it_Spaceships = List_Spaceships.erase(it_Spaceships);
   if(Player == NULL)
   {
      it_Spaceships++;
      if(it_Spaceships != List_Spaceships.end())
      {
         Player = (*it_Spaceships);
      }
   }
   break;
}

Jetzt hier speziell habe ich 21 Raumschiff eingebaut, wovon beim Programmstart der "Player" auf das 11. Raumschiff zeigt. Wenn ich über 10mal Return drücke, dann würde ich ja das 11. Raumschiff löschen, worauf die Kamera gerichtet ist. Dann soll einfach nur das nächste Raumschiff gewählt werden. Nach welchem Kriterium müsste ich hier dann Player auf NULL setzen?? Das geht ja schlecht im Destruktor von der Struktur für Raumschiffe (struct m_SSpaceship) . Im Destruktur kann man sich nicht selbst auf NULL setzen, oder???

Hinweis: In den If-Block kommt das Programm niemals rein.

Sowas hab ich auch probiert:
CPP:
(*it_Spaceships) = NULL;


Nur, da weiß "Player" natürlich immer noch nicht, dass er auch auf NULL zeigen sollte.[/cpp]
_________________
Kein Rückzug! Kein Aufgeben!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 29.01.2008, 07:47    Titel: Antworten mit Zitat

Wozu hälst du seperat zu den Raumschiffen überhaupt noch ein Raumschiff in der seperaten variable "Player"?

Würde doch ausreichen wenn du der Raumschiffklasse eine simple Bool variable gibst wie bool mb_IsControlledByPlayer findest du beim durchgehen kein Raumschiff bei dem der Flag gesetzt ist brauchst du den Player nicht steuern bzw weisst das der Player tot ist.

Ausserdem wäre es evtl eine gute Sache für deine Probleme mit "Was passiert wenn ich ein Objekt lösche aber ein anderes hält noch einen Verweis auf dieses Objekt?" eine Art Observer zu basteln, der auf das löschen der Objekte reagiert.

CPP:
class Observer
{
  public:
  virtual ~Observer()
  {
    for (int i=0; i<ObserverList.size(); ++i)
      ObserverList[i].OnObserverDeleted(this);
  }
  void AddObserver(Observer* newObserver) {...}
  void RemoveObserver(Observer* newObserver) {...}
  virtual void OnObserverDeleted(Object* deletedObserver)
  {
    std::vector<Observer*>::iterator Iter = std::find(ObserverList.begin(), ObserverList.end(), deletedObserver);
    if (Iter != ObserverList.end())
      ObserverList.erase(Iter);
  }
};


Nun einfach deine Raumschiffe oder sonst was vom Observer ableiten lassen und OnObserverDeleted überladen sowie deine Dtors virtuell halten. So solltest du mitbekommen können wann zb dein Player Raumschiff gelöscht wird und kannst dementsprechend darauf reagieren.

CPP:
Raumschiff::OnObserverDeleted(Observer* deletedObserver)
{
  Observer::OnObserverDeleted(deletedObserver);
  if (Aitarget == deletedObserver)
  {
    Aitarget = this->SearchAitarget();
  }
}

_________________
"I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse."
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
LeeDiGer
Super JLI'ler



Anmeldedatum: 31.08.2003
Beiträge: 366
Wohnort: Duisburg
Medaillen: Keine

BeitragVerfasst am: 29.01.2008, 19:45    Titel: Antworten mit Zitat

Zitat:
Wozu hälst du seperat zu den Raumschiffen überhaupt noch ein Raumschiff in der seperaten variable "Player"?

Würde doch ausreichen wenn du der Raumschiffklasse eine simple Bool variable gibst wie bool mb_IsControlledByPlayer findest du beim durchgehen kein Raumschiff bei dem der Flag gesetzt ist brauchst du den Player nicht steuern bzw weisst das der Player tot ist.

Ist ne Möglichkeit ,aber ich finds praktisch, weil ich mit den Werten von "Player" nicht mehr an diese Aufrufschleife gebunden bin und auch an anderen Stellen ggf, darauf zugreifen kann. Aber das nur mal am Rande....

Aber für Raketen wäre das optimal, weil ich nicht in jedem Frame die komplette Raumschiffsliste wieder durchlaufen brauch. Das würde sonst in einem exponentiellen Aufwand arten.

Bin mir nicht sicher, ob ich deine Observerklasse ganz verstanden habe, aber das sieht mir auch so aus, als würde da ein exponentieller Aufwand sein....falls nicht , dann nehm ichs zurück und hoffe auf Erläuterung der Funktionalität.

Ansonsten habe ich mir ne Alternative überlegt:
Ich speicher ein zusätzliches Attribut "BOOL Delete". z.B. wird ein Raumschiff zerstört, weil Schutzschilde und Panzerung auf Null geschossen wurden. In diesem Fall soll "Delete" auf true gesetzt werden. Eine Schleife, die nix anderes tut ,als eine Löschung zu überprüfen, löscht in jedem Schleifendurchgang alle Raumschiffe, bei denen "Delete" auf true gesetzt ist.

Und jetzt der Clou: Bevor das betroffene Raumschiff gelöscht wird, kann jeder Zeiger, der auf das Raumschiff noch zugreift, das "Delete" state abrufen und ggf. den Zeiger auf NULL setzen. Hab ich alles durchgetestet und funktioniert....und das auf jedenfall ohne exponentiellen Aufwand.
_________________
Kein Rückzug! Kein Aufgeben!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 29.01.2008, 22:24    Titel: Antworten mit Zitat

LeeDiGer hat Folgendes geschrieben:
Ansonsten habe ich mir ne Alternative überlegt:
Ich speicher ein zusätzliches Attribut "BOOL Delete". z.B. wird ein Raumschiff zerstört, weil Schutzschilde und Panzerung auf Null geschossen wurden. In diesem Fall soll "Delete" auf true gesetzt werden. Eine Schleife, die nix anderes tut ,als eine Löschung zu überprüfen, löscht in jedem Schleifendurchgang alle Raumschiffe, bei denen "Delete" auf true gesetzt ist.

Und jetzt der Clou: Bevor das betroffene Raumschiff gelöscht wird, kann jeder Zeiger, der auf das Raumschiff noch zugreift, das "Delete" state abrufen und ggf. den Zeiger auf NULL setzen. Hab ich alles durchgetestet und funktioniert....und das auf jedenfall ohne exponentiellen Aufwand.


Genau das tut die Observerklasse von mir, sobald ein Objekt gelöscht wird das sich in einem Observer registriert hat wird OnObserverDeleted aufgerufen, dort kannst du nun alle verweise auf das zerstörte Objekt auf NULL setzen, hier ein Beispiel:

CPP:
Raumschiff::SucheFeind()
{
  ... // suchen
  if (AktuellerFeind != NULL)
    AktuellerFeind->RemoveObserver(this); // alter AktuellerFeind braucht nicht mehr überwacht werden
  AktuellerFeind = GefundenerFeind;
  if (AktuellerFeind != NULL)
    AktuellerFeind->AddObserver(this); // neuer AktuellerFeind muss überwacht werden
}

Raumschiff::OnObserverDeleted(Object* deletedObserver)
{
  Observer::OnObserverDeleted(deletedObserver); //Parentklasse soll das auch verarbeiten, zwecks Austragen aus der Liste
  if (deletedObserver == AktuellerFeind)
    AktuellerFeind = NULL;  // später kann ein neuer Feind gesucht werden
  ... // weitere Dinge erledigen
}


Die Raumschiff Klasse sollte btw ungefähr so aussehen:
CPP:
class Raumschiff : public Observer
{
public:
  virtual ~Raumschiff();
  ...
};


Sobald du also irgendein eine RaumschiffInstanz löschst (delete RaumschiffAlpha) wird der DTor von der Observerklasse aufgerufen und benachrichtigt alle Observer die sich an der aktuell zu zerstörenden Instanz registriert haben.
_________________
"I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse."
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
LeeDiGer
Super JLI'ler



Anmeldedatum: 31.08.2003
Beiträge: 366
Wohnort: Duisburg
Medaillen: Keine

BeitragVerfasst am: 30.01.2008, 00:41    Titel: Antworten mit Zitat

Also angenommen, du hast da ne ziemlich Große Liste an Raumschiffen, die jeweils ein Zeiger auf ein anderes zeigt. Dann müsste man für jedes Raumschiff ein Observer erstellen, richtig?
Und wenn ein Raumschiff gelöscht wird, dann wird die komplette Raumschiffs liste durchgegangen und die entsprechenden Zeiger auf NULL gesetzt, wenn ich das richtig verstehe. Klingt für mich nach exponentiellem Aufwand.

Aber jetzt hab ich ne andere Herausforderung:
Wenn jetzt jedes Raumschiff ein Gegner angepeilt hätte und es möchte einer von denen sein Ziel wechseln... wie könnte man mit dem aktuellen Zeiger zum nächsten Objekt übergehen? Ist man gezwungen, die komplette Raumschiffsliste durchzugehen und zum aktuell angepeilten Objekt zu gehen und erst dann den Iterator zu inkrementieren? Bzw. analog dekrementieren, wenn man ein vorheriges Objekt anpeilen will?


Sowas in der Art habe ich mal probiert...aber vielleicht gibts ja ne geschicktere Lösung.

CPP:
//Gegner anpeilen
for(it_Spaceships = List_Spaceships.begin(); it_Spaceships != List_Spaceships.end(); it_Spaceships++)
{
   if((*it_Spaceships)->Mesh.m_Delete == FALSE)
   {
      if(Opponent == (*it_Spaceships))
      {            
         vector<m_SSpaceship*>::iterator it_TEMP; //Iterator der Spaceships   
         //Nächsten Gegner wählen, der nicht Typ=0 ist
         for(it_TEMP = ++it_Spaceships; it_Spaceships != List_Spaceships.end(); it_Spaceships++)
         {
            if((*it_Spaceships)->iType == 1)
            {
               Opponent = *it_Spaceships;
               break;
            }
         }
         break;
      }
   }
}

_________________
Kein Rückzug! Kein Aufgeben!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 30.01.2008, 07:44    Titel: Antworten mit Zitat

Zitat:
Also angenommen, du hast da ne ziemlich Große Liste an Raumschiffen, die jeweils ein Zeiger auf ein anderes zeigt. Dann müsste man für jedes Raumschiff ein Observer erstellen, richtig?
Und wenn ein Raumschiff gelöscht wird, dann wird die komplette Raumschiffs liste durchgegangen und die entsprechenden Zeiger auf NULL gesetzt, wenn ich das richtig verstehe. Klingt für mich nach exponentiellem Aufwand.


Jedes Raumschiff ist ein Observer, durch die vererbung bedingt. Wird ein Observer/Raumschiff zerstört werden nur die Observer/Raumschiffe darüber in kenntniss gesetzt die sich dafür interessieren, ich wüsste jetzt nicht weshalb ein Raumschiff jedes andere Raumschiff sepert speichern sollte, wenn einem raumschiff die Liste aller anderen Raumschiffe interessiert so kann er dafür ja sicher die Hauptliste nutzen.

Zitat:
Aber jetzt hab ich ne andere Herausforderung:
Wenn jetzt jedes Raumschiff ein Gegner angepeilt hätte und es möchte einer von denen sein Ziel wechseln... wie könnte man mit dem aktuellen Zeiger zum nächsten Objekt übergehen? Ist man gezwungen, die komplette Raumschiffsliste durchzugehen und zum aktuell angepeilten Objekt zu gehen und erst dann den Iterator zu inkrementieren? Bzw. analog dekrementieren, wenn man ein vorheriges Objekt anpeilen will?


Weshalb nimmt es das nächste Raumschiff in der Liste und nicht das Raumschiff was die grösste Bedrohung für ihn darstellt, nur mal als Beispiel. Ansonsten kannst du ja den Iterator auch als Membervariable speichern, solange du aufpasst das er nicht ungültig wird kannst du diesen ja problemlos weiter benutzen. Alternativ kannst du auch einfach nur wie bisher den Pointer selber speichern und den Iterator in der Liste mit std::find suchen. Wenn du noch einen Vergleichsoperator erstellt hast und die Liste vorher sortiert wurde sollte der Iterator auch schnell gefunden werden können.

mfg Mark
_________________
"I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse."
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
LeeDiGer
Super JLI'ler



Anmeldedatum: 31.08.2003
Beiträge: 366
Wohnort: Duisburg
Medaillen: Keine

BeitragVerfasst am: 03.02.2008, 21:46    Titel: Antworten mit Zitat

Zitat:
Weshalb nimmt es das nächste Raumschiff in der Liste und nicht das Raumschiff was die grösste Bedrohung für ihn darstellt, nur mal als Beispiel

Joa, in der Praxis würd ichs so machen. Nur für den Fall der Fälle wollte ich eben eine Funktion haben, um Objekte einer Liste durchzuselektieren. Und das dann noch im Loop-Modus, d.h. wenn ich beim letzten Element angelangt bin, soll der Zeiger wieder zum ersten Element springen.

Zitat:
Wenn du noch einen Vergleichsoperator erstellt hast und die Liste vorher sortiert wurde sollte der Iterator auch schnell gefunden werden können.

Solange man davon ausgehst, dass der Spieler gegen den Rest der Welt agiert, kann man sortieren...aber wenn Jedes Objekt jeden anpeilen will, dann weiß ich nicht, ob jedesmal eine Vorsortierung so toll wär Wink
_________________
Kein Rückzug! Kein Aufgeben!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung Alle Zeiten sind GMT
Gehe zu Seite Zurück  1, 2, 3
Seite 3 von 3

 
Gehe zu:  
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

Impressum