1. 程式人生 > 其它 >SDL程式設計入門(22)定時

SDL程式設計入門(22)定時

技術標籤:SDL2 教程中心SDL2多媒體開發C語言

定時

任何型別的遊戲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
程式設計之路從0到1