首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SDL/C EventHandler连续键

SDL/C EventHandler连续键
EN

Stack Overflow用户
提问于 2016-12-31 03:54:52
回答 0查看 295关注 0票数 0

我正在尝试用C语言开发一个使用SDL的事件处理程序。

我希望能够检测到以下内容:按下键、释放键和按键。

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

由于这失败了,我尝试映射SDL_GetKeyboardState(NULL);,它在某种程度上是有效的。但是我有一个问题,如果我按住一个键X秒,它将在相同的时间内垃圾邮件幽灵事件。

按esc键,按住Esc键一段时间,然后松开它的输出示例如下:

代码语言:javascript
复制
Pressed
HELD
HELD
HELD
... 
RELEASED       {it breaks down after first proper release}
PRESSED        
RELEASED 
HELD
PRESSED 
RELEASED 
HELD
...
RELEASED     // it always ends on released.

上面的结果是:

代码语言:javascript
复制
Pressed: 18;
Released: 21;
Held: 39.

Should be:
Pressed 1;
Released 1;
Held: say 20. 

我不确定是我搞乱了逻辑,还是键盘事件的实际内置机制。

代码如下:

/**程序接口

代码语言:javascript
复制
    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];
        }
    }
}
EN

回答

页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41401980

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档