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

22.02.2009, 20:37

Explosion bei SDL-Spiel

Hallo,
ich würde gerne eine Explosion bei einer Kollision zwischen Schuss und Asteroid oder Asteroid und Spieler haben, jedoch fühle ich mich damit grade etwas überfordert...
Muss ich eine eigene Explosionsklasse schreiben oder geht es auch anders?
:?:

Das Sprite habe ich schon, aber wie mache ich es, dass an der Position, wo davor der Asteroid bzw. der Spieler war, die Explosion stattfindet?

Ich dachte dass ich es mal so probiere:

Explosion.hpp

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
#ifndef EXPLOSION_HPP
#define EXPLOSION_HPP

#include "Sprite.hpp"

class CExplosion
{
  public:
    void Init     (CSprite *pSpriteExplosion, float fXPos, float fYPos);
    void Update   ();
    void Render   ();
    bool IsAlive  () {return m_bIsAlive;}
    void SetAlive (bool bIsAlive) {m_bIsAlive = bIsAlive;}
    SDL_Rect GetRect () {return m_Rect;}

  private:
    CSprite *m_pSpriteExplosion; // Zeiger auf Explosions-Sprite

    float    m_fXPos;            // X-Position der Explosion

    float    m_fYPos;           // Y-Position der Explosion

    float    m_fAnimPhase;      // Akt. Animationsphase der Explosion

    bool     m_bIsAlive;        // "Lebt" die Explosion noch?

    SDL_Rect m_Rect;            // Rect der Explosion


};

#endif


Explosion.cpp

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
#include "Explosion.hpp"

// Init

//

// Aufgabe: Explosion initialisieren

//

void CExplosion::Init (CSprite *pSpriteExplosion, float fXPos, float fYPos)
{
  // Zeiger auf Sprite kopieren und Koordinaten setzen

  m_pSpriteExplosion = pSpriteExplosion;
  m_fXPos = fXPos;
  m_fYPos = fYPos;

  // Animation beginnt beim ersten Einzelbild

  m_fAnimPhase = 0.0f;

  // Rect initialisieren

  m_Rect.x = static_cast<int>(fXPos);
  m_Rect.y = static_cast<int>(fYPos);
  m_Rect.w = pSpriteExplosion->GetRect().w;
  m_Rect.h = pSpriteExplosion->GetRect().h;

  // Asteroid aktivieren

  m_bIsAlive = true;

} // Init



// Update

//

// Aufgabe: Animation der Explosion

//

void CExplosion::Update ()
{
      // Animieren

      m_fAnimPhase += 12.0f * g_pTimer->GetElapsed ();

     // Prüfen, ob die Animation am Ende angelangt ist, wenn ja, dann deaktivieren

     if (m_fAnimPhase >= 16.0f)
     {
         m_bIsAlive = false;
     }

} //Update

 

// Render

//

// Aufgabe: Explosion rendern

//

void CExplosion::Render ()
{
  m_pSpriteExplosion->SetPos (m_fXPos, m_fYPos);
  m_pSpriteExplosion->Render (m_fAnimPhase);

} // Render


Game.hpp

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
#ifndef GAME_HPP
#define GAME_HPP

#include "Player.hpp"
#include "Asteroid.hpp"

class CGame
{
  public:
    CGame ();

    void Init ();
    void Run  ();
    void Quit ();

  private:
    void ProcessEvents         ();
    void SpawnAsteroids        ();
    void RenderAsteroids       ();
    void CheckCollisions       ();
    void CheckPlayerCollisions (); 

    CPlayer *m_pPlayer;             // Spieler-Instanz

    CSprite *m_pSpriteBackground;   // Sprite für den Hintergrund

    CSprite *m_pSpriteAsteroid;     // Sprite für die Asteroiden

    //CSprite *m_pSpriteExplosion;    //Sprite für eine Explosion

    float    m_fAsteroidTimer;      // Zeitgeber für nächsten Asteroiden

    bool     m_bGameRun;            // Läuft das Spiel noch?

    list<CAsteroid> m_AsteroidList; // Liste der Asteroiden


};

#endif


Game.cpp:
in CGame::Init()

C-/C++-Quelltext

1
2
3
  m_pSpriteExplosion = new CSprite;
  m_pSpriteExplosion->Load ("Data/Explosion.bmp", 16, 64, 64);
  m_pSpriteExplosion->SetColorKey (255, 0, 255);


in CGame::CheckCollisions()

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
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;

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


Und hier dachte ich schreibe ich dann :

C-/C++-Quelltext

1
2
        m_pSpriteExplosion->SetPos( XPos, YPos);
        m_pSpriteExplosion->Render();

oder etwas in der Art



}

}

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
    // Asteroid löschen, falls deaktiviert

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

  }

} // CheckCollision




So aber was mache ich falsch, weil wenn ich das Spiel dann sraten möchte bleibt es schwarz und beendet sich dann.
Ohne diese ganzen Explosionsteile funktioniert alles bestens...
Und was soll ich bei m_pSpriteExplosion->Setpos (XPos, YPos) reinschreiben, damit die Explosion am früheren Standort des Asteroids stattfindet??

Sry ist jetzt bissi viel Quellcode, aba vll kann mir ja wer helfen...[/cpp]
------------------

Jonny :)

2

22.02.2009, 21:39

Du brauchst doch nur die Position des Spielers/Asteroiden in einer Variablen zwischenspeichern und bei der Explosion dann verwenden.
fka tm

3

22.02.2009, 21:51

Aber es wird ja eine Zufallszahl ermittelt, wie kann ich denn da die Position ermitteln von den Asteroiden?

Vll. mit RectAsteroid.y und RectAsteroid.x als x- und yPosition??

Und is der Quelltext soweit in Ordnung (also im Großen und Ganzen)?
------------------

Jonny :)

4

22.02.2009, 22:39

Zitat von »"JoNnY"«

Aber es wird ja eine Zufallszahl ermittelt, wie kann ich denn da die Position ermitteln von den Asteroiden?
Vll. mit RectAsteroid.y und RectAsteroid.x als x- und yPosition??

Würde ich mal ausprobieren, denn so macht's Sinn. ;)

Zitat

Und is der Quelltext soweit in Ordnung (also im Großen und Ganzen)?

Sieht ein wenig umständlich aus, auf den ersten Blick.
Bist aber auf dem richtigen Weg, denke ich.
fka tm

5

22.02.2009, 23:08

Mhh das funzt so einfach nicht...
Und so geht es dann auch nicht:

CExplosion Bumm;
Bumm.Init (m_pSpriteExplosion, RectAsteroid.x, RectAsteroid.y);
Bumm.Update();
Bumm.Render();

Aber das geht auch nicht...
Da steht dann da: Der Ausdruck links von . oder -> hat einen Typ, der nicht aufgelöst werden konnte.

Weis da jemand wieso das so is?
------------------

Jonny :)

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

6

22.02.2009, 23:32

Den Header hast du aber included, oder?

Im übrigen ist es keine gute Idee die Explosion so zu erstellen, weil du dann auch nichts davon siehst, oder zumindest nur sehr kurz. Du erstellst da ja ein Objekt, welches am Ende der Funktion wieder zerstört wird. Somit wird die Explosion nur einmal gerendert und nicht z.B 5 Sekunden.

Ich würde da eher eine Liste mit Explosionsobjekten speichern, die du dann alle updatest und renderst. Dann kannst du ganz einfach in die Liste eine neue Explosion hinzufügen.

7

23.02.2009, 00:45

Also soll ich hier :

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
      // Ü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);
 ==> ==> Hier soll dann noch eine Liste rein oder?
        Also wo man die 16 einzelnen Teile der Animation nacheinander
        einfügt und jedes einzeln updatet und rendert um Zeit zu gewinnen
        oder?
        
      }


Entschuldigung wenn ich mich ein bisschen dumm anstell aber ich sitze da ein bisschen auf der Leitung grad :?
[/cpp]
------------------

Jonny :)

8

23.02.2009, 13:38

Oder ist es möglich so eine fertige Animation
http://bestanimations.com/Nature/Fire/Ex…xplosions2.html

einzufügen, dann wäre das Problem mit der Zeit gelöst und ich bräcuhte es nicht zu updaten. Einfach dann m_pPSpriteExplosion-> Load (und dann diese Animation) , dann diese rendern an der Position des Asteroiden...

Geht sowas?[/url]
------------------

Jonny :)

9

23.02.2009, 14:33

Afaik unterstützt SDL keine animierten Gifs.
fka tm

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

10

23.02.2009, 15:34

Zitat von »"JoNnY"«

Oder ist es möglich so eine fertige Animation
http://bestanimations.com/Nature/Fire/Ex…xplosions2.html

einzufügen, dann wäre das Problem mit der Zeit gelöst und ich bräcuhte es nicht zu updaten. Einfach dann m_pPSpriteExplosion-> Load (und dann diese Animation) , dann diese rendern an der Position des Asteroiden...

Geht sowas?[/url]


nein geht afaik auch nicht. naja hätte auch die nachteile, dass:

:arrow: 256 Farben
:arrow: schwere synchronisation zur framerate

da würde ich doch die andere variante bevorzugen, da werden die sich bei SDL was gedacht haben ;)

Werbeanzeige