如何创建事件驱动的 SDL2 应用程序

How to create an event driven SDL2 application

本文关键字:事件驱动的 SDL2 应用程序 创建 何创建      更新时间:2023-10-16

如何创建基于事件的 SDL2 应用程序?(C++( 我当前的模型有一个更新循环,它只是在我需要输入设备时轮询它们,或者在逻辑不需要时就不理会它们。 但是,我想转向事件驱动模型,但是有很多系统不会在某些事件上更新,只是在更新循环的每个刻度时更新。

我该如何处理这些问题? 当我收到新事件时,我是否会添加一个新线程并以某种方式中断更新循环?

有很多方法可以实现您正在尝试做的事情,我能想到的一种方法是事件调度系统。 假设您有一个事件管理器。 应用程序可以使用事件管理器为各种事件注册各种处理程序。 您的事件管理器将侦听/轮询事件,然后调度(调用与事件匹配的事件处理程序(。 事件管理器将具有查找映射,以跟踪所有处理程序到相应的事件类型。

要在 SDL2 中进行基于事件的编程,您需要自己实现其中的一部分。现在,您可能有一个如下所示的基本大纲(+错误处理等(:

SDL_Init(SDL_INIT_VIDEO);
auto window = SDL_CreateWindow(/*arguments*/);
//create something in the window, possibly in a loop
SDL_DestroyWindow(window);
SDL_Quit();

要执行事件处理,您需要自己创建一个主循环。在此循环中,您反复向 SDL 询问下一个事件,并在该事件提供给您后立即处理该事件。您还可以在此循环中重新绘制窗口的内容。在游戏编程(和一般UI,在较小程度上(中,标准系统是一遍又一遍地清除屏幕外缓冲区(屏幕外缓冲区只是用户不可见的图像(,绘制到它,然后使该缓冲区可见(同时通常采用可见的缓冲区(缓冲区只是图像(,并将其作为下一次循环迭代的屏幕外缓冲区(。此循环运行的次数是您在视频游戏中的 FPS 值,您可以通过计算循环在一秒钟内运行的次数来衡量 FPS。

bool quit = false;
SDL_Event event;
while(!quit){
while(SDL_PollEvent(&e)){
switch(e.type){
case SDL_QUIT:
quit = true;
break;
//add more event types here as you see fit
}
}
//it is customary to re-draw the window as fast as possible here, to allow for the window contents to change
}

您可以选择编写更复杂的事件处理系统来抽象此循环,但如上所述的简单循环 + 开关通常就足够了。 Noobius 的回答给出了一些更详细的指示,说明如果一个简单的 loop+switch 是不够的,如何制作更复杂的系统(确保它确实如此!复杂性是软件开发的大敌,所以在其他条件相同的情况下,越简单越好。

参考,以了解更多信息:https://lazyfoo.net/tutorials/SDL/03_event_driven_programming/index.php