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

11

16.03.2011, 18:30

Dann wird der Fehler wohl hier:

void CHighscore::LoadBackground ()
{
m_SpriteHighscore = new CSprite;
m_SpriteHighscore->Load ("Data/Highscore.bmp");
}

liegen. Ich weiß nicht, was deine Klasse CSprite macht. Ich würde mal CSprite::Load überprüfen.


Alle Dateien vom ganzen Projekt habe ich auf megaupload geladen. Aber ich poste trotzdem mal den quellcode rein. aber ich schätze das der fehler nicht dort liegt weil ich die eine datei vom buch noch unverändert 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
#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


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

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

12

16.03.2011, 18:34

Ja hast zwar alle Daten, aber keinen Quellcode geladen, nur .obj Dateien, sehr hilfreich (;

Und wie ich das sehen, du lädst zwar das Bild, aber du erwartest, dass nun etwas damit passiert?
Vllt. solltest du SDL_Flip bzw. SDL_UpdateRect benutzen.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

13

16.03.2011, 20:42

Ich habe das Problem einigermaßen gelöste jetzt habe ich nur das problem das wenn ich jetzt ESC mache das das ganze Programm beendet. Irgendwie muss es am Sprite.cpp liegen da wenn die Variable m_pSpriteBackground == NULL ist das Programm beendet ich bin mir aber nicht sicher.

Quelltext

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

// Konstruktor
//
// Aufgabe: Allgemeine Initialisierungen
//
CGame::CGame ()
{
  m_pPlayer = NULL;
  m_pSpriteBackground = NULL;
  m_pSpriteAsteroid = NULL;

} // Konstruktor


// Init
//
// Aufgabe: Spieler, Hintergrund und Asteroid 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);

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

    // Kollisionen prüfen
    CheckCollisions ();

    // Asteroiden rendern
    RenderAsteroids ();

    // 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):
          {
  
            m_pSpriteBackgroundd = new CSprite;

            m_pSpriteBackgroundd->Load ("Data/Highscore.bmp");

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

    }

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

  }

} // RenderAsteroids


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

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Tunfisch« (16.03.2011, 20:58)


BurningWave

Alter Hase

Beiträge: 1 106

Wohnort: Filderstadt/Konstanz

Beruf: Student

  • Private Nachricht senden

14

16.03.2011, 20:52

Ich verstehe nicht ganz, was du sagen willst... Warum soll das Programm mit diesen Zeilen

// Ja, also Spiel beenden
m_pSpriteBackgroundd = new CSprite;
m_pSpriteBackgroundd->Load ("Data/Highscore.bmp");

beendet werden? Das einzige, was du machst, ist Speicherlücken zu erzeugen, da du bei jedem Druck auf ESC ein neues Sprite erstellt, aber nirgends eins löschst. Außerdem ist es Quatsch, Daten in der Nachrichtenschleife zu laden.

15

16.03.2011, 20:57

Ich verstehe nicht ganz, was du sagen willst... Warum soll das Programm mit diesen Zeilen

// Ja, also Spiel beenden
m_pSpriteBackgroundd = new CSprite;
m_pSpriteBackgroundd->Load ("Data/Highscore.bmp");

beendet werden? Das einzige, was du machst, ist Speicherlücken zu erzeugen, da du bei jedem Druck auf ESC ein neues Sprite erstellt, aber nirgends eins löschst. Außerdem ist es Quatsch, Daten in der Nachrichtenschleife zu laden.


Das //Ja also Spiel beenden habe ich vergessen raus zu machen sollte ich aber jetzt besser tun weil sonst glaubt jeder ich will damit das spiel beenden aber ich habe ja ein anderes Problem ich möchte ja eine Highscore Liste erstellen und dafür ein ganz neues Fenster Laden wo dann Die Überschrift ist und Die Spieler mit der Highscore Liste aber wenn ich jetzt ESC drück dann beendet das ganze Fenster und das will ich ja nicht damit erreichen. Das das Funktionen laden in der Nachrichtenschleife nicht besonders gut ist wusste ich jetzt nicht aber ich hab es halt mal so probiert.

BurningWave

Alter Hase

Beiträge: 1 106

Wohnort: Filderstadt/Konstanz

Beruf: Student

  • Private Nachricht senden

16

16.03.2011, 21:18

Ich kenne mich mit der SDL nicht so aus, aber ich könnte mir vorstellen, dass die SDL ein Druck auf ESC standardmäßig als Befehl zum Beenden interpretiert. Das müsstest du in der Doku nochmal nachlesen. Sonst kannst du auch einfach eine andere Taste verwenden.

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

17

16.03.2011, 21:21

Ich kenne mich mit der SDL nicht so aus, aber ich könnte mir vorstellen, dass die SDL ein Druck auf ESC standardmäßig als Befehl zum Beenden interpretiert. Das müsstest du in der Doku nochmal nachlesen. Sonst kannst du auch einfach eine andere Taste verwenden.

Nein eig. nicht. Dazu muss man die Game Loop beenden. Das drücken von Escape sendet kein Quit Event, das bekommt man afaik nur, indem man manuell das Fenster schließt.

Tunfisch:
Dir wird auch kein Fehler ausgegeben, oder?
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

BurningWave

Alter Hase

Beiträge: 1 106

Wohnort: Filderstadt/Konstanz

Beruf: Student

  • Private Nachricht senden

18

16.03.2011, 21:24

Ok, ich habe trotzdem den Fehler gefunden, glaube ich (CSprite::Load):

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
 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 - wie willst du so jemals den Fehlertext lesen können?
    exit (1);
  }

19

16.03.2011, 21:32

ne es gibt keine fehlermeldung

BurningWave

Alter Hase

Beiträge: 1 106

Wohnort: Filderstadt/Konstanz

Beruf: Student

  • Private Nachricht senden

20

16.03.2011, 21:34

Natürlich gibt es eine, die kannst du nur nicht lesen, weil du das Programm im selben Moment beendest, siehe meinen vorherigen Beitrag...

Werbeanzeige