2012-08-05 40 views
0

我試圖創建一個表面矢量,它將包含用戶輸入的消息(其聊天框)。但是,無論何時向矢量添加新曲面並顯示它們,其他曲面都會顯示在曲面矢量中。我不知道這是爲什麼。我認爲這是因爲矢量不斷被調整大小.push_Back();和計算機沒有這樣做之前,其他表面被移動,所以他們「卡在中間」,並顯示在表面的地方。 但是,當我檢查了這一點,它只是沒有添加任何!我甚至試過.reserve(myVect.size() + 1);但唉,只給了我同樣的問題。SDL_Surface Vectors

問題在於handle_input();以及我想如何顯示消息。我無法在網絡上的任何地方發現任何問題!

這裏是我的源:

ofstream logFile; 


    SDL_Surface *text = NULL; 


void apply_surface (int x, int y, SDL_Surface *source, SDL_Surface *destination, SDL_Rect *clip = NULL) { 

    SDL_Rect offset; 
    offset.x = x; 
    offset.y = y; 

    SDL_BlitSurface(source, clip, screen, &offset); 
} 


vector <SDL_Surface*> surface_vect; 

bool handle_input() { 

if (event.type == SDL_KEYDOWN) { 

    std::string temp = str; 

    if (str.length() <= 48) { 
     logFile << "str's length is <=48.\n"; 
     if (event.key.keysym.unicode == (Uint16) ' ') { 

     str += (char)event.key.keysym.unicode; 
     logFile << "Space bar was pressed.\n"; 
     charcount += 1; 
     } 
     else if ((event.key.keysym.unicode >= (Uint16)'0') && (event.key.keysym.unicode <= (Uint16) '9')) //Finally works! 
     { 
     charcount += 1; 
     str += (char)event.key.keysym.unicode; 
     logFile << "Number key: " <<(char)event.key.keysym.unicode << " pressed, and added to str.\n"; 
     } 
     else if ((event.key.keysym.unicode >= (Uint16)'A')&& (event.key.keysym.unicode <= (Uint16) 'Z')) 
     { 
     charcount += 1; 
     str += (char)event.key.keysym.unicode; 
     logFile << "Number key: " <<(char)event.key.keysym.unicode << " pressed, and added to str.\n"; 
     } 
     else if ((event.key.keysym.unicode >= (Uint16)'a')&& (event.key.keysym.unicode <= (Uint16) 'z')) 
     { 
     charcount += 1; 
     str += (char)event.key.keysym.unicode; 
     logFile << "Number key: " <<(char)event.key.keysym.unicode << " pressed, and added to str.\n"; 
     } 
     else if ((event.key.keysym.unicode == SDLK_RETURN)) 
     { 
     str = ""; 
     surface_vect.reserve (surface_vect.size() + 1); 

     if (surface_vect.size() < surface_vect.capacity()) { //PREVENTS AN ACCESS READING VIOLATION ERROR! THE ELEMENTS IN THE VECTOR WERE BECOMING TOO LARGE FOR THE VECTOR!! 
     surf_count += 1; 
     surface_vect.push_back (text); 
     logFile << "surface_vect has: " << surf_count << " surfaces!"; 
    } 

    } 
     if (event.key.keysym.unicode == SDLK_BACKSPACE && str.length() != 0) { 
      charcount -= 1; 
     str.erase(str.length() - 1); 
     logFile << "Backspace was pressed.\n"; 
     } 
     if (str != temp) { 
      SDL_FreeSurface (text); //This frees up the text surface whenever the str changes. 

      text = TTF_RenderText_Solid(font, str.c_str(), textcolor); //Renders the text whenever that change occurs. 

     logFile << "Full text rendered: " << str.c_str() << " Number of surfaces in existence: " << c << " Number of characters in current surface: " << charcount << "\n"; 
     } 


     //OK SO: the program separates the surfaces! Now to just make each surface different for each different message! To do this, we will put the "text" surface into the top of surface_vect, because that vector will be our messages body. Text will display all messages being typed, only when return is pressed is it added to the message surfaces body! 
    } 
} 
return true; 
} 


int main (int argc, char* args[]) 
{ 
    time(&currentTime); 

    int count = 0; 

    text = TTF_RenderText_Solid(font, "First surface message!", textcolor); 

    surface_vect.push_back(text); 

    Timer myTime; 
    Timer fps; 

    if (init() == false) { 
     return false; 
    } 

    logFile << "Everything initialized fine. \n" ; 
    if (load_files() == false) { 

     return false; 
    } 

    logFile << "All files loaded successfully.\n"; 

myTime.start(); //The time the loop started. Keeps track of the time. 

while (quit == false) 
{ 
    fps.start(); //Frame timer. 
    std::stringstream time; //Something to convert the time into a string, along with a message. 
    while (SDL_PollEvent(&event)) { 
     count += 1; 
    if (handle_input() == false) { 
     logFile << "Handle_input() returned false on the: " << count << "th run through the while loop!"; 
     return false; 
    } 

     if (event.type == SDL_QUIT) { 
      fps.stop(); 
      myTime.stop(); 
      quit = true; //Duh. 
     } 

    } 

    apply_surface(0,0, background, screen); 
    apply_surface (25, 435, text, screen); //Render the text surface because its separate from the other surfaces! It needs its own render command. 

for (int c = 0; c <= surface_vect.size() - 1; c+=1) { 
     apply_surface(25, newY - (13 * c), surface_vect.at(c), screen); 
    } 

    if (SDL_Flip (screen) == - 1) { 
     return false; 
    } 
    frame += 1; //Frame counter. Used to 
     if(fps.get_ticks() < 1000/FRAMES_PER_SECOND) 
     { 
      SDL_Delay((1000/FRAMES_PER_SECOND) - fps.get_ticks()); 
     } 

} 
clean_up(); 
return 0; 

} 

有沒有更好的方式來做到這一點?它應該只是把用戶的文本,把它放入一個表面矢量,並將其顯示在上面。

回答

0

我不明白你對症狀的描述,但看着代碼我猜你推入surface_vect向量的文本之後不會顯示,因爲當用戶按下返回鍵時,你實際上正在做(我保留只有相關線):

surface_vect.push_back (text); 
SDL_FreeSurface (text); 
text = TTF_RenderText_Solid(font, str.c_str(), textcolor); 

記住text變量和surface_vect矢量不持有實際的表面,但指向的表面,所以當你做的push_back你不把表面的進入副本矢量,只是指針的副本。當你SDL_FreeSurface(text)表面本身被清除,這意味着你剛插入到矢量中的指針現在指向一個清除的表面,不會顯示任何東西......你可以通過在push_back後執行text=NULL來解決這個問題(SDL_FreeSurface(text)接受NULL和將不會做任何事情)

請注意,您的代碼中還存在很多其他小問題(例如,使用vector就好像它是C數組,或者您應該使用list代替),但它不在問題的範圍;)