 |
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Mr.Matze Mini JLI'ler

Alter: 33 Anmeldedatum: 05.07.2006 Beiträge: 27 Wohnort: Neustadt a. d. Weinstraße Medaillen: Keine
|
Verfasst am: 15.08.2006, 19:16 Titel: Problem |
|
|
Hallo,
ich habe ein Problem. Ich versuche ein Breakout spiel zu programmieren. Ich speiche einen Zeiger zu jedem Sprite in einem Vector. Und ich habe einen Vector in dem zu jedem Sprite ein Typ gespeichert wird, also wenn ich einen Ball erstell z.B. typ 2.
Ich möchte, wenn ein Ball unter dem Bildschirm ist ( y < Screen_width), dass er gelöscht wird das mache ich so:
Code: |
if(Ball[ k ]->y_pos > 600)
{
delete Object[ tmp ];
delete Ball[ k ]; //Ein Vektor mit dem Zeiger auf eine Strucktur, die die Geschwindigkeit und Position des Balles speichert
typ[ tmp ] = 0; //tmp ist der index des Objektes im Sprite Vector
ball_id[ k ] = 0; //k ist der wert der in einer for schleife alle Bälle durchläuft, ball id (das was tmp zugewiesen wurde)
m_balls --;
if(m_balls == 0)
{
return TRUE;
}
}
|
Später durchlaufe ich jedes Sprite in einer Schleife und wenn typ[ i ] != 0 dann wird es gezeichnet. Wenn der Ball gelöscht wird und dann neu gezeichnet. Stürtzt das Programm ab mit dem Fehler "Unbehandelte Ausnahme in Sample.exe 0xC0000005 acces Violtation. Ich denke, es hat was mit dem Vector zu tun, aber ich komm net drauf. Ich hab versucht, jedesmal wenn das Programm das Sprite zeichnet, zu schauen, ob es das Object wirklich gibt, oder ob es eben halt gelsöcht wurden. Das merkwürdige ist nur, komma wenn ich jedes mal anhalt Funktioniert es. Ich versteh's net ich hofffe ihr könnt mir helfen.
Das ist der Gesamte Code des Gamemanagers:
CPP-File meiner Klasse
http://rafb.net/paste/results/d1Notj45.html
H-File meiner Klasse
http://rafb.net/paste/results/7FczRa31.html
Ich hoffe ihr könnt mir Helfen und danke schonmal
Grüße
Matze _________________ Bitte besucht meine Webiste:
www.m-soft.de.tp
www.der-sternschnuppen-gruss.de.tp |
|
Nach oben |
|
 |
manu Super JLI'ler

Alter: 35 Anmeldedatum: 09.03.2006 Beiträge: 327 Wohnort: allgäu (DE) Medaillen: Keine
|
Verfasst am: 15.08.2006, 20:07 Titel: |
|
|
CPP: | if(Ball[ k ]->y_pos > 600)
{
delete Object[ tmp ];
delete Ball[ k ];
typ[ tmp ] = 0;
ball_id[ k ] = 0;
m_balls --;
if(m_balls == 0)
{
return TRUE;
}
}
//Bewegen
Ball[ k ]->x_pos += Ball[ k ]->x_speed / fps ;
Ball[ k ]->y_pos += Ball[ k ]->y_speed / fps; |
wenn ball k gelöscht wird, wird er doch dannach trotzdem bewegt. Könnte das nicht einen derartigen fehler verursachen? oder gibt es immer nur einen Ball, sodass nach dem Löschen die anzahl der Bälle zwangsläufig 0 ist? |
|
Nach oben |
|
 |
Jonathan_Klein Living Legend

Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 15.08.2006, 20:13 Titel: |
|
|
Jo, ich würds so machen. Eien Schleife für z.b. alle Bälle. Dadrinne danne rst den Ball bewegen und wenn er ungültig ist, dann löschen. Erst löschen und dann Bewegen ist entscheidend schlechter^^ _________________ https://jonathank.de/games/ |
|
Nach oben |
|
 |
The Lord of Programming Living Legend

Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 16.08.2006, 00:05 Titel: |
|
|
Hmm...löschen über delete solltest du wirklich nur einsetzen, wenn dus auch per new erstellt hast!
Bei Vectoren funktioniert das allerdings anders. Der Vector kümmert sich selbst ums erstellen, also kümmert er sich auch ums löschen. Natürlich kannst du das auch manuell machen, aber nicht per delete, sondern über die Elementfunktion erase:
CPP: | //Vector mit 20 Elementen
std::vector<int> myvector(20);
std::vector<int>::iterator it_integer;
//Vector von vorne bis hinten durchgehen
for(it_integer=myvector.begin(); it_integer!=myvector.end(); )
{
//Element soll gelöscht werden
if(whatever)
{
//Element löschen, auf das der Iterator zeigt
//Wichtig ist, dass der Rückgabewert der Elementfunktion erase() dem Iterator zugewiesen wird. Andernfalls zeigt der Iterator ins Leere.
//Der Iterator zeigt nach dem Löschen auf das Element NACH dem gelöschten
it_integer=myvector.erase(it_integer);
}
//WICHTIG: NUR Iterator inkrementieren, wenn du kein Element löschst, das erledigt schon die Zuweisung des Rückgabewerts.
//Andernfalls gibt es wieder eine Zugriffsverletzung, wenn zufällig das letzte Element gelöscht wird.
//Dann bist du durch die Zuweisung des Rückgabewerts schon bei myvector.end().
//Ein Inkrementieren dieses Iterators endet eben in dieser Zugriffsverletzung.
else it_integer++;
} |
(Hab das jetzt nur so schnell aus dem Kopf getippt, hoffe ist kein Fehler drin...) _________________ www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console
Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet... |
|
Nach oben |
|
 |
David Super JLI'ler
Alter: 40 Anmeldedatum: 13.10.2005 Beiträge: 315
Medaillen: Keine
|
Verfasst am: 16.08.2006, 06:42 Titel: |
|
|
Hi!
Das ist natürlich blanker Unsinn. Er hat ein Vektor welcher Zeiger auf Objekte aufnimmt. Diese Objekte müssen natürlich manuell erstellt und später auch gelöscht werden.
Solltest du vergessen den Speicher auf ein gezeigtes Element freizugeben bevor du den Eintrag aus dem Vektor löschst wirst du die tollsten Speicherleaks bekommen.
grüße |
|
Nach oben |
|
 |
The Lord of Programming Living Legend

Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 16.08.2006, 06:52 Titel: |
|
|
Noja, hab mir jetzt auch nicht den ganzen Code angesehen.
Wenn er den Speicher per delete wieder freigibt, aber das Element immer noch im Vector bestehen bleibt(wenn mich nicht alles täuscht, bleibt es bei ihm bestehen), dann bekommt er beim nächsten Zugriff auf das Element Probleme.  _________________ www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console
Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet... |
|
Nach oben |
|
 |
Mr.Matze Mini JLI'ler

Alter: 33 Anmeldedatum: 05.07.2006 Beiträge: 27 Wohnort: Neustadt a. d. Weinstraße Medaillen: Keine
|
Verfasst am: 16.08.2006, 11:11 Titel: |
|
|
Also es wird ja geprüft ob das object gültig ist mit if(typ[ i ] != 0)
Es gibt 2 vectoren der Vector in dem das Object ist und " parallell" dazu ein Vector, indem der typ des Objectes gespeichert wird. Ich lasse jedes Object aus, dass den Typ 0 hat, was bei mir gelöscht heißt.
Zu dem mit den Speicherlecks, heißt das ich muss dies earse Funktion aufrufen, sonste geht's net? Muss ich dann delete UND earse benutzen oder nur earse, und welches muss ich dazu erst benutzten?
Sollte ich die for-Schleife behalten, oder das ganze über diee Iteratoren machen??
Edit.:@manu, du hast recht, aber der Fehler ist mir net aufgefallen, da ich nur einen Ball als Test hatte. Aber das war nicht der Fehler
Grüße
Matze _________________ Bitte besucht meine Webiste:
www.m-soft.de.tp
www.der-sternschnuppen-gruss.de.tp |
|
Nach oben |
|
 |
David Super JLI'ler
Alter: 40 Anmeldedatum: 13.10.2005 Beiträge: 315
Medaillen: Keine
|
Verfasst am: 16.08.2006, 11:40 Titel: |
|
|
Mal davon abgesehen das diese 1000 parallelen Vektoren ziemlich unsinnig sind (du könntest das bestimmt auch mit einem Vektor lösen) musst du erst den Speicher freigeben und kannst dann das Element aus dem Vektor entfernen (per erase).
grüße |
|
Nach oben |
|
 |
Jonathan_Klein Living Legend

Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 16.08.2006, 15:16 Titel: |
|
|
außerdem empfiehlt es sich ein einem soclehn Falle eine List zu benutzen, den die ist eher darauf ausgelegt, das in der mitte was entfertn wird oder dazu kommt. _________________ https://jonathank.de/games/ |
|
Nach oben |
|
 |
David Super JLI'ler
Alter: 40 Anmeldedatum: 13.10.2005 Beiträge: 315
Medaillen: Keine
|
Verfasst am: 16.08.2006, 16:05 Titel: |
|
|
Jonathan_Klein hat Folgendes geschrieben: | außerdem empfiehlt es sich ein einem soclehn Falle eine List zu benutzen, den die ist eher darauf ausgelegt, das in der mitte was entfertn wird oder dazu kommt. |
Das wird bei drei Bällen nicht sehr ins Gewicht fallen, allerdings hast du natürlich Recht das eine verlinkte Liste in solchen Fällen geeigneter ist.
grüße |
|
Nach oben |
|
 |
DirectXer Dark JLI'ler

Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 19.08.2006, 15:49 Titel: |
|
|
Mr.Matze hat Folgendes geschrieben: | Zu dem mit den Speicherlecks, heißt das ich muss dies earse Funktion aufrufen, sonste geht's net? Muss ich dann delete UND earse benutzen oder nur earse, und welches muss ich dazu erst benutzten? |
zuerst delete (sofern der Vektor auch aus Zeigern besteht denen mit new Speicher zugewiesen wurde) dann erase (wenns das letzte Objekt ist, ist pop_back() noch besser), damit aus dem Vektor auch alle schon zerstörten Objekte weg sind. Hat keinen Sinn, zerstörte Objekte im Vektor zu haben, IMHO. Warum diese Reihenfolge? Deshalb:
CPP: | // step 1: neues Objekt in den Vektor einfügen
vec.push_back()
// step 2: neuem Objekt Speicher zuweisen (x = die Nummer des neuen Objekts, Foo = irgendeine Klasse)
vec[x] = new Foo;
// das Ganze ginge auch etwas schneller durch vec.push_back( new Foo );
// step 3: neues Objekt löschen; das = 0 ist in diesem Fall eigentlich
// unnötig, sollte man aber trotzdem dran denken, lieber einmal zu viel
// nullen als einmal zu wenig
delete vec[x];
vec[x] = 0;
// step 4: das Objekt aus dem Vektor entfernen(wenns das letzte is, so:).
vec.pop_back(); //im Grunde dasselbe wie vec.erase( vec.end() );
|
Muss man sich halt klarmachen, das is so wie wenn du eine Hülle und einen Kern hast(also 2 Schichten, die eine ist umhüllt von der anderen). Der Kern ist in der Hülle. Wenn du die Hülle entfernst kommst du net mehr an den Kern ran (der Speicher des Objekts ist zwar noch reserviert, aber unzugänglich) Musst also erst den Kern entfernen, dann die Hülle.
Mr.Matze hat Folgendes geschrieben: | Sollte ich die for-Schleife behalten, oder das ganze über diee Iteratoren machen?? |
eigentlich brauchst du nur die for-Schleife, da der []-Operator intern sowieso mit Iteratoren arbeitet. Erst wenn du ein Objekt in der Mitte des Vektors löschen willst, musst du einen Iterator auf dieses haben, da du vector::erase() diesen Iterator und damit die Position des Objekts übergeben musst.
Gruß DXer |
|
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
|