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

19.06.2012, 19:18

player asteroid kollision -> leben abziehen

ich bin gerade dabei, das sdl spiel (kapitel 12) zu erweitern.

ich habe eine kollisionskontrolle zwischen spieler und asteroid eingebaut, die auch funktioniert. nun möchte ich, das der player bei einer kollision ein leben verliert. hier mal meine checkCollision methode und meine PlayerHit methode:

Quellcode

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
 void CGame::CheckCollisions () {

    
    // Schussliste des Spielers holen
    list<CShot> *ShotList = m_pPlayer->GetShotList ();

    // Iteratoren für Asteroiden- und Schussliste
    list<CAsteroid>::iterator ItAsteroid = m_AsteroidList.begin ();
    list<CShot>::iterator ItShot;

    // Rects für Asteroiden und Schüsse
    SDL_Rect RectAsteroid;
    SDL_Rect RectShot;
    SDL_Rect RectPlayer;

    

    // Alle Asteroiden durchlaufen
    while (ItAsteroid != m_AsteroidList.end () )
    {
        // Rect des Asteroiden und players holen
        RectAsteroid = ItAsteroid->GetRect ();
        RectPlayer = m_pPlayer->GetRect();

        //rect des players holen
        RectPlayer = m_pPlayer->GetRect();

        // Überschneiden sich die Rects (asteroid spieler)?
            if (RectPlayer.y < RectAsteroid.y + RectAsteroid.h &&
                RectPlayer.y + RectPlayer.h > RectAsteroid.y &&
                RectPlayer.x < RectAsteroid.x + RectAsteroid.w &&
                RectPlayer.x + RectPlayer.w/10 > RectAsteroid.x) {

                // Ja, also gab es eine Kollision
                cout << "kollision" << endl;
                ItAsteroid->SetAlive (false);
                cout << "rectplayer.x: " << RectPlayer.x << endl;
                cout << "rectplayer.y: " << RectPlayer.y << endl;

                m_pPlayer->SetAlive(false);
                if (!m_pPlayer->IsAlive() ) {
                    PlayerHit();
                }

            
            }



        // Alle Schüsse durchlaufen
        for (ItShot = ShotList->begin ();
            ItShot != ShotList->end ();
            ++ItShot)
        {
            // Rect des Schusses holen
            RectShot = ItShot->GetRect ();

            // Überschneiden sich die Rects?
            if (RectShot.y < RectAsteroid.y + RectAsteroid.h &&
                RectShot.y + RectShot.h > RectAsteroid.y &&
                RectShot.x < RectAsteroid.x + RectAsteroid.w &&
                RectShot.x + RectShot.w > RectAsteroid.x)
            {
                // Ja, also gab es eine Kollision. Somit Schuss und
                // Asteroid deaktivieren
                ItAsteroid->SetAlive (false);
                ItShot->SetAlive (false);
                cout << "treffer" << endl;
                

            }
        }

        // Asteroid löschen, falls deaktiviert
        if (ItAsteroid->IsAlive () ) {
            ItAsteroid++;
        } else {
            ItAsteroid = m_AsteroidList.erase (ItAsteroid);
        }

        

        

    }

} // CheckCollision

void CGame::PlayerHit() {
    int lives = m_pPlayer->GetLives();
    lives--;
    cout << lives << endl;

    m_pPlayer->SetAlive(true);
    

}
 


bei einer kollsion wird auch angezeigt, der player hat nurnoch 2 leben. also eins wird angezeigt. aber das wiederholt sich bei JEDER kollision, heißt es ist immer 2. :dash:
ich schätzte, es geht in die richtung, dass ich mir immerwieder den wert per getLives hole. zudem initialisiere ich lives in der player init methode. ich nehme an, ich benutzte garnicht den veränderten wert...
aber ich komme momentan auf keine löung :dash:
wäre nett wenn jemand mir helfen könnte :D

2

19.06.2012, 19:26

Ab der Zeile 89 solltest du dir es nochmal anschauen. Du erzeugst eine Variable weißt ihm einen Wert zu. Mehr nicht.
Das heißt die Funktion ist sinnlos. Es sollte so eine Funktion geben m_Player->setLives(int);.
Diese Funktion nutzt du dann, nachdem du den Wert von lives veränderst. Also m_Player->setLives(lives);

Mfg
Delop

3

19.06.2012, 19:35

natürlich, setter und getter methoden, danke!

das ist nun die funktionierende methode:

Quellcode

1
2
3
4
5
6
7
8
9
10
 void CGame::PlayerHit() {
    int lives = m_pPlayer->GetLives();
    lives--;
    m_pPlayer->SetLives(lives);
    cout << "lives: " << lives << endl;

    m_pPlayer->SetAlive(true);
    

} 



tja bis jetzt klappt alles...mal sehen wann das nächste problem kommt :thumbup:

4

19.06.2012, 19:39

Bitte :). Eine Sache noch, wieso rufst du SetAlive auf? Was wenn die Lebensvariable unter oder gleich 0 ist? Ich würde die Funktion nur aufrufen, wenn das Leben gleich oder unter 0 ist.

5

19.06.2012, 19:44

um isAlive in player.cpp wieder auf true zu setzten. brauche ich das garnicht?? so sieht momentan meine methode aus:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void CGame::PlayerHit() {
    int lives = m_pPlayer->GetLives();
    lives--;
    m_pPlayer->SetLives(lives);
    cout << "lives: " << lives << endl;

    if (lives == 0) {
        cout << "leben = 0" << endl;
        m_pPlayer->SetAlive(true);
    
        m_pPlayer->Reset ();
        lives = 3;
        m_pPlayer->SetLives(lives);

    }

    

} 


funktioniert alles momentan :D

6

19.06.2012, 19:50

Ahh, du hast eine If-Abfrage. Dann vergiss, was ich gesagt habe. :D

Werbeanzeige