2013-12-16 5 views
1

У меня есть следующий код, который является частью некоторой функции, которая перемещает точку на экране. Я использую SDLОчередь событий SDL

if(SDL_PollEvent(&event)){ 

    //BreakPoint A 

    if(event.type == SDL_KEYDOWN) 
     if(event.key.keysym.sym == SDLK_d){ 
      goLeft = true; 
      //BreakPoint B 
     } 
    else if(event.type == SDL_KEYUP) 
     if(event.key.keysym.sym == SDLK_d){ 
      goLeft = false; 
      //BreakPoint C 
     } 
    else{ 
     //BreakPoint D 
    } 

} 

//BreakPoint E 

//Move sprites and other things.. 
//Update screen .. 

Все это в то время loop.Each этот цикл побежал, расчеты делаются для перемещения из точки и кадр визуализируется. Моя проблема в том, что когда я непрерывно нажимаю 'D', после выхода из кнопки точка не останавливается немедленно.

if(SDL_PollEvent(&event)){ Изменение
к while(SDL_PollEvent(&event)){ вещи Ok.Why это происходит?

Предполагается, что при непрерывном нажатии кнопки «D» очередь событий наводняется событиями ввода с клавиатуры. Многие из этих событий вставляются в очередь событий, и все это происходит в одном кадре рендеринга или в одном итерация цикла, о которой я говорил выше, но на каждом кадре я удаляю только одно событие из очереди. Поэтому, когда я оставляю кнопку «D», больше не добавляются события и происходит «лишнее» перемещение, потому что для получения события, D 'был выпущен и обновлен переменная goLeft. Сначала я должен удалить все те события, которые наводнили очередь один за другим. Таким образом, пока они не будут освобождены, точка будет перемещаться.

Но с другой стороны, если у меня есть while(SDL_PollEvent(&event)){ и «D» постоянно нажата, он когда-нибудь покинет эту внутреннюю петлю? Поскольку этот цикл запускается, пока в очереди есть события, и, как я уже сказал, я постоянно вставляю их, нажимая «D».

EDIT

Как я уже говорил с петлей в то время как он работает нормально, и это на самом деле ускользает от loop.How это происходит?
И от некоторых тестов, которые я сделал, я увидел, что при нажатии кнопки «D» непрерывно программа выполняется на каждой внешней итерации цикла следующим образом:

  • BreakPoint A
  • точку останова B
  • BreakPoint A
  • C
  • точку останова
  • E точку останова

ответ

1

я тонкий Я просто ответил на аналогичный Prob lem: SDL mouse events are not being handled quick enough

Кажется, что вы испытываете ту же проблему, а именно ожидаете vsync в середине цикла событий. Если вы ждете события постоянно срабатывает, вы можете сделать что-то вроде:

Uint32 timeout = SDL_GetTicks() + 10; 
while(SDL_PollEvent(&events) && !SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) {...} 

Это будет гарантировать, что ваш цикл обработки событий не работает в течение более чем 10ms.Or вы могли бы иметь счетчик и убедитесь, что вы не делаете для более, чем "x" итераций.

+0

Прежде всего, спасибо за ваш ответ. На самом деле происходит то, что он выходит из цикла. Поскольку, как я сказал, он отлично работает с циклом while. И одна часть моего вопроса - почему и как это происходит. –

+0

Это ускользает от цикла while, потому что даже если у вас высокая частота повторения клавиатуры, вы получите новое ключевое событие максимум каждые 100 миллисекунд или около того (10 ключевых событий в секунду, но я думаю, что это, как правило, намного более низкая ставка).Тем временем очередь в основном пуста (давайте или принимаем несколько событий мыши), поэтому цикл while завершается. Если вы вместо этого удаляете события один за другим, используя «if» (по сравнению с «while»), возможно, что куча событий накапливается во время рендеринга, что дает эффект «замедленного движения», который вы видите, когда вы перестаете нажимать клавишу. – gabomdq

+0

Можете ли вы объяснить, почему эта ставка низкая? Имеет ли SDL намеренно это из операционной системы? –

Смежные вопросы