SDL2教程(四):timer 定時器

在主循环中的控制中,时间是十分重要的

你需要知道在那个点你需要采取什么样的操作,因为渲染器并不是时时刻刻都要刷新

那样不仅不明智而且没必要甚至会与自己的目标效果背道而驰

拿“俄罗斯”方块例子来说

每隔一段时间方块就需要下落一次,这个时间是固定的

但每次都使用类似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的参数

    return interval : 该函数返回值为下次唤醒的时长,若返回0,则不会再唤醒.

  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;
}


效果如下:


里面采用了使用定时器和不用定时器两种方式

注释里面为不采用定时器


下次我们将使用前面的知识做一个游戏角色走路的效果

猜你喜欢

转载自blog.csdn.net/qq_40953281/article/details/80214908
今日推荐