Lesson 4: 事件处理
在本课中, 我们将学习使用 SDL 读取用户输入的基本知识, 在这个简单的例子中, 我们将解释任何输入作为用户想要退出我们的应用程序。为了读取事件, SDL 提供了 SDL_Event 的结构和函数来从队列中获取事件, 如 SDL_PollEvent。本课的代码是从3课代码中构建的, 如果您需要该代码从 Github 获取, 让我们开始吧!
我们需要做的第一个更改是加载新映像以显示输入提示。然后像以前一样使用我们的 loadTexture 功能加载它。
基本的主循环
我们将添加一个主循环来保持程序运行, 直到用户退出, 以便他们想使用就可以使用它, 而不是一些固定的延迟时间。这个循环的结构是非常基本的。
while (!quit){
//Read user input & handle it
//Render our scene
}
SDL 事件队列
要正确使用 sdl 的事件系统, 我们至少需要了解 sdl 如何处理事件。当 SDL 收到一个事件时, 这个事件将被推到所有已接收但尚未被轮询的其他事件的队列后面。如果我们要启动我们的程序, 然后调整窗口的大小, 请单击鼠标并按下一个键, 事件队列将像下图这样。
当我们调用 SDL_PollEvent, 我们得到队列前面的事件, 这相当于最古老的事件。轮询将这个事件从队列中移除, 如果我们想在不删除它们的情况下检索一些事件, 我们可以使用 SDL_PeepEvents SDL_PEEKEVENT 标志, 但这超出了本介绍的范围。我鼓励你阅读开发文档!
处理事件
在主循环中, 我们要阅读的每一个事件, 发生自上一帧和处理它们, 我们可以做到这一点, 把 SDL_PollEvent 在一个 while 循环, 因为该函数将返回 1, 如果一个事件被读取和0如果没有。因为我们要做的是退出程序, 当我们得到一个事件, 我们将设置一个退出 bool 来跟踪主循环是否应该退出。因此, 我们的事件处理循环看起来像这样。
在主循环中,如果我们要捕获全部的事件,我们应该将SDL_PollEvent放在while循环中,通过返回值判断是否还存在事件。我们需要设置一个bool值,当我们设置的某个事件发生(这个事件发生则退出程序)时,将bool值反转,然后就可以退出程序。
//e is an SDL_Event variable we've declared before entering the main loop
while (SDL_PollEvent(&e)){
//If user closes the window
if (e.type == SDL_QUIT){
quit = true;
}
//If user presses any key
if (e.type == SDL_KEYDOWN){
quit = true;
}
//If user clicks the mouse
if (e.type == SDL_MOUSEBUTTONDOWN){
quit = true;
}
}
SDL_QUIT 事件发生在用户关闭我们的窗口时, SDL_KEYDOWN 在按下键时发生, 并且在按下鼠标按钮时发生 SDL_MOUSEBUTTONDOWN。这些只是我们可以接收的各种各样的事件中的几个, 我强烈建议您阅读 SDL_Event 文档中的其他类型。
完成主循环
我们的主回路的最后部分跟处理渲染我们的场景使用相同的方法和以前一样。当我们结合我们的事件处理代码, 我们的基本主循环成为:
//Our event structure
SDL_Event e;
bool quit = false;
while (!quit){
while (SDL_PollEvent(&e)){
if (e.type == SDL_QUIT){
quit = true;
}
if (e.type == SDL_KEYDOWN){
quit = true;
}
if (e.type == SDL_MOUSEBUTTONDOWN){
quit = true;
}
}
//Render the scene
SDL_RenderClear(renderer);
renderTexture(image, renderer, x, y);
SDL_RenderPresent(renderer);
}
我们的程序将不断重复, 直到用户要求退出, 并会不断重绘图案。
结束
当您运行该程序时, 您应该能够通过关闭窗口、按任意键或单击鼠标来退出。如果您有任何问题的请检查您的代码和/或张贴您的问题下面。