如何创建事件驱动的 SDL2 应用程序
How to create an event driven SDL2 application
如何创建基于事件的 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
- 如何创建事件驱动的 SDL2 应用程序
- 具有Qt事件循环的可移植通用共享库设置
- 不带轮询的 SDL2 事件回调
- 我的 SDL2 程序需要哪些二进制文件,以便它在另一台未安装 SDL2 的计算机中工作
- 在C++中的SDL2窗口上显示.bmp时出现问题
- 防止SC_METHOD在没有事件/触发器的情况下执行
- 访问与使用 TraceLoggingWrite 提供的事件关联的用户数据
- 是什么原因导致我的SDL2程序中出现杂散像素
- 实现 QIODevice 驱动的类
- 程序在没有输入的情况下退出,它有基本的,驱动的类属性初始化问题
- 重写多线程事件驱动的C 程序以使用单线程Boost :: Asio
- C 成员功能指针或事件驱动的编程
- C 事件驱动的JSON流读取器
- WASAPI:以最小的延迟播放正弦波声音,无毛刺(专用事件驱动模式)
- 事件驱动的火车模拟,似乎无法理解它
- 在C++中实施事件和定期驱动的"script language"?
- 事件驱动的模拟器中同时发生的事件
- C/C++事件驱动的监视非子程序的终止
- 这会导致事件驱动编程中的竞争条件吗?
- 如果我想要事件驱动的服务器使用libevent或libev