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

05.01.2010, 22:31

Kollisionsabfrage liefert komische Ergebnisse

ich habe das SDL Game mal ein bisschen erweitert und jetzt gibt es (theoretisch) eine kollision der Asteroiden mit dem Spieler, jedoch geht dabei nicht alles glatt
ich habe

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
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
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;
  RectPlayer = m_pPlayer->GetRect();

  // Alle Asteroiden durchlaufen

  while (ItAsteroid != m_AsteroidList.end () )
  {
    // Rect des Asteroiden holen

    RectAsteroid = ItAsteroid->GetRect ();

    // 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);
      }

    }

    //Schauen ob der Asteroid mit dem Player kollidiert

    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 &&
        ItAsteroid->IsAlive())
    {
      // Ja, also gab es eine Kollision. Somit Schuss und

      // Asteroid deaktivieren

      ItAsteroid->SetAlive (false);
      m_pPlayer->Reset();
    }

    // Asteroid löschen, falls deaktiviert

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

  }

} // CheckCollision

für die kollisionen und

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
// Init

//

// Aufgabe: Sprites erzeugen und laden

//

void CPlayer::Init ()
{
  // Spielersprite erstellen

  m_pSpritePlayer = new CSprite;

  m_pSpritePlayer->Load ("Data/Player.bmp", 11, 64,64);
  m_pSpritePlayer->SetColorKey (255, 0, 255);

  // Schuss-Sprite erstellen

  m_pSpriteShot = new CSprite;

  m_pSpriteShot->Load ("Data/Laser.bmp", 0, 64, 64);
  m_pSpriteShot->SetColorKey (255, 0, 255);

  //Rect initialisieren

  m_Rect.h = 64;
  m_Rect.w = 64;

} // Init
zur bestimmung des Rects.
X und Y werden auch bei jedem Zyklus geupdatet.
Gewinnen ist, wenn man einmal mehr aufsteht, als man zu Boden geht.

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

2

05.01.2010, 22:48

Du hast vergessen zu erklären, was genau nicht richtig läuft..

3

05.01.2010, 22:55

Es kommt zu einer Kollision, wenn es nicht sollte.
Dabei lässt sich jedoch kein klarer Bereich (also ein vergrößertes Rect)
erkennen.
Gewinnen ist, wenn man einmal mehr aufsteht, als man zu Boden geht.

Luca

Treue Seele

Beiträge: 188

Wohnort: Braunschweig

  • Private Nachricht senden

4

12.06.2011, 11:09

Hallo,
ich kann dir zwar nicht die Antwort auf des Rätsels Lösung geben, aber genau das gleiche Problem habe ich auch...
Ich habe ebenfalls alles genau so initialisiert und die Collisionsprüfung sieht bei mir auch genau so aus. Aber wenn ich es ausführe, bricht das Spiel komplett hat -_-*

Ich suche schon seit Wochen nach diesem Fehler...

daG

Treue Seele

Beiträge: 130

Wohnort: Hamburg

  • Private Nachricht senden

5

12.06.2011, 14:30

Laut Google müsste folgende Bedingung richtig sein um zu überprüfen, ob 2 Rechtecke sich berühren. Deine Funktion testet nur, soweit ich das richtig gesehen habe, ob das eine innerhalb des anderen liegt.

C-/C++-Quelltext

1
2
3
4
5
6
!( 
    rect2->left > rect1->right ||
    rect2->right < rect1->left ||
    rect2->top > rect1->bottom ||
    rect2->bottom < rect1->top
)


Das dürfte bei dir dann so aussehen:

C-/C++-Quelltext

1
2
3
4
5
6
!( 
    RectAsteroid.x > (RectPlayer.x + RectPlayer.w) ||
    (RectAsteroid.x + RectAsteroid.w) < RectPlayer.x ||
    RectAsteroid.y > (RectPlayer.y + RectPlayer.h) ||
    (RectAsteroid.y + RectAsteroid.h) < RectPlayer.y
)

Die Klammern hab ich nur wegen der besseren Übersicht hinzugefügt.

Mastermind

unregistriert

6

12.06.2011, 14:36

Dir ist schon klar dass ! aus || && macht und die Ungleichungen umdreht (de Morgan)?

Was du hingeschrieben hast ist äqivalent zu dem was er schon hatte.

daG

Treue Seele

Beiträge: 130

Wohnort: Hamburg

  • Private Nachricht senden

7

12.06.2011, 14:59

Oha, ja manchmal sollte man sich selbst noch mal angucken was man da überhaupt posted x)

daG

Treue Seele

Beiträge: 130

Wohnort: Hamburg

  • Private Nachricht senden

8

12.06.2011, 15:04

Jetzt wo geklärt ist, das die Abfrage wohl richtig ist... :)

Du deaktivierst zwar mit ItShot->SetAlive (false); den Schuss, aber löscht du ihn auch später? Nicht dass die Schüsse evtl. als unsichtbare Leichen noch herumliegen...

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

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

  • Private Nachricht senden

9

12.06.2011, 15:13

Dir ist schon klar dass ! aus || && macht und die Ungleichungen umdreht (de Morgan)?

Was du hingeschrieben hast ist äqivalent zu dem was er schon hatte.

Nicht ganz. Einer von beiden müsste <= und >= verwenden.
Wenn schon klugscheissen, dann richtig xD

Ich vermute, das rect vom Spieler wird nicht (richtig) geupdatet. :D
"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