2017-01-23 1 views
0

Im folgenden Code:SDL_UpperBlit: bestanden NULL Oberflächenfehler

#include <iostream> 
#include "SDL.h" 
using namespace std; 


int main(int argc, char** argv) 
{ 
    SDL_Surface* screenSurface = nullptr; 
    SDL_Surface* image = nullptr; 
    SDL_Window* window = nullptr; 

    const Uint8* keystate; 

    SDL_Rect offset; 
    offset.x = 100; 
    offset.y = 200; 

    if (SDL_Init(SDL_INIT_VIDEO) < 0) 
    { 
     cout << "Window initialization error: " << SDL_GetError(); 
    } 
    else 
    { 
     window = SDL_CreateWindow("game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN); 

     bool isRunning = true; 
     SDL_Event ev; 

     //game loop 
     while (isRunning) 
     { 
      while (SDL_PollEvent(&ev) != 0) 
      { 
       if (ev.type == SDL_QUIT) 
        isRunning = false; 
      } 

      keystate = SDL_GetKeyboardState(NULL); 
      if (keystate[SDL_SCANCODE_W]) 
      { 
       offset.y -= 1; 
      } 
      else if (keystate[SDL_SCANCODE_A]) 
      { 
       offset.x -= 1; 
      } 
      else if (keystate[SDL_SCANCODE_S]) 
      { 
       offset.y += 1; 
      } 
      else if (keystate[SDL_SCANCODE_D]) 
      { 
       offset.x += 1; 
      } 

      screenSurface = SDL_GetWindowSurface(window); 
      image = SDL_LoadBMP("world.bmp"); 
      SDL_BlitSurface(image, NULL, screenSurface, &offset); 
      SDL_UpdateWindowSurface(window); 
      cout << SDL_GetError() << endl; 
     } 
    } 

    SDL_FreeSurface(image); 
    SDL_DestroyWindow(window); 

    image = nullptr; 
    window = nullptr; 
    SDL_Quit(); 

    return 0; 

} 

ich eine Fehlermeldung erhalten, sagen: "SDL_UpperBlit: a. NULL Oberflächenfehler bestanden" Aber der Fehler trat nicht auf, bis ich eine switch-Anweisung in der while-Schleife für SDL_PollEvent verwendete, sondern nur if-Anweisungen mit SDL_SCANCODE_ in der isRunning-while-Schleife. Der Fehler tritt also nicht sofort auf, sondern nach kurzer Zeit, etwa 10 Sekunden. So kann ich mich mit WASD für eine kurze Zeit auf der world.bmp bewegen, dann bekomme ich den Fehler "SDL_UpperBlit: einen NULL-Oberflächenfehler übergeben.".

Was ist die Lösung dafür?

+0

Sie laden ein Bild auf jeden Frame, aber nur einmal beim Beenden. Wahrscheinlich haben Sie keinen freien Speicher mehr und 'SDL_LoadBMP' gibt schließlich NULL zurück. – keltar

Antwort

1
image = SDL_LoadBMP("world.bmp"); 

Dies lädt world.bmp von der Platte, schafft eine völlig neue Oberfläche und speichert das Innere Bild. Sie zerstören niemals diese Oberfläche, und Sie überprüfen auch nicht auf Fehler.

Wie Sie dies einmal laufen pro Frame, SDL läuft schnell aus Ressourcen, SDL_LoadBMP kehrt NULL es zu signalisieren, und Sie passieren, dass NULL-SDL_BlitSurface.

Laden Sie Ihre Ressourcen nur einmal und achten Sie darauf, sie zur richtigen Zeit zu zerstören. C++ hat intelligente Zeiger und RAII, um das für Sie zu tun.

+0

Danke, ich habe 'SDL_FreeSurface (image);' zur isRunning-Schleife hinzugefügt, die es behoben hat. Beim Schließen des Programms bekomme ich jedoch eine Ausnahme, die das Fenster nicht richtig schließt. Irgendein Vorschlag dafür? – ye546

+2

@ ye546 sollten Sie stattdessen 'SDL_LoadBMP' lieber außerhalb der Schleife verschieben. Es sei denn, Sie beabsichtigen, die Datei "world.bmp" sechzig Mal pro Sekunde zu ersetzen und das Programm weiter so zu halten. – Quentin

+0

Wenn ich nur albern bin, habe ich vergessen SDL_FreeSurface (screenSurface) hinzuzufügen; ' – ye546

Verwandte Themen