在我的SDL 1.2程序中,我有一个函数 KeyPressed ,需要检查是否按下了某个键。如果鼠标指针未在窗口前移动,则按下键时程序将按预期停止。另一方面,如果鼠标指针在窗口前移动,则事件队列似乎填满,之后程序不响应按键。当没有键盘事件时,有没有办法清空事件队列?
#include <SDL/SDL.h>
#include <stdio.h>
static void Init(int *error)
{
SDL_Surface *display;
*error = SDL_Init(SDL_INIT_VIDEO);
if (! *error) {
display = SDL_SetVideoMode(640, 480, 8, 0);
if (display != NULL) {
*error = 0;
} else {
fprintf(stderr, "SDL_SetVideoMode: %s\n", SDL_GetError());
*error = 1;
}
} else {
fprintf(stderr, "SDL_Init: %s\n", SDL_GetError());
*error = 1;
}
}
static int KeyPressed(void)
{
SDL_Event event;
int count, result;
result = 0;
SDL_PumpEvents();
count = SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_EVENTMASK(SDL_KEYDOWN));
switch (count) {
case -1:
fprintf(stderr, "SDL_PeepEvents: %s\n", SDL_GetError());
break;
case 0:
break;
case 1:
result = 1;
break;
}
return result;
}
int main(void)
{
int error;
Init(&error);
if (! error) {
do {
/*nothing*/
} while (! KeyPressed());
}
return error;
}
答案 0 :(得分:2)
您应该使用轮询在while循环中检查事件,轮询将在处理队列时弹出事件。使用多个if/then
语句或swicth
块来处理事件。我建议使用此方法,因为您在使用SDL_QUIT
SDL_PeepEvent
基本示例:
SDL_Event e;
while (SDL_PollEvent(&e))
{
if (e.type == SDL_QUIT)
{
// do something here
}
}
答案 1 :(得分:0)
以下解决方案受到Zammalad评论的启发似乎有效。当没有找到按键事件时,我们从队列中删除一个事件(通常是鼠标事件)以为新事件腾出空间。为了使代码更健壮,我还用数组事件替换了标量事件。
#define LEN(a) ((int) (sizeof (a) / sizeof (a)[0]))
static int KeyPressed(void)
{
SDL_Event events[1];
int count, result;
result = 0;
SDL_PumpEvents();
/*search the event queue for key down events*/
count = SDL_PeepEvents(events, LEN(events), SDL_PEEKEVENT, SDL_EVENTMASK(SDL_KEYDOWN));
switch (count) {
case -1:
fprintf(stderr, "SDL_PeepEvents: %s\n", SDL_GetError());
break;
case 0:
/*make room for new events by removing (non-key down) event from the queue*/
count = SDL_PeepEvents(events, LEN(events), SDL_GETEVENT, -1);
if ((count > 0) && (events[0].type == SDL_QUIT)) {
exit(EXIT_SUCCESS);
}
break;
case 1:
result = 1;
break;
}
return result;
}