微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – 如何使用SDL一次处理多个按键?

使用c在Ubuntu上使用SDL熟悉OpenGL编程.经过一些环顾和试验,我开始明白了.我需要SDL的键盘事件处理方面的建议.

我有一个第一人称相机,可以左右走fwd,back,strafe,并使用鼠标环顾四周,这是伟大的.这是我的processEvents函数

void processEvents()
{
    int mid_x = screen_width  >> 1;
int mid_y = screen_height >> 1;
int mpx = event.motion.x;
int mpy = event.motion.y;
float angle_y  = 0.0f;
float angle_z  = 0.0f;

while(SDL_PollEvent(&event))
{
    switch(event.type)
    {
        case SDL_KEYDOWN:
            switch(event.key.keysym.sym)
            {
                case SDLK_ESCAPE:
                    quit = true;
                    break;
                case SDLK_w:
                    objCamera.Move_Camera( CAMERASPEED);
                    break;
                case SDLK_s:
                    objCamera.Move_Camera(-CAMERASPEED);
                    break;
                case SDLK_d:
                    objCamera.Strafe_Camera( CAMERASPEED);
                    break;
                case SDLK_a:
                    objCamera.Strafe_Camera(-CAMERASPEED);
                    break;
                default:
                    break;
            }
            break;

        case SDL_MOUSEMOTION:
            if( (mpx == mid_x) && (mpy == mid_y) ) return;

            SDL_WarpMouse(mid_x,mid_y);

            // Get the direction from the mouse cursor,set a resonable maneuvering speed
            angle_y = (float)( (mid_x - mpx) ) / 1000;      
            angle_z = (float)( (mid_y - mpy) ) / 1000;

            // The higher the value is the faster the camera looks around.
            objCamera.mView.y += angle_z * 2;

            // limit the rotation around the x-axis
            if((objCamera.mView.y - objCamera.mPos.y) > 8)  objCamera.mView.y = objCamera.mPos.y + 8;
            if((objCamera.mView.y - objCamera.mPos.y) <-8)  objCamera.mView.y = objCamera.mPos.y - 8;

            objCamera.Rotate_View(-angle_y);

            break;

        case SDL_QUIT:
            quit = true;
            break;

        case SDL_VIDEORESIZE:
            screen = SDL_SetVideoMode( event.resize.w,event.resize.h,screen_bpp,SDL_OPENGL | SDL_HWSURFACE | SDL_RESIZABLE | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE );
            screen_width = event.resize.w;
            screen_height = event.resize.h;
            init_opengl();
            std::cout << "Resized to width: " << event.resize.w << " height: " << event.resize.h << std::endl;
            break;

        default:
            break;
    }
}
}

现在在工作的时候,它有一些限制.最大的一个,我的问题的目的是,似乎只是处理最新的按键.所以,如果我抱着’向后走’,我按’d’来说是正确的,我最后就是争取权利,而不是倒退.

有人可以指出我正确的方向,以更好的键盘处理与SDL,一次支持多个按键等?

谢谢

解决方法

一个很好的方法是写一个处理输入事件的键盘(“input”)处理程序,并将事件的状态保持在某种结构中(关联数组听起来很好 – 键[keyCode]).

每当键盘处理程序接收到“按键”事件时,它将该键设置为启用(true),并且当它获取一个关键的事件时,它将其设置为禁用(false).

然后,您可以一次检查多个键,而不直接拉动事件,您将能够在整个框架上重复使用键盘,而不会将其传递到子程序.

一些快速伪码:

class KeyboardHandler {
    handleKeyboardEvent(SDL Event) {
        keyState[event.code] = event.state;
    }

    bool ispressed(keyCode) {
        return (keyState[keyCode] == pressed);
    }

    bool isReleased(keyCode) {
        return (keyState[keyCode] == RELEASED);
    }

    keyState[];
}

...

while(SDL Pull events)
{
    switch(event.type) {
        case SDL_KEYDOWN:
        case SDL_KEYUP:
                keyHandler.handleKeyboardEvent(event);
            break;
        case SDL_ANOTHER_EVENT:
                ...
            break;
    }   
}

// When you need to use it:
if(keyHandler.ispressed(SOME_KEY) && keyHandler.ispressed(SOME_OTHER_KEY))
    doStuff(TM);

原文地址:https://www.jb51.cc/c/115867.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐