前言
如果我们的目的是以写应用或游戏的话,那我写的第一篇Hello world SDL已经创建了一个窗口,应用的第一步就有了进展,作为游戏的第二个很重要的部分就是控制,输入控制。这次我们来捕获我们的鼠标键盘消息。
接着上一篇文章,我们把主要的框架留下来:
#include <iostream>
#include "SDL2/include/SDL.h"
const int screen_width = 800;
const int screen_height = 600;
int main(int, char**)
{
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow("YourGame",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
screen_width, screen_height,
SDL_WINDOW_SHOWN);
SDL_Surface* window_surface = SDL_GetWindowSurface(window);
bool sdl_quit = false;
// TODO(yourtayu@gmail.com): Write SDL event processing logic here.
// ...
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
加上我们处理Event的逻辑代码:
SDL_Event sdl_event;
bool sdl_quit = false;
while (!sdl_quit)
{
while (SDL_PollEvent(&sdl_event))
{
if (sdl_event.type == SDL_QUIT)
{
std::cout << "SDL QUIT ENENT!" << std::endl;
sdl_quit = true;
}
else if (sdl_event.type == SDL_MOUSEBUTTONDOWN)
{
auto button_type = sdl_event.button.button == SDL_BUTTON_LEFT ? "Left" : "Right";
std::cout << "Button is " << button_type << " Down" << std::endl;
}
else if (sdl_event.type == SDL_KEYDOWN)
{
std::cout << "Keyboard systemcode is " << sdl_event.key.keysym.sym << " Down" << std::endl;
std::cout << "Keyboard scancode is " << sdl_event.key.keysym.scancode << " Down" << std::endl;
}
}
}
我突发奇想觉得是不是不需要Window也可以捕获Event呢?我就把上面关于window的代码删除,结果事件无法捕获,这是因为这里的事件消息是指window的系统消息,写过MFC或Win32的小伙伴可能比较容易理解这里。目前这段代码只获取Window相关的消息,如window关闭,Windows内的键盘鼠标消息等。效果如下面图片所示:
值得注意的官方提示:
- As this function implicitly calls SDL_PumpEvents(), you can only call this function in the thread that set the video mode.
SDL_PollEvent会隐式调用SDL_PumpEvents,所以只有SDL_INIT_VIDEO模式下才可使用。如果不注意这个可能会影响你功能不work。
那SDL_PumpEvents是什么功能呢?看过官网文档后,总结一句话,我们可以手动调用SDL_PumpEvents来更新window的消息队列。