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

Errschaffer

Alter Hase

  • »Errschaffer« ist der Autor dieses Themas

Beiträge: 865

Wohnort: Frankfurt

  • Private Nachricht senden

1

22.03.2009, 16:35

Kapitel 12 erweitern (Kollision zwischen Schiff und Asteriod

Hallo,
ich habe Kapitel 12 nun zum 1 1/4 mal durch gelesen und so das grobe Verstanden.
Wie gerendert wird und wie dann alles auf Spieldfeld kommt, Steuerung u.s.w versteh ich alles.

Was mir allerdings noch Kopfschmerzen macht íst die Kollsion. Ich wollte nun auch eine Kollision zwischen Spieler und Asteriod einbauen.
Leider ohne Erfolg.

Ich fang mal zu erklären was ich gemacht habe. (am besten es weiß jemand der auch das Buch hat. :p ).

Also...

Ich habe mir in der Player.hpp ein Rect für den Spieler erstellt (soviel ich weiss ist ein Rect die größe und so. richtig?)

C-/C++-Quelltext

1
2
3
SDL_Rect m_Rect;          //Rect des Spielers

    float m_fXPos;            // X-Position des Spielers

    float m_fYPos;            // Y-Position des Spielers


Nach dem bewegen in der Funktion ProccesMoving aktuallisiere ich die Koordinaten im Rect. (wobei sich ja nur das X ändert)

C-/C++-Quelltext

1
2
m_Rect.x=m_fXPos;
m_Rect.y=m_fYPos;


Dann in der CGame holle ich mir das Rect über eine Funktion Names GetRect und speicher das ganze in einer eigenen Variable von CGame

C-/C++-Quelltext

1
2
3
4
5
6
CPlayer *Player=new CPlayer;

  // Rects für Asteroiden und Schüsse

  SDL_Rect RectAsteroid;
  SDL_Rect RectShot;
  SDL_Rect RectPlayer = Player->GetRect ();



Nun alles durchlaufen und Prüfen (Naja so wie ich mir das eben Gedacht habe)


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
for (ItAsteroid = m_AsteroidList.begin (); 
        ItAsteroid!= m_AsteroidList.end ();
         ++ItAsteroid)
    {
        RectPlayer=Player->GetRect ();
        RectAsteroid=RectAsteroid = ItAsteroid->GetRect ();

         if(RectPlayer.y < RectAsteroid.y + RectAsteroid.h &&
          RectPlayer.y + RectPlayer.x > RectAsteroid.y &&
          RectPlayer.x < RectAsteroid.x + RectAsteroid.w &&
          RectPlayer.x + RectPlayer.x > RectAsteroid.x)
         {
            Player->Reset ();
         }


Ich stell jetzt mal einfach mal die banale Frage: Was mach ich falsch?


edit: löschen von Objekten nach Kollision fehlt noch aber ich wollte erstmal das , dass klappt.

KeksX

Community-Fossil

Beiträge: 2 107

Beruf: Game Designer

  • Private Nachricht senden

2

22.03.2009, 16:43

Hab mal kurz überflogen und gesehen dass du die Zeile, um das Rect des Asteroids zu holen, irgendwie verdreht hast.

C-/C++-Quelltext

1
RectAsteroid=RectAsteroid = ItAsteroid->GetRect (); 

Da ist ein RectAsteroid = zuviel ;).

3

22.03.2009, 17:52

sollte das nicht trotzdem Funktionieren?

Errschaffer

Alter Hase

  • »Errschaffer« ist der Autor dieses Themas

Beiträge: 865

Wohnort: Frankfurt

  • Private Nachricht senden

4

22.03.2009, 18:01

Tuts leider nicht.
Ist vieleicht was bei der Berechnung falsch?

5

22.03.2009, 18:07

Re: Kapitel 12 erweitern (Kollision zwischen Schiff und Aste

Zitat von »"Errschaffer"«

Ich vieleicht was bei der Berechnung falsch?

Zitat von »"unsigned long"«

Dieser Satz kein Verb
:p
was sollen diese Zeilen überprüfen?:

Zitat von »"Errschaffer"«

C-/C++-Quelltext

1
2
RectPlayer.y + RectPlayer.x > RectAsteroid.y &&
RectPlayer.x + RectPlayer.x > RectAsteroid.x

6

22.03.2009, 18:08

Re: Kapitel 12 erweitern (Kollision zwischen Schiff und Aste

Zitat von »"Errschaffer"«


C-/C++-Quelltext

1
2
3
4
         if(RectPlayer.y < RectAsteroid.y + RectAsteroid.h &&
-->          RectPlayer.y + RectPlayer.x > RectAsteroid.y &&
          RectPlayer.x < RectAsteroid.x + RectAsteroid.w &&
-->          RectPlayer.x + RectPlayer.x > RectAsteroid.x)

ich hab da mal was herausgehoben.

Errschaffer

Alter Hase

  • »Errschaffer« ist der Autor dieses Themas

Beiträge: 865

Wohnort: Frankfurt

  • Private Nachricht senden

7

22.03.2009, 18:21

Hab mir jetzt mal nach einer Kollisionerkennung den X Wert ausgeben lassen un der liegt immer bei -1251. Also ist schon bei der Zuweisung was schief gelaufen.

Und ja das mit der Berechnugn find ich selber etwas komisch. :lol:

Naja dann weiss ich wenigstens was ich diese Nacht zu tun habe :D

8

22.03.2009, 19:14

Ich habe dazu noch extra eine Funktion CheckPlayerCollision geschrieben,
da habe ich dann auch versucht dass zuerst wie in CheckCollision mit
einer for-Schleife zu lösen aber das ging irgendwie nicht.

Vll liegt es ja bei dir auch an der for-Schleife, ich habe da anstatt der for-Schleife eine while-Schleife:

C-/C++-Quelltext

1
while (ItAsteroid != m_AsteroidList.end () )


Kannst ja mal ausprobieren, bei mir gings dann jedenfalls.
------------------

Jonny :)

n0_0ne

1x Contest-Sieger

  • Private Nachricht senden

9

22.03.2009, 21:04

Weil er nichts an der Liste selbst ändert, ist die for-schleife hier ganz praktisch. Die while-Schleife wird im Buch genutzt, weil man Objekte, wenn es eine Kollision gab, aus der Liste entfernt und dann den Iterator auf den von erase(It); zurückgelieferten Pointer setzt.

EDIT: Dass er immer den selben Wert für X einsetzt könnte daher kommen, weil im Buch der Seed für rand() nicht gesetzt wurde... deshalb fallen Asteroiden auch immer gleich, bei jedem Programmstart.

Toxic

Frischling

Beiträge: 53

Wohnort: Niedersachsen

Beruf: Ingenieur

  • Private Nachricht senden

10

23.03.2009, 00:18

Also, ich habe mich mal mit dem ganzen beschäftigt, hat sich angeboten weil ich auch gerade das SDL-Spiel erweitere und ohne Kollisionsabfrage zwischen Spiel und Asteroid ist das ganze natürlich wenig spannend :)

So funktioniert es bei mir:

In der Datei Game.cpp musst du folgendes in der Funktion CheckCollisons() schreiben:
Nach SDL_Rect RectShot.

C-/C++-Quelltext

1
2
SDL_Rect RectPlayer; 
RectPlayer = m_pPlayer->GetRect(); 

Nach dem Ende der for-Schleife:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
// Kollision zwischen Spieler und Asteroid

      if (RectPlayer.y < RectAsteroid.y + RectAsteroid.h &&
          RectPlayer.y + RectPlayer.h > RectAsteroid.y &&
          RectPlayer.x < RectAsteroid.x + RectAsteroid.w &&
          RectPlayer.x + 64 > RectAsteroid.x) 
      {
        // Ja, also gab es eine Kollision. 

    //Asteroid löschen, Spieler zurücksetzen 

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


In der Datei Player.hpp fügst du folgens hinzu:
Unter public.

C-/C++-Quelltext

1
SDL_Rect GetRect () {return m_Rect;}

Unter private.

C-/C++-Quelltext

1
SDL_Rect m_Rect;          // Rect des Players


Nun muss noch etwas in Player.cpp ergänzt werden:
In der Funktion Reset().

C-/C++-Quelltext

1
2
3
m_Rect.x = static_cast<int> (m_fXPos); 
m_Rect.y = static_cast<int> (m_fYPos); 
m_Rect.h = m_pSpritePlayer->GetRect().h;

Und ganz unten in der Funktion ProcessMoving().

C-/C++-Quelltext

1
m_Rect.x = static_cast<int> (m_fXPos);



Also so funktioniert das ganze bei mir sowohl in der Debug als auch in der Release Version einwandfrei. Ich hoffe ich habe jetzt wirklich nicht eine Stelle im Programm vergessen die noch notwendig ist...

Die Breite RectPlayer.w wurde übrigens gegen die 64 ausgetauscht weil der Wert von m_Rect.w wohl die Breite der gesamten Animation angibt.
Bei mir wird mit:

C-/C++-Quelltext

1
cout<<RectPlayer.w<<"\r";

Der Wert 644 angezeigt, vielleicht hat hier ja jemand eine bessere Lösung, die 64 gefällt mir irgendwie nicht so gut.
Wenn Architekten ihre Häuser so bauen würden wie Programmierer ihre Programme, könnte ein einziger Specht ganze Städte zerstören !

Werbeanzeige