2

私は SDL を使用して c++ で Yahtzee のような (スコアリング付きのサイコロ ゲーム) を作成しています。これは、自分で開発する最初の SDL プロジェクトです。

問題は次のように説明できます: ゲームを開始すると、テキストが正常にレンダリングされます。スコアを配置してゲームを続行できます。ただし、(まだプレイしているかどうかに関係なく) 数分間待つと、最終的にテキストのレンダリングが停止します。ゲームを続行できますが、テキストが表示されず、以前に表示されていたテキストが表示されなくなります。

私はこの問題に完全に困惑しています。これまでのゲームはどれも私が気付くほど長くなかったので、今まで起こったことはありません.

注:私がつまずいたのは、ソフトウェアとハ​​ードウェアのレンダリングでした。理由はわかりませんが、代わりにハードウェアでレンダリングしようとしましたが、問題は解決しませんでした。

別の注意:コードのテキスト レンダリング部分は、for ループ内の最後のほうにあります。

道に迷ったのですが、誰か助けてくれますか? コードを投稿しますが、長くてばかげていますが、それが問題だとは思いません。

int GUI(State& GameState)
{       
apply_surface( 0, 0, background, screen ); //background
apply_surface( SCORE_X, SCORE_Y, scoreImage, screen ); //score card
apply_surface( KEPT_TRAY_X, KEPT_TRAY_Y, keptTray, screen ); //kept tray
apply_surface( TEXT_BOX_X, TEXT_BOX_Y, textBox, screen ); //text box

//Blatantly handles only the next event on the queue per frame
if( SDL_PollEvent( &event ) )
    eventHandler(GameState);

//place button
if(GameState.placeButtonClicked)
{
    apply_surface( GameState.buttonV[GameState.placeButtonClicked].x, GameState.buttonV[GameState.placeButtonClicked].y, clickedButton, screen );
}

//dice[1]
apply_surface( *GameState.diceV[1].pointX, *GameState.diceV[1].pointY, *GameState.diceV[1].surfaceValue, screen );

//dice[2]
apply_surface( *GameState.diceV[2].pointX, *GameState.diceV[2].pointY, *GameState.diceV[2].surfaceValue, screen );

//dice[3]
apply_surface( *GameState.diceV[3].pointX, *GameState.diceV[3].pointY, *GameState.diceV[3].surfaceValue, screen );

//dice[4]
apply_surface( *GameState.diceV[4].pointX, *GameState.diceV[4].pointY, *GameState.diceV[4].surfaceValue, screen );

//dice[5]
apply_surface( *GameState.diceV[5].pointX, *GameState.diceV[5].pointY, *GameState.diceV[5].surfaceValue, screen );

//rollButton
if(GameState.navV[1].clicked)
{
    apply_surface( GameState.navV[1].x, GameState.navV[1].y, rollButtonClicked, screen);
}
else
{
    apply_surface( GameState.navV[1].x, GameState.navV[1].y, rollButton, screen );
}

//endTurnButton
if(GameState.navV[2].clicked)
{
    apply_surface( GameState.navV[2].x, GameState.navV[2].y, endTurnButtonClicked, screen );
}
else
{
    apply_surface( GameState.navV[2].x, GameState.navV[2].y, endTurnButton, screen );
}

//displaying the clickedButton if a score is clicked
if(GameState.placeButtonClicked != 0)
{
    apply_surface( GameState.buttonV[GameState.placeButtonClicked].x, GameState.buttonV[GameState.placeButtonClicked].y, clickedButton, screen );
}

//displaying the scores for each "button" (each score segment)
for(int i = 1; i <= (GameState.buttonV.size() - 1); i++)
{
    if(GameState.buttonV[i].value >= 0)
    {
        message = TTF_RenderText_Solid( scoreFont, GameState.buttonV[i].valueString, scoreFontColor );
        apply_surface( GameState.buttonV[i].x + 10, GameState.buttonV[i].y + 2, message, screen );
    }
}

if( SDL_Flip( screen ) == -1 )
{
    return 1;
}

decGUICounters(GameState);

return 0;

}

4

2 に答える 2

5

このウェブサイトを閲覧して答えを見つけました(時間がかかりました!)。うまくいけば、私が見つけたもので他の誰かを助けることができます:

問題は、新しいテキストをメッセージに繰り返し設定していたことです。

message = TTF_RenderText_Solid(etc);

を呼び出すとTTF_RenderText_Solid()、新しいサーフェスがサーフェス ポインタに返されます (メッセージ)。ただし、古いサーフェスに含まれていた RAM は解放されません。

あなたがしなければならないSDL_FreeSurface(message);のは、新しいメモリをサーフェスポインターに割り当てる前です(メッセージ)。

これにより、メモリ リークが防止され、CPU によってメモリがランダムに消去されるのを防ぐことができます。

TL;DR:

SDL_FreeSurface(message);

前:

message = TTF_RenderText_Solid();
于 2012-06-28T08:37:10.913 に答える