SDL程式設計入門(22)定時
定時
任何型別的遊戲API的另一個重要部分是處理時間的能力。在本教程中,我們將製作一個我們可以重新啟動的計時器。
//Using SDL, SDL_image, SDL_ttf, standard IO, strings, and string streams
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <stdio.h>
#include <string>
#include <sstream>
在本教程中,我們將使用字串流,並且必須包含sstream頭,它應該是C++編譯器的標準配置。
bool loadMedia()
{
//Loading success flag
bool success = true;
//Open the font
gFont = TTF_OpenFont( "22_timing/lazy.ttf", 28 );
if( gFont == NULL )
{
printf( "Failed to load lazy font! SDL_ttf Error: %s\n" , TTF_GetError() );
success = false;
}
else
{
//Set text color as black
SDL_Color textColor = { 0, 0, 0, 255 };
//Load prompt texture
if( !gPromptTextTexture.loadFromRenderedText( "Press Enter to Reset Start Time.", textColor ) )
{
printf( "Unable to render prompt texture!\n" );
success = false;
}
}
return success;
}
正如字型渲染教程中提到的,你要儘量減少渲染文字的次數。我們將有一個紋理來提示輸入,還有一個紋理以毫秒為單位顯示當前時間。時間紋理每一幀都會改變,所以我們每一幀都要渲染,但提示紋理不會改變,所以我們可以在檔案載入函式中渲染一次。
//Main loop flag
bool quit = false;
//Event handler
SDL_Event e;
//Set text color as black
SDL_Color textColor = { 0, 0, 0, 255 };
//Current time start time
Uint32 startTime = 0;
//In memory text stream
std::stringstream timeText;
在進入主迴圈之前,我們要宣告一些變數。我們要注意的兩個變數是startTime
變數(這是一個32bits的無符號整數)和timeText
變數,它是一個字串流。
對於那些從來沒有使用過字串流的人來說,只需要知道它們的功能就像iostreams一樣,只不過不是向控制檯讀寫,而是允許你向記憶體中的字串讀寫。當我們在程式中進一步看到它們的使用時,就會更容易理解了。
//While application is running
while( !quit )
{
//Handle events on queue
while( SDL_PollEvent( &e ) != 0 )
{
//User requests quit
if( e.type == SDL_QUIT )
{
quit = true;
}
//Reset start time on return keypress
else if( e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_RETURN )
{
startTime = SDL_GetTicks();
}
}
有一個名為SDL_GetTicks的函式,該函式返回自程式啟動以來的時間(以毫秒為單位)。 對於此演示,我們將擁有一個定時器,該定時器將在每次按回車鍵時重新啟動。
還記得我們如何在程式啟動時將開始時間初始化為0嗎? 這意味著定時器的時間僅是SDL_GetTicks
返回程式開始以來的當前時間。 如果我們要在SDL_GetTicks
為5000毫秒(5秒)時重新啟動定時器,那麼當前時間為10,000毫秒-開始時間將是10000減去5000將是5000毫秒。 因此,即使SDL_GetTicks
包含的定時器尚未重新啟動,我們也可以讓定時器跟蹤相對的開始時間並重置其開始時間。
//Set text to be rendered
timeText.str( "" );
timeText << "Milliseconds since start time " << SDL_GetTicks() - startTime;
這裡使用的是我們的字串流。首先用一個空字串呼叫str來初始化它為空。然後我們把它當作cout,並向它列印 "自啟動時間以來的毫秒"和當前時間減去相對啟動時間,這樣它就會列印自上次啟動定時器以來的時間。
//Render text
if( !gTimeTextTexture.loadFromRenderedText( timeText.str().c_str(), textColor ) )
{
printf( "Unable to render time texture!\n" );
}
現在我們已經在字串流中得到了時間,我們可以從中得到一個字串,並使用它將當前時間渲染成紋理。
//Clear screen
SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
SDL_RenderClear( gRenderer );
//Render textures
gPromptTextTexture.render( ( SCREEN_WIDTH - gPromptTextTexture.getWidth() ) / 2, 0 );
gTimeTextTexture.render( ( SCREEN_WIDTH - gPromptTextTexture.getWidth() ) / 2, ( SCREEN_HEIGHT - gPromptTextTexture.getHeight() ) / 2 );
//Update screen
SDL_RenderPresent( gRenderer );
最後我們將提示紋理和時間紋理渲染到螢幕上。
在 這裡下載本教程的媒體和原始碼。
關注我的公眾號:程式設計之路從0到1