SDL_GetKeyboardState无效

时间:2014-04-27 20:53:19

标签: c input keyboard sdl

我正在尝试为SDL 2的游戏制作一个控制器(不想在gamedev上询问因为它不是直接的游戏问题)我使用SDL_GetKeyboardEvent来查看导航箭头是否被按下但是它显然没有不工作,如果按下其中一个键,它应该打印一个值1或-1但它不会打印0即使我按住键几秒钟,它就像它没有检测到钥匙被按下了。我搜索了整个互联网,这就是他们这样做的方式,但它对我不起作用。

#define SDL_MAIN_HANDLED
#include <stdio.h>
#include "SDL.h"

/* I'll add some code later
so something that isn't used
might be initialized
*/
int main (void)
{
    int a = 1;
    int x;
    int z;
    SDL_Event quit;
    const Uint8 *keys = SDL_GetKeyboardState(NULL);

    SDL_Init(SDL_INIT_VIDEO);

    while(a)
    {
        SDL_PollEvent(&quit);
        if(quit.type == SDL_QUIT)
            a = 0;

        if(keys[SDL_SCANCODE_UP])
            z = 1;
        else if(keys[SDL_SCANCODE_DOWN])
            z = -1;
        else
            z = 0;
        if(keys[SDL_SCANCODE_LEFT])
            x = -1;
        else if(keys[SDL_SCANCODE_RIGHT])
            x = 1;
        else
            x = 0;
        printf("%d, %d\n", x, z);
//This is supposed to print
//x, z values so if up arrow is pressed it will print 0, 1 and if
//down arrow is pressed it will print 0, -1: the same with horizontal ones.
//1 or -1, 1 or -1
    }

    SDL_Quit();
    return 0;
}

4 个答案:

答案 0 :(得分:0)

似乎您只更新键盘状态一次

SDL_GetKeyboardState(NULL);

应该在循环中使用。

尽管如此,输入管理通常是这样做的:

switch(quit.type)
{
    case SDL_KEYDOWN:
    switch(quit.key.keysym.sym)
    {
        case SDLK_ESCAPE:
            //quit
        case SDLK_UP:
            //up arrow
            break;
        case SDLK_DOWN:
            //down arrow     
            break;
        case SDLK_RIGHT:
            //right arrow
            break;
        case SDLK_LEFT:
            //left arrow
            break;
        default : break;
    }
    case SDL_KEYUP
    ...

而不是在每一帧都获得所有键盘,你看起来有什么变化。

此外,您不应在不限制帧速率的情况下使用SDL_PollEvent。

答案 1 :(得分:0)

阅读文档:wiki

Note: This function gives you the current state after all events have been processed, so if a key or button has been pressed and released before you process events, then the pressed state will never show up in the SDL_GetKeyboardState() calls

这意味着什么?

您需要处理所有事件。怎么样?在循环之后循环PollEvent(或者如果要检查循环,请在结尾处检查),SDL_GetKeyboardState可用。

因此,通过循环,检查键盘状态。不要忘记在检查密钥之前总是经历循环

e.g。

while (game)
    {
        /*! updates the array of keystates */
        while ((SDL_PollEvent(&e)) != 0)
        {
            /*! request quit */
            if (e.type == SDL_QUIT) 
            { 
                game = false;
            }
        }

        if (keys[SDL_SCANCODE_RIGHT])
            std::cout << "Right key";
    }

答案 2 :(得分:0)

这是我的InputManager更新功能,用于更新键盘和鼠标的用户输入。请注意,const_cast需要能够更新类变量Uint8* keysArray;。这样,一次可以处理多个事件。

    void update() {
        SDL_PumpEvents();

        // update keyboard state
        keysArray = const_cast <Uint8*> (SDL_GetKeyboardState(NULL));

        if (keysArray[SDL_SCANCODE_RETURN])
            printf("MESSAGE: <RETURN> is pressed...\n");
        if (keysArray[SDL_SCANCODE_RIGHT] && keysArray[SDL_SCANCODE_UP])
            printf("MESSAGE: Right and Up arrows are pressed...\n");

        // update mouse location and button states
        SDL_GetMouseState(&x, &y);
        getMouseButtonStates();
}

答案 3 :(得分:0)

您需要使用SDL_SetVideoMode创建一个窗口来获取鼠标和键盘事件。