前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >(译)SDL编程入门(22)定时

(译)SDL编程入门(22)定时

作者头像
arcticfox
发布2021-01-06 11:40:04
6740
发布2021-01-06 11:40:04
举报

定时

任何类型的游戏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[1]的函数,该函数返回自程序启动以来的时间(以毫秒为单位)。对于此演示,我们将拥有一个定时器,该定时器将在每次按回车键时重新启动。

还记得我们如何在程序启动时将开始时间初始化为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 );

最后我们将提示纹理和时间纹理渲染到屏幕上。

在 这里[2]下载本教程的媒体和源代码。

原文链接[3]

「关注我的公众号:编程之路从0到1」

Reference

[1]

SDL_GetTicks: http://wiki.libsdl.org/SDL_GetTicks

[2]

这里: http://www.lazyfoo.net/tutorials/SDL/22_timing/22_timing.zip

[3]

原文链接: http://www.lazyfoo.net/tutorials/SDL/22_timing/index.php

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-12-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程之路从0到1 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 定时
    • Reference
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档