2015-10-03 3 views
4

У меня есть приложение, написанное в QT, которое использует QTimer. Это в основном игра, и все действия контролируются таймером. Игра включает в себя способность увеличивать \ уменьшать скорость игры. Код увеличения скорости являетсяQTimer setInterval без сброса оставшегося времени

timerValue -= speedUpValue; 
    if (timerValue < maxSpeed) { 
     timerValue = maxSpeed; 
    } 
    timer -> setInterval(timerValue); 

speedUpValue и maxSpeed константы. Для уменьшения скорости используется почти тот же код. Проблема в том, что setInterval сбрасывает внутренний таймер, и поэтому, если вы постоянно увеличиваете или уменьшаете скорость, игра в итоге никогда не будет продолжаться, потому что remainingTime постоянно сбрасывается. Есть ли способ установить remainingTime вручную или изменить интервал, не перезагружая его?

+1

Нет, нет возможности изменить интервал без автоматического перезапуска таймера. Однако вы можете добиться аналогичного эффекта, только обновляя интервал, когда таймер истечет. –

ответ

3

Вы можете полностью опустить объект таймера и вместо этого использовать статический метод QTimer::singleShot(...) и установить новый одиночный снимок на каждое событие таймера с помощью timerValue. Поэтому независимо от того, как часто изменяется timerValue, каждый цикл таймера будет завершен со старым значением и запланирован с текущим значением.

Как упоминалось в РА, вы можете эффективно достичь того же, что и объект таймера, но перемещая setInterval() на событие таймера, в основном то же самое, что и выше, но сохраняя объект таймера, если вам это нужно по какой-то причине.

Как отметил Крейг в комментариях, первый подход также гарантирует, что события таймера не накапливаются, если ваша логика игры занимает больше времени. Кроме того, если вы идете на асинхронный дизайн, возможно, что следующий игровой цикл начнет выполнение до того, как старый будет завершен, если вы перейдете на непрерывный таймер.

В этом отношении лучше не использовать постоянно работающий таймер, а планировать каждый следующий игровой цикл вручную, и только если вам нужно. Например, вам может не потребоваться запланировать другое, если игра подходит к концу. Кроме того, это позволит более точно контролировать, насколько точна скорость игры, после завершения игрового цикла вы можете рассчитать, сколько времени осталось до следующего, и запланировать его с этим значением, или если выполнение выполнено слишком долго, вы можете запланировать его немедленно.

+1

Дополнительным преимуществом использования одного кадра каждый раз является то, что тогда события не накапливаются. Если вы используете QTimer и не можете потреблять свои сигналы так быстро, как они генерируются, они накапливаются. Единичные снимки не могут накапливаться так, потому что вы запускаете только один из них при работе с текущим. Основным недостатком является меньшая точность/регулярность интервала. –

+0

@CraigScott: Я знаю, что это все старые новости, но это лучшая информация, которую я могу найти на данный момент. [Этот ответ] (https://stackoverflow.com/a/17077411/3491308), похоже, предполагает, что периодические события QTimer не накапливаются в любом случае. Больше похоже на проверку в конце цикла события, чтобы узнать, прошло ли заданное время. Если он, даже грубо, запускает одно событие и сбрасывает таймер. Какой правильный? – AaronD

+0

@AaronD Прошло много времени с тех пор, как я сделал вышеупомянутый комментарий, но я думаю, что это было основано на фактическом поведении, которое я видел, а не на гипотезе. Слишком давно для меня, чтобы запомнить детали, так что вам придется делать свои собственные тесты, чтобы проверить поведение с последним Qt. –

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