2015-07-19 181 views
0

我正在按鍵之間產生一個主要的(1-2秒)延遲。SDL事件處理延遲

下面是main.cpp中(滯後輸入處理):

#include <iostream> 

#include "src/Input/InputManager.h" 
#include "src/Graphics/Display.h" 

#define LOG(x) std::cout << x << std::endl; 

using namespace Rambug; 

int main(int arc, char** argv) 
{ 
    Graphics::Display display(900, 600, "Rambug Engine Tester", true); 
    display.createDisplay(); 

    SDL_Event event; 
    Input::InputManager inputManager; 

    // "Game" Loop 
    while (!display.isClosed()) 
    { 
     display.update(); 

     glClearColor(0.0f, 0.02f, 0.5f, 1.0f); 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

     while (SDL_PollEvent(&event)) 
     { 
      if (event.type == SDL_KEYDOWN) 
      { 
       std::cout << "Keydowner" << std::endl; 
      } 
      if (event.type == SDL_KEYUP) 
      { 
       std::cout << "Keyupper" << std::endl; 
      } 
     } 

    // inputManager.update(); 
    } 

    display.destroyDisplay(); 

    system("PAUSE"); 
    return 0; 
} 

這裏是Display.cpp,其運行完全沒有任何延遲,當我運行相同的代碼(SDL_KEYDOWN,SDL_KEYUP)我就跑SDL_QUIT在下面。

#include "Display.h" 

namespace Rambug 
{ 
    namespace Graphics 
    { 
     Display::Display(int width, int height, std::string title, bool log) 
     { 
      m_displayWidth = width; 
      m_displayHeight = height; 
      m_displayTitle = title; 
      m_log = log; 
      m_window = nullptr; 
     } 

     Display::Display() 
     { 

     } 

     Display::~Display() 
     { 

     } 

     void Display::createDisplay() 
     { 
      // Initialize SDL 
      SDL_Init(SDL_INIT_EVERYTHING); 

      // Setting attributes to our window 
      SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); 
      SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); 
      SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); 
      SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); 
      SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32); 
      SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 

      // Create window 
      m_window = SDL_CreateWindow((m_displayTitle.c_str()), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_displayWidth, m_displayHeight, SDL_WINDOW_OPENGL); 

      // Error Check Window 
      if (m_window == nullptr) 
      { 
       if (m_log) 
        std::cerr << "Window could not be created!" << std::endl; 
      } 
      else 
      { 
       if (m_log) 
        std::cout << "Window Created Successfully With SDL!" << std::endl; 
      } 

      // Create OpenGL Context 
      m_glContext = SDL_GL_CreateContext(m_window); 

      // Initialize GLEW 
      glewExperimental = GL_TRUE; 
      GLenum status = glewInit(); 

      if (glewExperimental) 
      { 
       if (m_log) 
        std::cout << "Glew Experimental: On" << std::endl; 
      } 

      // Error Check GLEW 
      if (status != GLEW_OK) 
      { 
       if (m_log) 
       { 
        std::cerr << "GLEW could not be initialized!" << std::endl; 
       } 
      } 
      else 
      { 
       if (m_log) 
       { 
        std::cout << "GLEW Was Initilized Successfully!" << std::endl; 
       } 
      } 

      // Log OpenGL Version Number 
      if (m_log) 
      { 
       std::cout << "Using OpenGL Version: " << glGetString(GL_VERSION) << std::endl; 
      } 

      m_closed = false; 
     } 

     void Display::destroyDisplay() 
     { 
      SDL_GL_DeleteContext(m_glContext); 
      SDL_DestroyWindow(m_window); 
      SDL_Quit(); 
     } 

     void Display::update() 
     { 
      SDL_GL_SwapWindow(m_window); 

      // Check for Input 
      while (SDL_PollEvent(&m_sdlEvent)) 
      { 
       if (m_sdlEvent.type == SDL_QUIT) 
       { 
        m_closed = true; 
       } 
      } 
     } 

     bool Display::isClosed() 
     { 
      return m_closed; 
     } 
    } 
} 

我也嘗試過使用輸入管理器類進行試驗,但這是相同的處理:延遲。更新的方法是什麼,我會在main.cpp中(我認爲,它已被註釋掉)

#include "InputManager.h" 
#include <iostream> 

#define LOG(x) std::cout << x << std::endl; 

namespace Rambug 
{ 
    namespace Input 
    { 
     InputManager::InputManager() 
     { 

     } 

     InputManager::~InputManager() 
     { 

     } 

     void InputManager::keyPressed(unsigned int keyCode) 
     { 
      m_keyMap[keyCode] = true; 
     } 

     void InputManager::keyReleased(unsigned int keyCode) 
     { 
      m_keyMap[keyCode] = false; 
     } 

     bool InputManager::isKeyDown(unsigned int keyCode) 
     { 
      auto it = m_keyMap.find(keyCode); 

      if (it != m_keyMap.end()) 
      { 
       return it->second; 
      } 
      else 
      { 
       return false; 
      } 
     } 

     void InputManager::update() 
     { 
      while (SDL_PollEvent(&m_event)) 
      { 
       switch (m_event.type) 
       { 
       case SDL_KEYDOWN: 
        LOG("SDL_KEYDOWN"); 
        keyPressed(m_event.key.keysym.sym); 
        break; 
       case SDL_KEYUP: 
        LOG("SDL_KEYUP"); 
        keyReleased(m_event.key.keysym.sym); 
        break; 
       } 
      } 
     } 
    } 
} 

所以輸入管理和main.cpp中有重大延誤打電話,而Display.cpp運行完美。是否因爲我無法運行兩次SDL_PollEvents?

+0

對兩個不同地方的事件進行投票似乎確實是一個糟糕的主意。您應該從Display類中移除它,並以其他方式處理退出事件。 – jpw

回答

1

是不是因爲我不能運行SDL_PollEvents兩次?

你的問題不是我所期望的,但是,是的,運行SDL_PollEvents兩次是個壞主意。 SDL保留一個事件堆棧,該堆棧在您的程序運行時添加。 SDL_PollEvents從堆棧中彈出事件直到它爲空。結果,運行兩個輪詢循環,一個會刪除另一個不會看到的事件。盲目運氣(或運行瓶頸)將決定哪個循環更有可能發生任何特定事件。 (見http://wiki.libsdl.org/SDL_PollEvent)。

如果你真的想運行兩個輪詢循環,可以存儲事件未處理在默認情況下,每個迴路與SDL_PushEvent後回推事件列表:http://wiki.libsdl.org/SDL_PushEvent

此說,我很驚訝,你的活動在延遲後「通過」:我希望它們消失。你握着鑰匙了嗎?然後,你的操作系統密鑰重複延遲可能就是你所看到的,之後事件隊列在每個循環之間被淹沒。您可能要檢查的一些關鍵事件的重複標誌:http://wiki.libsdl.org/SDL_KeyboardEvent

我會說這指向一個設計問題。你應該問自己,爲什麼顯示器委託遊戲結束?把這個事實告訴顯示器和其他所有事情,是不是更明智?

+0

是的,當我拿着它時,它確實註冊了,而不是當我快速點擊它時。我現在進行了嘗試,從Display類中刪除了PollEvents,並且在InputManager類中只有一個輪詢事件。感謝您的幫助 –

+0

@JavaManTeaMan很高興能幫助您!如果您的問題得到解決,您應該考慮將答案標記爲解決方案,或者您可以將自己的解決方案作爲答案並標記出來。這樣很明顯,問題解決了,答案是什麼。 – Qualia