Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

03.06.2010, 22:25

Kap. 12: Zusammenstoß Asteroid-Spieler

hallo

ich habe das buch durchgearbeitet und soweit verstanden. als erweiterung des 12. kapitels wollte ich beginnen, dem spiel einen sinn zu geben: wenn der Spieler gegen einen Asteroiden fliegt, soll er eines seiner 3 Leben verlieren und der Asteroid explodieren - bzw zuerst einmal nur verschwinden.
so habe ich es geschrieben:

Zitat

void CGame::CheckCrash ()
{
list<CAsteroid>::iterator ItAsteroid = m_AsteroidList.begin ();

SDL_Rect RectAsteroid;
SDL_Rect RectPlayer;

RectPlayer = m_pPlayer -> GetRect();

while (ItAsteroid != m_AsteroidList.end())
{
RectAsteroid = ItAsteroid -> GetRect();

if (((RectPlayer.x >= RectAsteroid.x && RectPlayer.x <= RectAsteroid.x + RectAsteroid.w) ||
(RectPlayer.x + RectPlayer.w >= RectAsteroid.x && RectPlayer.x + RectPlayer.w <= RectAsteroid.x + RectAsteroid.w)) &&
RectPlayer.y <= RectAsteroid.y + RectAsteroid.h)

{
ItAsteroid -> SetAlive (false);
m_pPlayer -> loseLive();
}

if (ItAsteroid -> IsAlive())
ItAsteroid++;
else ItAsteroid = m_AsteroidList.erase (ItAsteroid);
}
}
Bei der Klasse CPlayer habe ich die hier folgend grünen Zeilen hinzugefügt...

Zitat

class CPlayer
{
public:
CPlayer ();

SDL_Rect GetRect()
{return m_Rect;}

void Init ();
void Quit ();
void Render ();
void Update ();
void Reset ();
void loseLive()
{m_Lives --;}
int m_getLives()
{return m_Lives;}
list<CShot> *GetShotList () {return &m_ShotList;}


private:
void ProcessMoving ();
void ProcessShooting ();
void CheckPosition ();

CSprite *m_pSpritePlayer; // Sprite für Spieler
CSprite *m_pSpriteShot; // Sprite für Laserschüsse
float m_fXPos; // X-Position des Spielers
float m_fYPos; // Y-Position des Spielers
float m_fAnimPhase; // Aktuelle Animationsphase
bool m_bShotLock; // Darf der nächste Schuss raus?
list<CShot> m_ShotList; // Liste der Schüsse
int m_Lives;
SDL_Rect m_Rect;


};

Am Ende von CGame::Run() habe ich noch

Zitat

if (m_pPlayer -> m_getLives() == 0)
m_bGameRun = false;
hinzugefügt.
Leider ändert das im Spiel aber nichts. Ich kann weiterhin muter durch Asteroiden fliegen, so lange ich will.
Was fehlt hier noch?
lg und danke schonmal =)

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

2

04.06.2010, 08:37

schau dir nochmal die kollisionsabfrage an. auf seite 436(2. erweiterte auflage) steht die lösung.

versuch dir eine funktion zu schreiben der du referenzen auf die rect´s übergibst und ein bool wert zurück gibt. so musst du das nicht immer wieder schreiben.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

little_Progger

Treue Seele

Beiträge: 188

Wohnort: Nähe Bielefeld

Beruf: Azubi

  • Private Nachricht senden

3

04.06.2010, 15:15

Was soll den das "oder" || in der Kollisionsabfrage bringen wenn ich mal fragen darf?!
Du kannst dir die komplette Kollisionsabfrage theoretisch kopieren und einfach über all das Rect des Spieler mit dem des Schusses austauschen.

EDIT---

Hab mir grad nochmal die Kollisionsabfrage angeschaut und mir is aufgefallen das die eig. komplett für die Tonne ist.
1. Nächstes mal bitte mit dem Editor -> Button -> C/C++ Quelltext -> "Hier Quelltext einfügen" ins Forum da die Kollisionsabfrage schon passend formatiert nicht sonderlich leicht zu durchschauen ist.
und 2. Kopier dir die ganze Kollisionsabfrgae aus dem Buch und mach dir genau klar was genau was macht in der Abfrage.

Gruß

4

04.06.2010, 19:11

okay, ich hab die kollisionsabfrage jetzt geändert. das hatte ich auch schonmal so, aber es passiert eben im spiel trotzdem nichts.
irgendwo muss noch ein anderer fehler sein bwz etwas fehlen...

little_Progger

Treue Seele

Beiträge: 188

Wohnort: Nähe Bielefeld

Beruf: Azubi

  • Private Nachricht senden

5

04.06.2010, 21:27

Zeig mal deinen Quelltext wie er jetzt auf dem neustem Stand ist.
Aber diesmal mit C++ Quelltext formatierung.

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

6

04.06.2010, 21:33

ganz dooofe frage... wird die funktion CheckCrash() überhaupt jedes frame aufgerufen?

ich find deine vielen leerzeichen komisch *grins*
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

7

04.06.2010, 22:43

checkcrash:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void CGame::CheckCrash ()
{
    list<CAsteroid>::iterator ItAstCrash = m_AsteroidList.begin ();

    SDL_Rect RectAsteroid;
    SDL_Rect RectPlayer;

    RectPlayer = m_pPlayer -> GetRect();

    while (ItAstCrash != m_AsteroidList.end())
    {
        RectAsteroid = ItAstCrash -> GetRect();

        if (RectPlayer.y < RectAsteroid.y + RectAsteroid.h &&
        RectPlayer.y + RectPlayer.h > RectAsteroid.y &&
        RectPlayer.x < RectAsteroid.x + RectAsteroid.w &&
        RectPlayer.x + RectPlayer.w > RectAsteroid.x)


        {
            ItAstCrash -> SetAlive (false);
            m_pPlayer -> loseLive();
        }

        if (ItAstCrash -> IsAlive())
            ItAstCrash++;
        else
            ItAstCrash = m_AsteroidList.erase (ItAstCrash);
    }
}

und ja, die wird jeden frame aufgerufen, direkt nach dem CheckCollision für das Abschießen eines Asteroiden.

mit vielen leerzeichen finde ich es persönlcih übesichtlicher ;)

den boolean collision habe ich auch mal geschrieben, aber wenn ich ihn bei der von der CD vorgegebenen funktion CheckCollision einfüge, kommen seltsame compiler-fehler^^

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
bool Collision(SDL_Rect Rect1, SDL_Rect Rect2)
{
    if (Rect1.y < Rect2.y + Rect2.h &&
        Rect1.y + Rect1.h > Rect2.y &&
        Rect1.x < Rect2.x + Rect2.w &&
        Rect1.x + Rect1.w > Rect2.x)
          return true;
    else return false;
}


den habe ich in CGame geschrieben. eigentlich müsste es doch dann bool CGame::Collision heißen oder? uneingebaut führt diese version habe zu keinem fehler .(??)

in CheckCollision eingebaut kommen folgende Fehler:

Game.obj : error LNK2001: Nichtaufgeloestes externes Symbol "private: bool __thiscall CGame::Collision(struct SDL_Rect,struct SDL_Rect)" (?Collision@CGame@@AAE_NUSDL_Rect@@0@Z)

und

Debug/SDL_Game.exe : fatal error LNK1120: 1 unaufgeloeste externe Verweise


ou man der einstieg in diese welt ist echt hart ..^^

wenn jemand zwar nicht weiß, wo mein fehler liegt, aber es selbst schonmal gemacht hat (was bei vielen denke ich der fall sein wird) , könnte seine methode und sonstige veränderungen vielleicht einfach mal posten bzw mir schicken, dann könnte ich auch selbst gucken, was ich falsch gemacht habe.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »bewa« (04.06.2010, 23:06)


little_Progger

Treue Seele

Beiträge: 188

Wohnort: Nähe Bielefeld

Beruf: Azubi

  • Private Nachricht senden

8

05.06.2010, 00:15

Also ich würde dir erstmal raten auch wenns blöd klingt, dass du das ganze nochmal löscht.
Ich habe meine Kollisionsabfragen in der Vorgegebenen Funktion bearbeitet da es doch übersichtlicher ist als wenn du einen Funktions Krieg nur wegen einer weiteren Kollisionsabfrage anfängst.
Belass es lieber bei der einen weiteren Funktion die dir das Rect des Spielers sendet.

Deine bool Funktion kannst du einfacher schreiben.

Und ja MIT "CGame::" sofern du diese Funktion auch in selbiger Klasse geschrieben hast!

C-/C++-Quelltext

1
2
3
4
5
6
7
bool CGame::Collision(SDL_Rect Rect1, SDL_Rect Rect2)
{
   return  (Rect1.y < Rect2.y + Rect2.h &&
            Rect1.y + Rect1.h > Rect2.y &&
            Rect1.x < Rect2.x + Rect2.w &&
            Rect1.x + Rect1.w > Rect2.x)
}


Abgefragt dann so:

C-/C++-Quelltext

1
2
3
4
if(Collision(RectX, RectY) == true)
{
...
} 


Die Funktion "Collision" nur so aufrufen wenn im Bereich der Klasse "CGame" aufgerufen!

9

05.06.2010, 00:52

hööö

ich hatte CGame::Collision und es ging nicht, dann hab ich es weggemacht und ich hatte immerhin keinen fehler. und jetzt hab ich es wieder hingemacht und auf einmal gehts?! mmh..^^

gut der boolean funktioniert.
trotzdem passiert nix wenn ich in nen asteroiden flieg^^

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

10

05.06.2010, 11:28

der fehler muss woanders liegen. in dem geposteten code ist alles richtig.

Zitat

if(Collision(RectX, RectY) == true)

das "== true" ist überflüssig.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Werbeanzeige