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

10.08.2009, 18:23

Problem bei Spielerweiterung(explosion)

Hi Leute ....ich weis das Thema Explosion gab s schon mal :roll:
bei mir sieht man die explosion au kurtz auf dem bildschirm aber eben nur kurtz.... was mach ich falsch?





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
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
#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 Explosion-Sprite

    float    m_fXPos;           // X-Position der Explosion

    float    m_fYPos;           // Y-Position der Explosion

    float    m_fAnimPhase;      // Akt. Animationsphase des Asteroiden

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

    SDL_Rect m_Rect;            // Rect des Explosion


};

#endif

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

  // Exlosion aktivieren

  m_bIsAlive = true;

} // Init



// Update

//

// Aufgabe: Exlosion bewegen und Position prüfen

//

void CExplosion::Update ()
{
  // Explosion bewegen

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

  m_Rect.y = static_cast<int>(m_fYPos);

// Animieren

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

  // Prüfen, ob die Animation am Ende angelangt ist

  if (m_fAnimPhase >= 10.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


#ifndef GAME_HPP
#define GAME_HPP

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

class CGame
{
  public:
    CGame ();

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

  private:
    void ProcessEvents   ();
    void SpawnAsteroids  ();
    void RenderAsteroids ();
    void RenderExplosion ();
    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

    list<CExplosion> m_ExplosionList; 

};

#endif


#include "Game.hpp"

// Konstruktor

//

// Aufgabe: Allgemeine Initialisierungen

//

CGame::CGame ()
{
  m_pPlayer = NULL;
  m_pSpriteBackground = NULL;
  m_pSpriteAsteroid = NULL;
  m_pSpriteExplosion = NULL;

} // Konstruktor



// Init

//

// Aufgabe: Spieler, Hintergrund  Asteroid und Explosion initialisieren

//

void CGame::Init ()
{
  // Neuen Spieler initialisieren

  m_pPlayer = new CPlayer;
  m_pPlayer->Init ();
  m_pPlayer->Reset ();

  // Hintergrundbild (Sprite) laden

  m_pSpriteBackground = new CSprite;
  m_pSpriteBackground->Load ("Data/Background.bmp");
  
  // Sprite für Asteroiden laden

  m_pSpriteAsteroid = new CSprite;
  m_pSpriteAsteroid->Load ("Data/Asteroid.bmp", 20, 64, 64);
  m_pSpriteAsteroid->SetColorKey (255, 0, 255);
  
  // Sprite für Explosion laden

  m_pSpriteExplosion = new CSprite; 
  m_pSpriteExplosion->Load ("Data/Explosion2.bmp", 10, 70, 70); 
  m_pSpriteExplosion->SetColorKey (255, 0, 255); 

  // Timer für Asteroiden zurücksetzen

  m_fAsteroidTimer = 0.0f;
  
  // Spiel läuft

  m_bGameRun = true;

} // Init



// Quit

//

// Aufgabe: Instanzen freigeben

//

void CGame::Quit ()
{
  // Spieler freigeben

  if (m_pPlayer != NULL)
  {
    m_pPlayer->Quit ();
    delete (m_pPlayer);
    m_pPlayer = NULL ;
  }

  // Hintergrundsprite freigeben

  if (m_pSpriteBackground != NULL)
  {
    delete (m_pSpriteBackground);
    m_pSpriteBackground = NULL;
  }

  // Asteroidensprite freigeben

  if (m_pSpriteAsteroid != NULL)
  {
    delete (m_pSpriteBackground);
    m_pSpriteBackground = NULL;
  }

  


} // Quit



// Run

//

// Aufgabe: Hauptschleife des Spiels

//

void CGame::Run ()
{
  // Hauptschleife des Spiels durchlaufen

  //

  while (m_bGameRun == true)
  {
    // Events bearbeiten

    ProcessEvents ();

    // Framework updaten und Buffer löschen

    g_pFramework->Update ();
    g_pFramework->Clear ();

    // Hintergrundbild rendern

    m_pSpriteBackground->Render ();

    // Spieler updaten und rendern

    m_pPlayer->Update ();
    m_pPlayer->Render ();

    // Neue Asteroiden hinzufügen

    SpawnAsteroids ();

    // Neue Exlosion hinzufügen

    

    // Kollisionen prüfen

    CheckCollisions ();

    // Asteroiden rendern

    RenderAsteroids ();

    // Explosion redern

    RenderExplosion ();


    
    // Buffer flippen

    g_pFramework->Flip ();

  }

} // Run



// ProcessEvents

//

// Aufgabe: Events bearbeiten

//

void CGame::ProcessEvents ()
{
  SDL_Event Event;

  // Gab es ein Event?

  if (SDL_PollEvent (&Event))
  {
    // Ja, also schauen welches

    switch (Event.type)
    {
      // Beenden?

      case (SDL_QUIT):
      {
        m_bGameRun = false;

      } break;

      // Wurde eine Taste gedrückt?

      case (SDL_KEYDOWN):
      {
        switch (Event.key.keysym.sym)
        {
          case (SDLK_ESCAPE):
          {
            // Ja, also Spiel beenden

            m_bGameRun = false;

          } break;
        }
      } break;
    }
  }

} // ProcessEvents



// SpawnAsteroids

//

// Aufgabe: Nach Ablauf einer bestimmten Zeit neuen Asteroiden erzeugen

//

void CGame::SpawnAsteroids ()
{
  // Timer für nächsten Asteroiden erhöhen

  m_fAsteroidTimer += g_pTimer->GetElapsed ();

  // Wenn eine halbe Sekunde vergangen ist,

  // dann einen neuen Asteroiden erzeugen

  if (m_fAsteroidTimer >= 0.5f)
  {
    // Neuer Asteroid

    CAsteroid Asteroid;

    // Zufällige X-Position

    int XPos = rand()%736 ;
    
    

    // Asteroid initialisieren

    Asteroid.Init (m_pSpriteAsteroid, static_cast<float>(XPos), -60.0f);
    
    // Asteroid in Liste einfügen

    m_AsteroidList.push_back (Asteroid);

    // Zeitgeber wieder zurücksetzen

    m_fAsteroidTimer = 0.0f;

  }

} // SpawnAsteroids




// CheckCollisions

//

// Aufgabe: Kollisionen zwischen Asteroiden und Schüssen prüfen

//

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<CExplosion>::iterator ItExplosion = m_ExplosionList.begin ();
  list<CShot>::iterator ItShot;
  // Rects für Asteroiden und Schüsse

  SDL_Rect RectAsteroid;
  SDL_Rect RectExplosion;
  SDL_Rect RectShot;
  SDL_Rect RectPlayer;

  // Alle Asteroiden durchlaufen

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

    RectAsteroid = ItAsteroid->GetRect ();

    // Rect des Spielers holen

    RectPlayer = m_pPlayer->GetRect();

    

      

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

// Rect der Exlosion holen

    RectExplosion = ItExplosion->GetRect();

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



      }
    
    }

    // Asteroid löschen, falls deaktiviert

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


  }




} // CheckCollision



// RenderAsteroids

//

// Aufgabe: Alle Asteroiden rendern und updaten

//

void CGame::RenderAsteroids ()
{
  // Iterator für die Asteroiden-Liste

  list<CAsteroid>::iterator It;

  // Asteroiden-Liste durchlaufen

  for (It = m_AsteroidList.begin (); It != m_AsteroidList.end (); ++It)
  {
    // Asteroid rendern

    It->Render ();

    // Asteroid updaten

    It->Update ();

  }

} // RenderExplosion


// RenderExlosion

//

// Aufgabe: Alle Explosionen rendern und updaten

//

void CGame::RenderExplosion ()
{
  // Iterator für die Asteroiden-Liste

  list<CExplosion>::iterator It;

  // Asteroiden-Liste durchlaufen

  for (It = m_ExplosionList.begin (); It != m_ExplosionList.end (); ++It)
  {
    // Asteroid rendern

    It->Render ();

    // Asteroid updaten

    It->Update ();

  }

} // RenderExlosion


danke schon mal für eure hilfe :)

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

2

10.08.2009, 18:27

Zitat

C-/C++-Quelltext

1
2
3
4
5
6
7
8
// Animieren

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

  // Prüfen, ob die Animation am Ende angelangt ist

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


Ist das nicht ein wenig zu schnell? - Mach da mal einen kleineren Wert hin. (Also nicht 10.0f, sondern z.B 1.0f ).

3

10.08.2009, 18:39

:? da hat sich schon mal nix geändert denke ehr das ich in der Game.cpp anders vorgehen muß

4

10.08.2009, 21:10

vielleicht hilft das ja au noch.....

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
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#ifndef SPRITE_HPP
#define SPRITE_HPP

#include "Framework.hpp"

class CSprite
{
  public:
    CSprite ();
    ~CSprite ();

    void Load        (const string sFilename);
    void Load        (const string sFilename, int NumFrames,
                      int FrameWidth, int FrameHeight);
    void SetColorKey (int R, int G, int B);
    void SetPos      (float fXPos, float fYPos);
    void Render      ();
    void Render      (float fFrameNumber);
    SDL_Rect GetRect () {return m_Rect;}

  private:
    SDL_Surface *m_pScreen; // Zeiger auf den Screen des Frameworks

    SDL_Surface *m_pImage;  // Das eigentliche Bild des Sprites

    SDL_Rect m_Rect;        // Rect des Sprites

    SDL_Rect m_FrameRect;   // Ausschnitt für Animationsphase

    int m_NumFrames;        // Anzahl der Animationsphasen

    int m_FrameWidth;       // Breite einer Animationsphase

    int m_FrameHeight;      // Höhe einer Animationsphase

    int m_NumFramesX;       // Wie viele Anim-Phasen in X-Richtung?


};

#endif


#include "Sprite.hpp"

// Konstruktor

//

// Aufgabe: Zeiger auf Screen holen

//

CSprite::CSprite ()
{
  // Zeiger auf Screen holen

  m_pScreen = g_pFramework->GetScreen ();

} // Konstruktor



// Destruktor

//

// Aufgabe: Surface des Sprites freigeben

//

CSprite::~CSprite ()
{
  // Surface freigeben

  SDL_FreeSurface (m_pImage);

} // Destruktor



// Load

//

// Aufgabe: Einfaches, nicht animiertes Sprite laden

//

void CSprite::Load (const string sFilename)
{
  // Bitmap laden

  m_pImage = SDL_LoadBMP (sFilename.c_str () );

  // Prüfen, ob alles glatt ging

  if (m_pImage == NULL)
  {
    cout << "Fehler beim Laden von: " << sFilename.c_str ();
    cout << endl;
    cout << "Fehlermeldung: " << SDL_GetError () << endl;

    // Framework herunterfahren

    g_pFramework->Quit ();

    // Gesamtes Spiel beenden

    exit (1);
  }

  // Rect initialisieren

  m_Rect.x = 0;
  m_Rect.y = 0;
  m_Rect.w = m_pImage->w;
  m_Rect.h = m_pImage->h;

} // Load



// Load

//

// Aufgabe: Animiertes Sprite laden

//

void CSprite::Load (const string sFilename, int NumFrames,
                    int FrameWidth, int FrameHeight)
{
  // Bitmap laden

  Load (sFilename); 

  // Rect für Animationsphase initialisieren

  m_NumFrames   = NumFrames;
  m_FrameWidth  = FrameWidth;
  m_FrameHeight = FrameHeight;
  m_FrameRect.w = FrameWidth;
  m_FrameRect.h = FrameHeight;
  m_NumFramesX  = m_pImage->w / m_FrameWidth;

} // Load



// SetColorKey

//

// Aufgabe: Transparente Farbe festlegen

//

void CSprite::SetColorKey (int R, int G, int B)
{
  // Colorkey einstellen

  SDL_SetColorKey (m_pImage, SDL_SRCCOLORKEY, 
                   SDL_MapRGB (m_pImage->format, R, G, B) );

} // SetColorKey



// SetPos

//

// Aufgabe: Position des Sprites festlegen

//

void CSprite::SetPos (float fXPos, float fYPos)
{
  // Rect updaten

  m_Rect.x = static_cast<int>(fXPos);
  m_Rect.y = static_cast<int>(fYPos);

} // SetPos



// Render

//

// Aufgabe: Sprite rendern (ohne Animation)

//

void CSprite::Render ()
{
  // Sprite rendern

  SDL_BlitSurface (m_pImage, NULL, m_pScreen, &m_Rect);

} // Render



// Render

//

// Aufgabe: Ausschnitt des Sprites rendern (Animationsphase)

//

void CSprite::Render (float fFrameNumber)
{
  // Ausschnitt der aktuellen Animationsphase berechnen

  //


  // Spalte berechnen

  int Column = static_cast<int>(fFrameNumber)%m_NumFramesX;

  // Zeile berechnen

  int Row = static_cast<int>(fFrameNumber)/m_NumFramesX;

  // Rect berechnen

  m_FrameRect.x = Column * m_FrameWidth;
  m_FrameRect.y = Row * m_FrameHeight;

  // Ausschnitt rendern

  SDL_BlitSurface (m_pImage, &m_FrameRect, m_pScreen, &m_Rect);

} // Render

5

11.08.2009, 15:18

Zitat

void CGame::RenderExplosion ()
{
// Iterator für die Asteroiden-Liste
list<CExplosion>::iterator It;

// Asteroiden-Liste durchlaufen
for (It = m_ExplosionList.begin (); It != m_ExplosionList.end (); ++It)
{
// Asteroid rendern
It->Render ();

// Asteroid updaten
It->Update ();

}

} // RenderExlosion

Dort geht er die Liste für die zu rendernen Objekte durch, die du wahrscheinlich von der Schussliste übernommen hast. Ist auch alles in Ordnung

Zitat


// Rect der Exlosion holen
RectExplosion = ItExplosion->GetRect();

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

Meine Annahme: Du vergisst die neue Explosion in diese Liste einzuordnen.
Deshal werden dann eben nur einmal diese Befehle, die du dort angegeben hast, ausgeführt

6

11.08.2009, 17:20

:lol: jo daran lag s viele dank war schon am verzweifeln :idea:

7

16.08.2009, 10:08

Ich bin auch grade Explosionen am machen, habs genauso wie techno gemacht, aber die Explosionen bleiben die ganze Zeit da, wie kann ich die nach einer Sekunde (oder mehr) wieder verschwinden lassen?

8

17.08.2009, 14:33

Indem du einen Timer benutzt.

9

17.08.2009, 18:25

Kannst du mir sagen wie ich einen solchen Timer hinbekomme?
Sleep() ist da keine wirkliche hilfe wie ich feststellen durfte, gibt es einen Timer der den Wert einer Variable jede Sekunde erhöht, um das löschen der Explosion aus der List einzuleiten wenn die Variable einen bestimmten Wert hat.

10

18.08.2009, 15:25

Mit was arbeitest du denn? Die Win-API hat so einen Timer. Mit der SDL kann aber auch Zeit stopen. Die genauen Funktionsnamen habe ich gerade nicht im Kopf, müsste sonst mal anchschlagen, aber google sollte was finden. Wenn nicht, meld dich einfach wieder.

Werbeanzeige