在主循环中的控制中,时间是十分重要的
你需要知道在那个点你需要采取什么样的操作,因为渲染器并不是时时刻刻都要刷新
那样不仅不明智而且没必要甚至会与自己的目标效果背道而驰
拿“俄罗斯”方块例子来说
每隔一段时间方块就需要下落一次,这个时间是固定的
但每次都使用类似delay这样的函数确并不明智,因为它是将程序完全停止在那一刻
SDL给我们封装好了几个函数
1. Uint32 SDL_GetTicks():获取从SDL库初始化(定时器模块初始化)开始到当前的运行时间(ms);
2. Uint64 SDL_GetPerformanceCounter():获取高精度定时器的当前值;
3. Uint64 SDL_GetPerformanceFrequency():获取高进度定时器频率(每秒钟高精度定时器的次数);
4. void SDL_Delay(Uint32 ms):延迟函数;
5. SDL_TimerID SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param):
向系统请求增加一个定时器.
SDL_TimerID: 定时器的ID,若该值为NULL,表示请求失败,通过这个ID访问定时器;
interval: 定时间隔;
callback: 回调函数指针,定时时间到后会调用此函数;
param:传递给callback的参数
6. SDL_bool SDL_RemoveTimer(SDL_TimerID id): 删除给定id的定时器,返回值表示是否删除成功.
callback 函数形式:
Uint32 callback(uint32 interval, void * param)
{
return interval;
}
如果需要使用param则需要类型转换,如果param是整形的则需要使用时(int*)(param)
不需要时置为NULL
定时器自创立开始启用,每隔一段时间自动调用回调函数
下面给一个例子:
#define SDL_MAIN_HANDLED
#include<SDL.h>
#include<SDL_image.h>
#include<iostream>
using namespace std;
SDL_Window* win;
SDL_Renderer* renderer = NULL;
SDL_Texture* texture;
SDL_Rect rect = { 100,0,50,50 };
Uint32 callback(Uint32 interval, void *param)//回调函数
{
printf("done %d\n",interval);
SDL_RenderClear(renderer);
rect.y = (rect.y + 30) % 480;
SDL_RenderCopy(renderer, texture, NULL, &rect);
SDL_RenderPresent(renderer);
return interval;
}
int main()
{
SDL_Init(SDL_INIT_VIDEO| SDL_INIT_TIMER);
if (IMG_Init(IMG_INIT_JPG) != IMG_INIT_JPG)
{
cout << SDL_GetError() << endl;
system("pause");
return 0;
}
win = SDL_CreateWindow("time_try", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
texture = NULL;
SDL_Surface* img = IMG_Load("box.jpg");
if (img == NULL)
{
cout << SDL_GetError() << endl;
system("pause");
return 0;
}
texture = SDL_CreateTextureFromSurface(renderer,img);
SDL_Event event;
bool quit = false;
Uint32 start = SDL_GetTicks();//获取开始时间
SDL_TimerID timer = SDL_AddTimer(400, callback, NULL);//创立定时器timer
while (!quit)
{
//不用定时器的方式
//if ((SDL_GetTicks() - start) % 400 == 0)
//{
// SDL_RenderClear(rend);
// rect.y = (rect.y+30)%480;
// SDL_RenderCopy(rend, texture, NULL, &rect);
// SDL_RenderPresent(rend);
//}
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT) quit = true;
}
}
SDL_RemoveTimer(timer);
SDL_DestroyWindow(win);
SDL_Quit();
system("pause");
return 0;
}
效果如下:
注释里面为不采用定时器
下次我们将使用前面的知识做一个游戏角色走路的效果