2017-01-23 26 views
0

在下面的代碼:SDL_UpperBlit:通過一個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; 

} 

我得到一個錯誤,他說: 「SDL_UpperBlit:通過一個零位面的錯誤。」但是,直到我在while循環中使用switch語句來使用SDL_PollEvent,直到在isRunning while循環中使用使用SDL_SCANCODE_的if語句時,才發生錯誤。所以這個錯誤不會立即發生,但是過了一會兒,就像10秒左右。所以我可以用WASD在world.bmp中移動一段時間,然後我得到錯誤「SDL_UpperBlit:傳遞了NULL表面錯誤。」。

這是什麼解決方案?

+0

您正在每個框架上加載圖像,但在退出時只釋放一次。很有可能你的內存不足,'SDL_LoadBMP'最終返回NULL。 – keltar

回答

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

這從磁盤加載world.bmp,創建一個全新的表面並將圖像存儲在裏面。你永遠不會破壞這個表面,也不會檢查錯誤。

正如您每幀運行一次這樣,SDL快速耗盡資源,SDL_LoadBMP返回NULL來發信號通知您,並且您將該NULL傳遞給SDL_BlitSurface

只加載一次您的資源,並照顧在正確的時間銷燬它們。 C++有智能指針和RAII爲你做。

+0

謝謝,我添加了'SDL_FreeSurface(image);'到isRunning循環,它修復了它。雖然在程序關閉時我得到一個異常拋出,反過來不能正確關閉窗口。對此有何建議? – ye546

+2

@ ye546您應該將「SDL_LoadBMP」移到循環之外。除非你打算每秒更換一次'world.bmp'文件六十次,並讓程序跟上。 – Quentin

+0

只是我很傻,忘了添加'SDL_FreeSurface(screenSurface);' – ye546