1.简介
SDL事件可以是用户输入、系统通知或窗口管理事件等。SDL事件可以通过SDL_PollEvent和SDL_WaitEvent函数来获取。在SDL中,事件是通过SDL_Event结构体表示的,其中包含事件类型以及与该类型相关的具体数据。 下面是一些常见的SDL事件类型和相关的事件数据:
- SDL_QUIT:应用程序退出事件。
- SDL_KEYDOWN/SDL_KEYUP:键盘按键按下/松开事件。
- SDL_MOUSEMOTION:鼠标移动事件。
- SDL_MOUSEBUTTONDOWN/SDL_MOUSEBUTTONUP:鼠标按键按下/松开事件。
- SDL_WINDOWEVENT:窗口事件(如窗口大小改变、窗口最小化、窗口最大化等)。
- SDL_USEREVENT:用户自定义事件。
2.简单示例
一下这几行代码就是 SDL 消息循环和事件响应的核心了,写一个死循环,然后通过SDL_PollEvent不断的从事件队列中取事件,如果有则返回 1,没有则返回 0。
当用户点击了窗口关闭的时候,对应 SDL_Event 的 type 就是SDL_QUIT,这个 type 是一定要添加处理的,不然点叉就关闭不了窗口了。
SDL_Event windowEvent;
while (true){
if (SDL_PollEvent(&windowEvent)){
if (SDL_QUIT == windowEvent.type){
break;
}
}
}
3.SDL_PollEvent和SDL_WaitEvent区别
除了SDL_PollEvent方法去取消息外,还有SDL_WaitEvent方法。顾名思义,该方法会阻塞当前调用的线程,直到取出一个消息为止。
SDL_PollEvent:
SDL_PollEvent函数是一个非阻塞函数,它会不断地检查 SDL 事件队列,直到有事件产生。如果有事件到达,它将将其从队列中取出并返回。如果没有事件,SDL_PollEvent会返回0。这种方式可以在事件到达时立即处理,而不需要等待。但是,如果程序需要等待某个特定事件,这种方法可能不够灵活。
SDL_WaitEvent:
SDL_WaitEvent函数是一个阻塞函数,它会等待 SDL 事件队列中的事件。直到有事件到达时,它才会返回。与SDL_PollEvent不同,SDL_WaitEvent会在没有事件时阻塞等待,直到事件到达或超时。这种方式在需要等待特定事件(例如用户输入)时非常有用。但是,如果事件处理程序在等待事件时需要执行其他任务,程序可能会变得不够高效。
4.自定义事件响应
除了系统事件,还可以自定义事件。
首先定义一个事件类型的宏:REFRESH_EVENT (一个刷新事件的宏)。
//Refresh Event
#define REFRESH_EVENT (SDL_USEREVENT + 1)
其次,要创建一个线程,让它延时40毫秒后,发送自定义事件,在主线程中去接收到这个事件。
定义一个 SDL_Event数据结构,把它的 type 赋值为自定义的类型,然后通过方法SDL_PushEvent把该消息事件放到消息队列中去。
int thread_exit=0;
int refresh_video(void *opaque){
while (thread_exit==0) {
SDL_Event event;
event.type = REFRESH_EVENT;
SDL_PushEvent(&event);
SDL_Delay(40);
}
return 0;
}
//创建线程
SDL_Thread *refresh_thread = SDL_CreateThread(refresh_video,NULL,NULL);
事件处理主线程:
SDL_Event event;
while(1)
{
//Wait
SDL_PollEvent(&event);
if(event.type==REFRESH_EVENT)
{
//deal
}
else if(event.type==SDL_QUIT)
{
break;
}
}