Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何清空SDL事件队列?_C_Sdl_Sdl 1.2 - Fatal编程技术网

C 如何清空SDL事件队列?

C 如何清空SDL事件队列?,c,sdl,sdl-1.2,C,Sdl,Sdl 1.2,在我的SDL 1.2程序中,我按下了一个功能键,需要检查是否按下了一个键。如果鼠标指针未在窗口前面移动,则当按下某个键时,程序将按预期停止。另一方面,如果鼠标指针移动到窗口前面,事件队列似乎已满,此后程序不会对按键做出响应。当事件队列中没有键盘事件时,是否有方法清空事件队列 #include <SDL/SDL.h> #include <stdio.h> static void Init(int *error) { SDL_Surface *display;

在我的SDL 1.2程序中,我按下了一个功能键,需要检查是否按下了一个键。如果鼠标指针未在窗口前面移动,则当按下某个键时,程序将按预期停止。另一方面,如果鼠标指针移动到窗口前面,事件队列似乎已满,此后程序不会对按键做出响应。当事件队列中没有键盘事件时,是否有方法清空事件队列

#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;
}
#包括
#包括
静态void Init(int*错误)
{
SDL_表面*显示器;
*错误=SDL_Init(SDL_Init_视频);
如果(!*错误){
显示=SDL_设置视频模式(640、480、8、0);
如果(显示!=NULL){
*误差=0;
}否则{
fprintf(stderr,“SDL_SetVideoMode:%s\n”,SDL_GetError());
*误差=1;
}
}否则{
fprintf(stderr,“SDL_Init:%s\n”,SDL_GetError());
*误差=1;
}   
}
按下静态int键(无效)
{
SDL_事件;
整数计数,结果;
结果=0;
SDL_泵通风孔();
计数=SDL_PeepEvents(&event,1,SDL_PeepEvent,SDL_EVENTMASK(SDL_按键关闭));
开关(计数){
案例1:
fprintf(标准,“SDL_对等事件:%s\n”,SDL_GetError());
打破
案例0:
打破
案例1:
结果=1;
打破
}
返回结果;
}
内部主(空)
{
整数误差;
初始化(&错误);
如果(!错误){
做{
/*没什么*/
}而(!KeyPressed());
}
返回误差;
}

您应该使用轮询检查while循环中的事件,轮询将在处理事件时从队列中弹出事件。使用多个
if/then
语句或
swith
块来处理事件。我建议使用此方法,因为使用
SDL\u PeepEvent

基本示例:

SDL_Event e;
while (SDL_PollEvent(&e))
{
    if (e.type == SDL_QUIT)
    {
        // do something here
    }
}

受赞马拉德评论的启发,以下解决方案似乎可行。当没有发现按键按下事件时,我们从队列中删除一个事件(通常是鼠标事件),为新事件腾出空间。为了使代码更加健壮,我还将标量事件替换为数组事件


您必须从事件队列的某个位置删除事件,您是否尝试过使用SDL_GETEVENT而不是SDL_PEEKEVENT?@nos OK,但我应该删除多少个事件?据我所知,没有办法获得事件队列的长度。您可以执行一个循环,首先执行SDL_事件,如果返回非零,则执行SDL_GETEVENT。如果它确实返回零,则表示已清空事件队列。尽管如此,目前还不清楚该代码是否只是实际应用程序的一部分——在实际应用程序中,控制流和检查关键事件通常会非常不同——并且通常按照此处所示进行处理@nos I原因是,由于我过滤了事件,所以不会使用SDL_GETEVENT删除鼠标事件。(在我正在编写的实际代码中,KeyPressed函数是API的一部分,不能更改。)感谢您的输入。然而,在我正在处理的实际代码中,KeyPressed函数是API的一部分,不能更改。否则我会听从你的建议。在这种情况下,你应该像在代码中一样用事件掩码检查事件队列,看看是否没有按键事件。如果没有,也要检查是否没有重要事件以同样的方式处理ie SDL_退出。然后使用
SDL\u PeepEvent
删除带有SDL\u GETEVENT的所有事件。看这里-
#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;
}