Hallo liebe Forumbesucher,
Erstmal möchte ich mich entschuldigen, dass ich ein Thema anspreche, zu dem es bereits Forenbeiträge gibt. Allerdings taucht dieses konkrete Problem meist erst auf der 2. Seite irgendwo versteckt auf und wurde nicht gelöst, weshalb ich diesen Beitrag noch einmal getrennt eröffnen möchte.
Als ich versucht habe die Kollision von Spieler und Asteroiden einzubauen bin ich in eine kleine Falle gelaufen. Ich habe die Breite des Raumschiffs versucht aus dem zugehörigen Sprite auszulesen, habe dabei aber die Breite des ganzen Bildes (alle Teile der Animation in einer langen Reihe) ausgelesen. Das erhält man mittels m_pSpritePlayer->GetRect().w, für den richtigen Wert muss man sich erst eine eigene Funktion bauen, die die Breite des Rects m_FrameRect ausliest, ich habe die Breite des Raumschiffs einfach konstant auf 64 gesetzt, nicht schön, aber funktioniert.
So weit alles schön und gut. Die große Frage, die sich mir dann aber gestellt hat war "Wie wurde das eigentlich bei den Asteroiden gemacht?", denn da sollte ja das gleiche Problem auftreten. Bei den Asteroiden passiert aber etwas ganz witziges. Die Breitenzuordnung sieht folgendermaßen aus:
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
|
void CAsteroid::Init (CSprite *pSpriteAsteroid, float fXPos, float fYPos)
{
.
.
.
m_Rect.w = pSpriteAsteroid->GetRect().w;
m_Rect.h = pSpriteAsteroid->GetRect().h;
.
.
.
} // Init
|
GetRect wiederum ist eine einfache Funktion des Sprites
|
C-/C++-Quelltext
|
1
|
SDL_Rect GetRect () {return m_Rect;}
|
und in der Variable m_Rect sollten eigentlich die Maße des gesamten Bildes geladen werden, also in diesem Fall sollte die Breite des Kometen auf 640 (Gesamtbreite der 10 Bilder hintereinander) und nicht 64 (Breite eines Ausschnitts des Kometenbildes) gesetzt werden.
Lustigerweise passiert das auch, aber nur beim allerersten Kometen.
Das haben sowohl Debugger als auch eine kleine Testausgabe bestätigt:
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
void CGame::CheckCollisions ()
{
.
.
.
while (ItAsteroid != m_AsteroidList.end () )
{
// Rect des Asteroiden holen
RectAsteroid = ItAsteroid->GetRect ();
cout << RectAsteroid.w;
.
.
.
} // CheckCollision
|
Wenn man diese kleine Zeile einfügt hat man nach Beenden des Spiels in der Konsole etwas in der Art:
640640640640640640640640640640640640640640640640640640640646406464064640646406464064....
stehen. Das ist jetzt nicht sehr hübsch, aber wer genau hinschaut sieht, dass der erste Komet Breite 640 hat und der 2. (und wenn man es etwas weiter laufen lässt sieht man, dass das auch für alle weiteren gilt) hat Breite 64.
Das lässt sich auch nochmal etwas besser mit dem Debugger überprüfen.
Die große Frage ist jetzt: Wie kommt das Zustande?
1. Was unterscheidet den 1. Kometen von allen weiteren
2. Wo kommt die 64 der späteren Kometen her? Nach meiner Ansicht müsste diese Breite immer bei 640 liegen.
Ich weiß, dass diese Frage nicht zu beantworten ist ohne den kompletten Code des Spiels in Kapitel 12 zu kennen. Da ich aber wirklich keine Ahnung habe wo der Fehler liegt, kann ich auch nicht wirklich mehr Code posten um das Problem deutlicher zu erklären. Unter
http://downloads.hanser.de/getDoc.asp?doc_id=21351514131-27 kann man alle Codebeispiele runterladen und im Ordner Quellcode/Visual Studio/Kapitel 12/SDL_Game findet man den Code des gesamten Projekts. Allerdings hoffe ich im Moment eher darauf, dass mir jemand die Frage beantworten kann, der sich bereits diesem Code beschäftigt hat. Sonst ist der Aufwand wahrscheinlich zu groß.
Ich habe mir schon eine ganze Weile den Kopf darüber zerbrochen, aber da dies offenbar ein bug ist, der auch in der 4. Auflage des Buches noch vorhanden ist (oder einfach ignoriert wurde?) ist das Problem vielleicht auch eher subtil. Ich hoffe einfach, dass sich hier ein paar sehr kluge Leute herumtreiben, die mir helfen können
Und nochmal um das klar zu machen: Dieses Problem entsteht wenn man den heruntergeladenen Originalcode aus dem Buch ungeändert (abgesehen von der Überprüfungsausgabe) laufen lässt, es ist also kein Fehler, den ich persönlich gemacht habe. Man sieht auch ein Symptom dieses Fehlers, wenn man mal versucht den ersten Kometen abzuschießen. Das klappt nämlich auch, wenn man ein gutes Stück weit weg ist.
Viele liebe Grüße
Anna