2017-01-23 1 views
0

Dans le code suivant:SDL_UpperBlit: a adopté une erreur de surface NULL

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

} 

Je reçois une erreur, en disant: "SDL_UpperBlit: a adopté une erreur de surface NULL." Mais l'erreur ne s'est pas produite avant d'avoir utilisé une instruction switch dans la boucle while de SDL_PollEvent, pour utiliser simplement les instructions if en utilisant SDL_SCANCODE_ dans la boucle isRunning while. Donc, l'erreur ne se produit pas instantanément, mais après un court moment, comme 10 secondes ou plus. Donc, je suis capable de se déplacer dans le monde.bmp avec WASD pendant un court moment, puis j'obtiens l'erreur "SDL_UpperBlit: passé une erreur de surface NULL.".

Quelle est la solution pour cela?

+0

Vous chargez une image sur chaque image, mais vous ne la libérez qu'une seule fois à la sortie. Très probablement vous manquez de mémoire disponible et 'SDL_LoadBMP' finit par retourner NULL. – keltar

Répondre

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

Cette charge world.bmp à partir du disque, crée une surface de marque nouvelle et stocke l'image à l'intérieur. Vous ne détruisez jamais cette surface, et vous ne vérifiez pas les erreurs non plus.

Comme vous utilisez cette fois par trame, SDL fonctionne rapidement des ressources, SDL_LoadBMP rendements NULL pour signaler, et vous passez que NULL-SDL_BlitSurface.

Ne chargez vos ressources qu'une seule fois et prenez soin de les détruire au bon moment. C++ a des pointeurs intelligents et RAII pour le faire pour vous.

+0

Merci, j'ai ajouté 'SDL_FreeSurface (image);' à la boucle isRunning, qui l'a corrigé. Cependant, à la fermeture du programme, une exception est levée, ce qui à son tour ne ferme pas correctement la fenêtre. Une suggestion pour cela? – ye546

+2

@ ye546 vous devriez probablement déplacer le 'SDL_LoadBMP' en dehors de la boucle à la place. Sauf si vous avez l'intention de remplacer le fichier 'world.bmp' soixante fois par seconde et que le programme continue. – Quentin

+0

Juste moi étant stupide, j'ai oublié d'ajouter 'SDL_FreeSurface (screenSurface);' – ye546