正如我们在鼠标输入教程中看到的那样,除了使用事件之外,还有其他方法可以获得输入设备(鼠标、键盘等)的状态。在本教程中,我们将使用按键状态而不是事件来重新制作键盘输入教程。
//Main loop flag
bool quit = false;
//Event handler
SDL_Event e;
//Current rendered texture
LTexture* currentTexture = NULL;
在进入主循环之前,我们声明一个纹理指针来跟踪我们要渲染到屏幕上的纹理。
//While application is running
while( !quit )
{
//Handle events on queue
while( SDL_PollEvent( &e ) != 0 )
{
//User requests quit
if( e.type == SDL_QUIT )
{
quit = true;
}
}
//根据当前的按键状态设置纹理
const Uint8* currentKeyStates = SDL_GetKeyboardState( NULL );
if( currentKeyStates[ SDL_SCANCODE_UP ] )
{
currentTexture = &gUpTexture;
}
else if( currentKeyStates[ SDL_SCANCODE_DOWN ] )
{
currentTexture = &gDownTexture;
}
else if( currentKeyStates[ SDL_SCANCODE_LEFT ] )
{
currentTexture = &gLeftTexture;
}
else if( currentKeyStates[ SDL_SCANCODE_RIGHT ] )
{
currentTexture = &gRightTexture;
}
else
{
currentTexture = &gPressTexture;
}
//Clear screen
SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
SDL_RenderClear( gRenderer );
//Render current texture
currentTexture->render( 0, 0 );
//Update screen
SDL_RenderPresent( gRenderer );
}
正如你所看到的,我们没有在事件循环中检查按键事件。我们所有的键盘输入都将通过键状态来处理。
关于SDL如何处理键状态,有一点很重要,那就是你仍然需要一个事件循环运行。SDL的内部键状态每次调用SDL_PollEvent[1]时都会更新,所以在检查键状态之前要确保你已经轮询了队列上的所有事件。
这里我们设置了要渲染的纹理。首先,我们使用 SDL_GetKeyboardState[2]获得一个指向按键状态数组的指针。所有键的状态都是由 SDL_Scancode[3] 排序的。扫描码就像SDL_Keycode[4]的值一样,只是扫描码被设计成可以和国际键盘一起使用。根据键盘布局的不同,不同的字母可能在不同的位置。扫描码是根据默认的物理按键位置,而不是它们在特定键盘上的位置。
您所要做的就是检查某个键是否被关闭,检查它在键状态数组中的状态。正如你在上面的代码中所看到的那样,如果键是按下的,我们将当前的纹理设置为相应的纹理。如果键都没有按下,我们就设置默认的纹理。
最后在这里,我们将当前纹理渲染到屏幕上。
[1]
SDL_PollEvent: http://wiki.libsdl.org/SDL_PollEvent
[2]
SDL_GetKeyboardState: http://wiki.libsdl.org/SDL_GetKeyboardState
[3]
SDL_Scancode: http://wiki.libsdl.org/SDL_Scancode
[4]
SDL_Keycode: http://wiki.libsdl.org/SDL_Keycode
[5]
这里: http://www.lazyfoo.net/tutorials/SDL/18_key_states/18_key_states.zip
[6]
原文链接: http://www.lazyfoo.net/tutorials/SDL/18_key_states/index.php