0

ユーザーが入力したメッセージ(チャットボックス)を含むサーフェスのベクトルを作成しようとしています。しかし、新しいサーフェスをベクトルに追加して表示すると、他のサーフェスがサーフェス ベクトルに表示されます。これがなぜなのかわかりません。ベクトルのサイズが変更され続け.push_Back();、他のサーフェスが移動する前にコンピューターがこれを行わなかったため、「途中でスタック」してサーフェスの代わりに表示されたためだと思いました。しかし、それを確認したところ、まったく追加されませんでした。私も試してみ.reserve( myVect.size() + 1);ましたが、残念ながら同じ問題しかありませんでした。

問題は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;

}

これを行うより良い方法はありますか?ユーザーのテキストを取得し、それをサーフェスのベクトルに入れて、上に表示するだけです。

4

1 に答える 1

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 の後に a を実行することでこれを解決できますtext=NULL( SDL_FreeSurface(text)NULL を受け入れ、受け入れません何でもする)

コードには他にも多くの小さな問題があることに注意してください(C配列であるかのように使用する、または代わりにvectora を使用する必要があるという事実など)が、質問の範囲外です;)list

于 2012-08-06T17:52:13.340 に答える