SDL/C EventHandler连续键

SDL/C EventHandler连续键,c,events,sdl,C,Events,Sdl,我正在尝试使用SDL在C中开发一个事件处理程序 我希望能够检测到以下情况:按键按下、按键释放和按键按下 问题是,键盘自动重复SPAM会在一定的延迟和给定的间隔后按下按键。为了缓解这种情况,我尝试使用SDL_EnableKeyRepeat(0,0);根据文档,哪个应该禁用它 由于失败,我尝试映射SDL_GetKeyboardState(NULL);这也算起作用了。但是我有一个问题,如果我按住一个键X秒,它会在相同的时间内发送幽灵事件 按下esc键,按住它一点,然后释放它的输出示例如下: Press

我正在尝试使用SDL在C中开发一个事件处理程序

我希望能够检测到以下情况:按键按下、按键释放和按键按下

问题是,键盘自动重复SPAM会在一定的延迟和给定的间隔后按下按键。为了缓解这种情况,我尝试使用SDL_EnableKeyRepeat(0,0);根据文档,哪个应该禁用它

由于失败,我尝试映射SDL_GetKeyboardState(NULL);这也算起作用了。但是我有一个问题,如果我按住一个键X秒,它会在相同的时间内发送幽灵事件

按下esc键,按住它一点,然后释放它的输出示例如下:

Pressed
HELD
HELD
HELD
... 
RELEASED       {it breaks down after first proper release}
PRESSED        
RELEASED 
HELD
PRESSED 
RELEASED 
HELD
...
RELEASED     // it always ends on released.
上述结果是:

Pressed: 18;
Released: 21;
Held: 39.

Should be:
Pressed 1;
Released 1;
Held: say 20. 
我不知道我是不是搞砸了我的逻辑,或者它是否与键盘事件的实际内置机制有关

代码如下:

/** 程序接口

    void ev_handle_start()      // Starts the Event Handler.
    void ev_handle_stop()       // Pauses the Event Handler.

**/

#include <stdio.h>
#include <SDL2/SDL.h>
#include <SDL/SDL.h>
#include "ev_handler.h"

#define PRESSED             1
#define RELEASED            0
#define TMR_FREQ            33
#define MOUSE_RIGHT         1
#define MOUSE_LEFT          3
#define EV_LEFT_CLICK       0
#define EV_LEFT_RELEASE     1
#define EV_RIGHT_CLICK      2
#define EV_RIGHT_RELEASE    3
#define EV_MOUSE_MAX        4
#define MAX_SCANCODES       SDL_SCANCODE_MODE
#define EV_DELAY            70

//********************************************************************************************//
//      VARIABLES
//********************************************************************************************//

SDL_Event e;
Uint8* keyboardState;
SDL_TimerID ev_timer = NULL;                // Timer to callback the search of the code
bool ev_handler_active = false;             // Used to determine if the ev_handler() is enabled or not
bool buttonState[EV_MOUSE_MAX];             // Button Stats, either pressed or released
bool evMouseEvent[EV_MOUSE_MAX];            // Used to flag if a mouse events
int evKeyEventStatus[MAX_SCANCODES];
bool evKeyStatePrev[MAX_SCANCODES];         //
bool evKeyStateCur[MAX_SCANCODES];          //

//********************************************************************************************//
//  1   FRONTEND
//********************************************************************************************//

//********************************************************************************************//
//  1.1 MOUSE
//      Can only handle left and right mouse buttons.
//********************************************************************************************//
bool evButtonPressed(int button)
{   bool flag = button == SDL_BUTTON_RIGHT || button == SDL_BUTTON_LEFT;
    if (!flag) {
        printf("ERROR: isButtonPressed(int) received parameter of invalid type.\n");
        return false;
    }
    return buttonState[button];
}

bool evLeftClick()
{
    return evMouseEvent[EV_LEFT_CLICK];
}

bool evLeftRelease()
{
    return evMouseEvent[EV_LEFT_RELEASE];
}

bool evRightClick()
{
    return evMouseEvent[EV_RIGHT_CLICK];
}

bool evRightRelease()
{
    return evMouseEvent[EV_RIGHT_RELEASE];
}

//********************************************************************************************//
//  1.2 KEYBOARD
//********************************************************************************************//
bool evKeyHeld(SDL_Scancode sc)
{
    return evKeyEventStatus[sc] == 1 || evKeyEventStatus[sc] == 3;
}

bool evKeyPressed(SDL_Scancode sc)
{
    return evKeyEventStatus[sc] == 1;
}

bool evKeyReleased(SDL_Scancode sc)
{
    return evKeyEventStatus[sc] == 2;
}

//********************************************************************************************//
//  1.3 MANAGE
//********************************************************************************************//
void evSetup()
{
    for (int i = 0; i < MAX_SCANCODES; i++) {
        evKeyStatePrev[i] = 0;
    }
    evClearEvents();
}

int j;
void evClearEvents()
{
    evMouseEvent[EV_LEFT_CLICK] = false;
    evMouseEvent[EV_LEFT_RELEASE] = false;
    evMouseEvent[EV_RIGHT_CLICK] = false;
    evMouseEvent[EV_RIGHT_RELEASE] = false;
}

//********************************************************************************************//
//  2   BACKEND
//********************************************************************************************//
void ev_handler()
{
    while(SDL_PollEvent(&e))
    {
        switch (e.type)
        {
            /*Skip unnecessary events*/
            case SDL_KEYDOWN:
                break;
            case SDL_KEYUP:
                break;
            case SDL_MOUSEMOTION:
                break;

            case SDL_MOUSEBUTTONDOWN:
                buttonState[e.button.button] = PRESSED;
                if (e.button.button == SDL_BUTTON_LEFT) {
                    evMouseEvent[EV_LEFT_CLICK] = true;
                }
                else if (e.button.button == SDL_BUTTON_RIGHT) {
                    evMouseEvent[EV_RIGHT_CLICK] = true;
                }
                break;

            case SDL_MOUSEBUTTONUP:
                buttonState[e.button.button] = RELEASED;
                if (e.button.button == SDL_BUTTON_LEFT) {
                    evMouseEvent[EV_LEFT_RELEASE] = true;
                }
                else if (e.button.button == SDL_BUTTON_RIGHT) {
                    evMouseEvent[EV_RIGHT_RELEASE] = true;
                }
                break;

            case SDL_QUIT:
                exit(0);
                printf("Quit\n");
                break;

            default:
                break;
        }

        keyboardState = SDL_GetKeyboardState(NULL);

        for (int i = 0;  i < MAX_SCANCODES; i++)
        {
            evKeyStateCur[i]  = keyboardState[i];
            int sum = evKeyStateCur[i] + evKeyStatePrev[i]*2;
            switch (sum) {
                case  0:
                    break;

                case 1:
                    evKeyEventStatus[i] = 1;
                    break;

                case 2:
                    evKeyEventStatus[i] = 2;
                    break;

                case 3:
                    evKeyEventStatus[i] = 3;
                    break;

                default: evKeyEventStatus[i] = 0; break;
            }
            evKeyStatePrev[i] = evKeyStateCur[i];
        }
    }
}
void ev\u handle\u start()//启动事件处理程序。
void ev_handle_stop()//暂停事件处理程序。
**/
#包括
#包括
#包括
#包括“ev_handler.h”
#定义1
#定义发布的0
#定义TMR_频率33
#定义鼠标右键1
#定义鼠标左键3
#定义EV\u左键单击0
#定义EV\U LEFT\U版本1
#定义EV\u右键单击2
#定义EV_RIGHT_版本3
#定义EV_鼠标_最大值4
#定义最大扫描码SDL\U扫描码\U模式
#定义EV_延迟70
//********************************************************************************************//
//变数
//********************************************************************************************//
SDL_事件e;
Uint8*键盘状态;
SDL_TimerID ev_timer=NULL;//用于回调代码搜索的计时器
bool ev_handler_active=false;//用于确定ev_处理程序()是否已启用
bool按钮状态[EV_MOUSE_MAX];//按钮统计,按下或释放
bool evMouseEvent[EV_MOUSE_MAX];//用于标记鼠标是否发生事件
int evKeyEventStatus[最大扫描码];
布尔evKeyStatePrev[最大扫描码]//
布尔evKeyStateCur[最大扫描码]//
//********************************************************************************************//
//1前端
//********************************************************************************************//
//********************************************************************************************//
//1.1鼠标
//只能处理鼠标左键和右键。
//********************************************************************************************//
按下布尔EV按钮(int按钮)
{bool flag=button==SDL_button_RIGHT | | button==SDL_button_LEFT;
如果(!标志){
printf(“错误:isButtonPressed(int)接收到无效类型的参数。\n”);
返回false;
}
返回按钮状态[按钮];
}
bool evLeftClick()
{
返回evMouseEvent[左键单击];
}
bool evLeftRelease()
{
返回evMouseEvent[电动左前释放];
}
bool evRightClick()
{
返回evMouseEvent[EV_右键单击];
}
bool evRightRelease()
{
返回evMouseEvent[EV_RIGHT_RELEASE];
}
//********************************************************************************************//
//1.2键盘
//********************************************************************************************//
bool EVKEYHOLD(SDL_扫描码sc)
{
返回evKeyEventStatus[sc]==1 | | evKeyEventStatus[sc]==3;
}
按下bool evKeyPressed(SDL_扫描码sc)
{
返回evKeyEventStatus[sc]==1;
}
bool evKeyReleased(SDL_扫描码sc)
{
返回evKeyEventStatus[sc]==2;
}
//********************************************************************************************//
//1.3管理
//********************************************************************************************//
void evSetup()
{
对于(int i=0;i