Ich finde den Laufzeitfehler nicht
-
Hallo zusammen
Ich habe ein kleines SDL Spiel geschrieben. Doch jetzt habe ich einen Laufzeit Fehler den ich nicht finde. Ich habe den Debugger schon benötigt, doch dieser funktioniert nicht. Könntet ihr mir vieleicht weiterhelfen?
Hier ist der Code:
// Player.h // #ifndef _PLAYER_H__ #define _PLAYER_H__ // Include-Dateien // #include "Sprite.h" #include <SDL.h> #include <stdlib.h> // Klasse // class CPlayer { private: // Membervariablen // CSprite * pPlayer; SDL_Surface * screen; SDL_Rect rect; int done; int PlayerPosX; int PlayerPosY; public: // Memberfunktionen // CPlayer (); void Init (); void Run (); void Quit (); void Move (); }; #endif _PLAYER_H__ // Sprite.h // #ifndef _SPRITE_H__ #define _SPRITE_H__ // Include-Dateien // #include <SDL.h> #include <stdlib.h> // Klasse // class CSprite { public: // Memberfunktionnen // CSprite (int x, int y); void Load (); void SetPos (int x, int y); void Move (int Move_X, int Move_Y); SDL_Rect * GetRect (); void Draw (SDL_Surface * target); void Flip (); protected: // Membervariablen // SDL_Surface * Image, * screen; SDL_Rect rect; }; #endif _SPRITE_H__ #include <iostream> using namespace std; CPlayer::CPlayer() { done = 0; PlayerPosX = 50; PlayerPosY = 50; } void CPlayer::Init() { if (SDL_Init (SDL_INIT_VIDEO) == -1) { printf ("Das SDL kann nicht initialisiert werden: %s\n", SDL_GetError ()); cout << "Das SDL kann nicht initialisiert werden" << endl; exit (1); } atexit (SDL_Quit); screen = SDL_SetVideoMode (640, 480, 16, SDL_HWSURFACE | SDL_DOUBLEBUF); if (screen == NULL) { printf ("Der Video Modus kann nicht gesetzt werden: %s\n", SDL_GetError ()); cout << "Der Video Modus kann nicht gesetzt werden" << endl; exit (1); } pPlayer->Load (); pPlayer->SetPos (50, 50); } void CPlayer::Move() { SDL_Event Event; if (SDL_PollEvent (&Event)) { switch (Event.type) { // Beenden case (SDL_QUIT): { SDL_Quit (); } break; // Wurde eine Taste gedrückt? case (SDL_KEYDOWN): { switch (Event.key.keysym.sym) { case (SDLK_LEFT): { if (pPlayer->GetRect ()->x + pPlayer->GetRect ()->w < screen->w) { PlayerPosX += 1; } } break; case (SDLK_RIGHT): { if (pPlayer->GetRect ()->x - pPlayer->GetRect ()->w > screen->w) { PlayerPosX -= 1; } } break; case (SDLK_UP): { if (pPlayer->GetRect ()->y + pPlayer->GetRect ()->h < screen->h) { PlayerPosY += 1; } } break; case (SDLK_DOWN): { if (pPlayer->GetRect ()->y - pPlayer->GetRect ()->h > screen->h) { PlayerPosY -= 1; } } break; case (SDLK_ESCAPE): { // Ja, also Spiel beenden SDL_Quit (); } break; } } break; } } } void CPlayer::Run() { pPlayer->Move (PlayerPosX, PlayerPosY); pPlayer->Flip (); pPlayer->Draw (screen); } void CPlayer::Quit() { SDL_Quit (); } // Sprite.cpp // // Include-Dateien // #include "Sprite.h" #include <SDL.h> #include <stdlib.h> #include <iostream> using namespace std; CSprite::CSprite (int x, int y) { SetPos (x, y); } void CSprite::Load () { Image = SDL_LoadBMP ("Gegner.bmp"); if (Image == NULL) { printf ("Das Bild konnte nicht geldaden werden: %s\n", SDL_GetError ()); cout << "Das Bild konnte nicht geladen werden!" << endl; exit (1); } } void CSprite::SetPos (int x, int y) { rect.x = x; rect.y = y; } void CSprite::Move (int Move_X, int Move_Y) { rect.x += Move_X; rect.y += Move_Y; } SDL_Rect * CSprite::GetRect() { return ▭ } void CSprite::Draw(SDL_Surface *target) { SDL_BlitSurface (Image, NULL, target, &rect); } void CSprite::Flip() { SDL_Flip (screen); } // main.cpp // // Include-Dateien // #include "Sprite.h" #include "Player.h" #include <SDL.h> #include <stdlib.h> // Hauptprogramm // int main (int argc, char *argv[]) { // Hier kommen dann die Funktionen der Klassen hinein // // Eine neue Spieler-Instanz // CPlayer Player; Player.Init (); Player.Run (); Player.Quit (); return 0; }Danke für hilfreiche Antworten
Gruss Eglifisch1
-
Vielleicht sagst du uns erstmal was überhaupt falsch läuft?
-
Hallo zusammen
Also am Anfang wenn ich das Spiel gestatet habe kommt sofort eine Medlung "Problembericht Senden" oder "Nicht Senden" Meldung, die kennt ihr bestimmt.
Somit habe ich das Spiel noch gar nicht spielen können!
Nun weiss ich aber nicht wo ich etwas falsch gemacht habe.
Gruss Eglifisch1
-
Ich habe den Debugger schon benötigt, doch dieser funktioniert nicht
Zeile 109: pPlayer (CSprite*) ist nicht initialisiert.
-
Hallo zusammen
Kannst du es etwas genauer schreiben, was du meinst, ich verstehe den Fehler nicht so richtig!
Gruss Eglifisch1
-
Nun weiss ich aber nicht wo ich etwas falsch gemacht habe.
Irgendwie sieht das alles nach einem ziemlich übel zusammengekleisterten Mist aus (entschuldige die harrsche Ausdrucksweise - das war mein erster Gedanke).
Eventbehandlung in der Spieler-Klasse, keine ersichtlicher Porgrammschleife (oder Event-Loop), Klassename CPlayer, Instanz mPlayer - welche allerdings ein Objekt der Klasse CSprite ist, etc.
Es verwundert nicht, dass du da nicht mehr durchblickst

Desweiteren hat SDL_Quit() afaik nicht die Aufgabe dein Programm zu beenden. Es beendet das SDL-System, räumt die Resourcen auf, etc => raus damit aus der Event-Behandlung!
Positiv ist, dass du bereits versuchst, dein Programm mittels Klassen zu organisieren und zu strukturieren.
Ein kleiner Vorschlag, wie du dein Programm besser strukturieren könntest (lauffähig):
#include <cstdlib> #include <SDL/SDL.h> #ifdef main #undef main #endif class Application { public: // --------------------------------------------------------- // Konstruktor und Destruktor // --------------------------------------------------------- Application() : screen_(NULL), running_(true) { SDL_Init(SDL_INIT_EVERYTHING); // TODO: Fehlerbehandlung! screen_ = SDL_SetVideoMode ( 640, 480, 0, SDL_SWSURFACE || SDL_DOUBLEBUF ); // TODO: Fehlerbehandlung! } ~Application() { SDL_Quit(); } // --------------------------------------------------------- // Weitere Methoden // --------------------------------------------------------- inline void onEvent(SDL_Event const& event) { switch(event.type) { case SDL_QUIT: running_ = false; break; } } inline void onUpdate() { // Objekte aktuallisieren und bei Bedarf zeichnen, etc. SDL_Flip(screen_); } void mainloop() { while(running_) { SDL_Event event; while(SDL_PollEvent(&event)) this->onEvent(event); this->onUpdate(); } } private: // --------------------------------------------------------- // Attribute // --------------------------------------------------------- SDL_Surface* screen_; bool running_; }; int main() { Application app; app.mainloop(); }Es ist nicht das Nonplusultra der Programmierung, teilt die Anwendung aber in logische Blöcke auf, welche alle eine definierte (und ersichtliche) Aufgabe haben.
Koordinatenberechnungen solltest du (später) auch aus der Event-Behandlung raushalten. Ein Methodenaufruf a la 'player.moveUp()' oder 'player.stop()' bei den entsprechenden Events ist einfacher zu lesen und besser wartbar (du kannst das jeweilige Verhalten dann der Player-Klasse überlassen).
Das sollte aber erstmal reichen.
Grüße... Heiko
-
Hallo Heiko
Für was ist der Doppelpunkt ":" im Konstruktor von der Applikations Klasse?
Du hast es voll darauf mit dem programmieren
Gruss Eglifisch1
-
pPlayer (CSprite*) ist nicht initialisiert.
Kannst du es etwas genauer schreiben, was du meinst, ich verstehe den Fehler nicht so richtig!
class CPlayer { // ... CSprite * pPlayer; // ... };In Deiner main() hast Du ein Objekt Player vom Typ CPlayer.
Da fuer CPlayer kein Constructor existiert der dessen Member initialisieren wuerde, zeigt pPlayer nun undefiniert irgendwo hin.
Auf diesem Haufen Speichermuell rufst Du daraufhin die Methode Load() auf.
Sobald dann eine Membervariable (hier Image) beschrieben werden soll, fuehrt das zur Speicherschutzverletzung.Dir fehlt:
pPlayer= new CSprite;
-
Für was ist der Doppelpunkt ":" im Konstruktor von der Applikations Klasse?
Der Doppelpunkt leitet die Initialisierungsliste1 ein.