代码之家  ›  专栏  ›  技术社区  ›  therealkf

使用SDL2和OpenGL进行非瞬时/急速移动

  •  0
  • therealkf  · 技术社区  · 8 年前

    我一直在研究一个小3D引擎,试图修复相机,使其不那么笨拙。我一直在使用SDL进行输入,当它工作时,它正在做这样的事情,如果我按住一个按钮,它会立即移动一次,然后暂停,然后开始适当移动,使移动感觉没有反应。

    我记录了它的GIF,虽然可能很难看到发生了什么,但希望它能提供一些想法:

    gif

    向前看,然后向右看会是这样的:

    网址www.wwwwwww.www网址aaaaaaaaAAaaaaaaa

    这里有重要的代码,但如有必要,请随时索取更多:

    //Poll events
        SDL_Event event;
        while (m_EngineState != EngineState::EXIT)
        {
            m_last = m_current;
            m_current = SDL_GetPerformanceCounter();
            deltaTime = (double)((m_current - m_last) * 1000 / SDL_GetPerformanceFrequency());
    
            while (SDL_PollEvent(&event))
            {
                switch (event.type) {
                case SDL_QUIT:
                    m_EngineState = EngineState::EXIT;
                    break;
    
                case SDL_MOUSEMOTION:
                    break;
    
                case SDL_KEYDOWN:
                    m_Keys[event.key.keysym.sym] = true;
                    break;
                case SDL_KEYUP:
                    m_Keys[event.key.keysym.sym] = false;
                    break;
                }
                ProcessEvents();
            }
    
    void Engine::ProcessEvents()
    {
        if (m_Keys[SDLK_w])
        {
            m_Camera->MoveForward(5.0f*(deltaTime*0.001));
        }
        if (m_Keys[SDLK_s])
        {
            m_Camera->MoveForward(-5.0f*(deltaTime*0.001));
        }
        if (m_Keys[SDLK_d])
        {
            m_Camera->MoveRight(5.0f*(deltaTime*0.001));
        }
        if (m_Keys[SDLK_a])
        {
            m_Camera->MoveRight(-5.0f*(deltaTime*0.001));
        }
    }
    
    void Camera::MoveForward(float amount)
    {  
        m_pos += m_forward * amount;
    }
    
    void Camera::MoveRight(float amount)
    {
        m_pos += glm::cross(m_forward, m_up) * amount;
    }
    
    1 回复  |  直到 8 年前
        1
  •  5
  •   Coal Paul-Jan    3 年前

    不要使用 SDL_PollEvent SDL_KEYDOWN SDL_KEYUP 事件,它受操作系统键盘重复率的影响。这对于打字来说很好,但对于相机/播放器控件来说就不行了。使用 SDL_GetKeyboardState(NULL) 而不是查询密钥的当前状态。

    例如:

    Uint8* keystate = SDL_GetKeyboardState(NULL);
    
    if (keystate[SDL_SCANCODE_W])
    {
      m_Camera->MoveForward(5.0f*(deltaTime*0.001));
    }
    
    if (keystate[SDL_SCANCODE_S])
    {
      m_Camera->MoveForward(-5.0f*(deltaTime*0.001));
    }