2017-01-29 7 views
0

Раньше в моей основной петле игры время управлялось с частотой 60 FPS и соответствующей задержкой для временной задержки.Управление очередью Sprites через DeltaTime

Последовательность Sprite оживлялся следующим образом:

<pre> 
if(++ciclos > 10){ 
    siguienteSprite++; 
    ciclos = 0; 
} 
</pre> 

Учитывая, что я использую Smooth Motion с DeltaTime, поэтому я устранил задержки из основного цикла; Создание этого цикла sprites анимации происходит быстрее, и не только это, но и время между каждой последовательностью меняется.

Кто-то может дать мне руку, только с логикой этой проблемы, заранее спасибо. :)

ответ

2

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

  • OS зернистость
  • синхронизации с GFX карты/водитель
  • не постоянное время обработки

Есть несколько способов, как справиться с этим:

  1. мера времени

    <pre> 
    t1=get_actual_time(); 
    while (t1-t0>=animation_T) 
    { 
    siguienteSprite++; 
    t0+=animation_T; 
    } 
    // t0=t1; // this is optional and change the timing properties a bit 
    </pre> 
    

    где t0 некоторая глобальная переменная холдинга "последний" измеряется время изменения ОС спрайтов. t1 - фактическое время и animation_T - постоянная времени между изменениями анимации. Чтобы измерить время, вам нужно использовать OS api как PerformanceCounter на окнах или RDTSC в asm или любом другом, что вы получили под рукой, но с достаточно небольшим разрешением.

  2. таймер OS

    просто увеличиваем siguienteSprite в некоторых таймер с animation_T интервалом. Это просто, но таймеры ОС не являются точными и обычно составляют около 1 мс или более. Гранулярность ОС (аналогична точности Sleep).

  3. таймер Thread

    вы можете создать один поток для целей синхронизации, например, что-то вроде этого:

    for (;!threads_stop;) 
    { 
    Delay(animation_T); // or Sleep() 
    siguienteSprite++; 
    } 
    

    Не забывайте, что siguienteSprite должен быть volatile и буферизацией во время рендеринга, чтобы избежать мерцания и или ошибки нарушения доступа. Этот подход немного более точен (если только у вас нет единого ядра CPU).

    Вы также увеличиваете переменную времени и используете это как фактическое время в своем приложении с любым требуемым разрешением.Но будьте осторожны, если delay не возвращается CPU управления для OS, этот подход будет использовать ваш CPU в 100%/CPU_cores. Существует средство для этого, и что меняет ваш delay с этим:

    Sleep(0.9*animation_T); 
    for (;;) 
    { 
    t1=get_actual_time(); 
    if (t1-t0>=animation_T) 
        { 
        siguienteSprite++; 
        t0=t1; 
        break; 
        } 
    

Если вы используете измеренное время, то вы должны обращаться с переполнением (t1<t0), потому что любой счетчик будет переполняться времени. Например, используя 32-разрядную часть RDTSC по адресу 3.2 GHzЯдро центрального процессора будет переполняться каждые 2^32/3.2e9 = 1.342 sec, поэтому это реальная возможность. Если моя память хорошо работает, то счетчики производительности в Windows обычно работают около 3.5 MHz по более старым системам OS и около 60-120 MHz на более новых (по крайней мере, в последний раз, когда я проверяю) и 64 бит, поэтому переполнение не так уж и много для проблемы (если только вы 24/7). Также в случае использования RDTSC вы должны установить привязку процесса/нити к одиночному CPU ядро, чтобы избежать проблем с синхронизацией на многоядерном процессоре CPU s.

Я сделал мою долю бенчмаркинга и расширенному времени с высоким разрешением на низком уровне в течение многих лет, так вот несколько связанных QA s шахты:


wrong clock cycle measurements with rdtsc - OS Зернистость
Measuring Cache Latencies - измерение частоты процессора
Cache size estimation on your system? - PerformanceCounter пример
Questions on Measuring Time Using the CPU Clock - PIT как альтернативный источник синхронизации

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