我已经编写了以下(典型)代码片段来处理SDL2中的关键事件:
#include <SDL.h>
#include <iostream>
using std::cout;
using std::endl;
// Custom key types
typedef enum Keys {
Back,
Reset
} KeyType;
// Structure that holds the type and pressed state of custom keys
typedef struct Button {
KeyType type;
bool pressed;
} Button;
int main(int argc, char ** argv)
{
// Variables
bool quit = false;
SDL_Event event;
Button buttons[] = {
{Back, false},
{Reset, false}
};
// Initialize SDL sub-systems, window, renderer and texture
SDL_Init(SDL_INIT_VIDEO);
SDL_Window * window = SDL_CreateWindow("SDL2 Keyboard/Mouse events",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 640, 0);
SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
// Loop while quit not disabled
while (!quit)
{
// Pool events
while(SDL_PollEvent(&event))
{
// Filter events
switch (event.type)
{
case SDL_QUIT: // Window closed
quit = true;
break;
case SDL_KEYDOWN: // Key pressed
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE:
quit = true;
break;
case SDLK_LEFT:
buttons[Back].pressed = true; // Toggle Back button to pressed
cout << "Back held" << endl;
// TODO Measure elapsed time and artificially toggle the pressed state to false if > 5s
break;
case SDLK_DOWN:
buttons[Reset].pressed = true; // Toggle Reset button to pressed
break;
}
break;
case SDL_KEYUP: // Key released
switch (event.key.keysym.sym)
{
case SDLK_LEFT:
if (buttons[Back].pressed) {
// TODO Measure elapsed time and print "Back emitted" if less than 5s
buttons[Back].pressed = false; // Toggle Back button to unpressed and emit Back event
}
break;
case SDLK_DOWN:
buttons[Reset].pressed = false; // Toggle Reset button to unpressed
cout << "Reset emitted" << endl;
break;
}
break;
case SDL_USEREVENT:
break;
}
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
}
}
// Cleanup resources
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
// Stop all SDL sub-systems
SDL_Quit();
return 0;
}
我试图找出一种方法来衡量buttons[Back].pressed
设置为true
之间的时间(即使只按住键的确切开头时#) 34;持有&#34;是我感兴趣的)然后到false
。 &#34;密钥已发布&#34;部分很容易因为这是一个单一的事件。
我想要区分短(单击&#34;按键&#34;收到的事件或持有的键少于让#5说)和长(按住键超过5秒)笔画,基本上是根据用户持有密钥的时间将两个操作映射到同一个键。
我无法弄清楚如何做到这一点。有任何想法吗?我需要在两个位置(imho)处理时间事件:
false
,以防止在检测到短按键时用户实际释放密钥。在这种情况下,检测到长键击 答案 0 :(得分:0)
我对@keltar的建议进行了扩展,虽然不是那么精确(但在我看来并不是必需的。)
我在elapsedTime
结构中添加Button
来保存时间信息并将其初始化为0
:
typedef struct Button {
KeyType type;
bool pressed;
uint32_t elapsedTime;
} Button;
每当按下给定的键时,我会检查elapsedTime == 0
是否如此,如果是,请拨打SDL_GetTicks()
。在释放密钥后,我得到currentTime
,这是该时间点SDL_GetTicks()
的另一个呼叫。我计算elapsedTime
和currenTime
之间的差异,并检查是否已经过了特定的时间间隔,然后决定调用哪个函数。
通过在每次循环迭代期间进行上述计算并进行完全相同的检查,可以扩展此解决方案。这使得可以不仅在释放给定键时检查经过的时间,而且这是对我的初始问题的更准确的答案。然而,第一个解决方案(没有额外检查)工作正常。我只需稍微调整一下我的情景。