| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Звук, графика и видео > Как грамотно реализовать анимацию? |
| Автор: Alix 15.12.2007, 10:51 |
| Упрощу задачу, для более легкого понимания (реально все по-другому). Есть текстовой файл, с записями по одной в строке, вида: timeshift image где timeshift - время, когда надо отобразить этот image. (не точное, а "после наступления которого"). Программа запускается, запоминает в startTime время запуска (GetTickCount). В дальнейшем в Application.OnIdle вызывается функция, которая берет текущее время currentTime := GetTickCount - startTime, а затем просматривает записи от lastLine (инициализована -1), до той, у которой timeshift не будет > currentTime. По-хорошему, такая запись должна выбраться только одна. Затем рисуется соотвествующая картинка и lastLine меняется на индекс последней обработаной строки. Вроде все хорошо, но есть три минуса: 1. Сильно грузит процессор 2. Не всегда OnIdle вызывается быстро. Не знаю чем обусловлено, но при нетронутом коде заход в OnIdle может происходить раза в 2-3 реже, в результате анимация начинает жутко тормозить. Почему так происходит пока не понял. 3. Часто OnIdle вызывается при уже вызванном OnIdle. Т.е. функция еще работает, а система решает вызвать ее еще раз. Решал с помощью doing : boolean; При заходе if doing then exit else doing := true, при выходе doing := false; Использовать timer - не лучшая идея, т.к. работать с интервалом в 10-15 мс он не способен. Как можно обойти эти недостатки? |
| Автор: OdesitVadim 3.1.2008, 23:06 | ||||
| я бы сделал по простому. вначале весь файл загружается, сортируется, что бы картинки шли в нужном порядке. и составляется список пар время показа и адрес картинки. теперь запускаем поток, ставим ему приоритет выше среднего. его основной цикл будет выглядеть так.
использование sleep в потоке вполне разумно - поток просто будет засыпать. в основной форме делаем обработку сообщения, где то так
так как поток основное время будет спать, то приоритет можно сделать немного выше - что бы винда не пропускала его обработку. Единственный недостаток этой системы - в целом последовательность может немного разтянуться. (винда не гарантирует, что она точно выдержить все временные промежутки, но недодерживать она не будет, скорее передержит). Но это решить просто - у нас ведь есть поле, которое указывает, в какое время нужно показывать картинку. С помощью GetTickCount вначале запоминаем начальное время, а потом в цикле запрашиваем и корректируем задержку. Но! винда не гарантирует, что выдержит интервалы, которые короче 52 милисекунды. А на серверных вариантах - и все 130 (не уверен в точности числа, но точно чуть больше 100). Поэтому, если у вас будут интервалы меньше 0.1 секунды - то это плохая задумка. В таком случае лучше применить совершенно другие технологии - есть специальные программы, которые с набора картинок могут сделать видеофайл. Может это решит всё проблему? |
| Автор: Alix 3.1.2008, 23:14 |
| я сомневаюсь в надежности данного метода, т.к. неизвестно сколько времени пройдет от посылки сообщения до приема, да и интервалы там поменьше 50мс будут. Впрочем проблему почти решило использование мультимедийного таймера и иная реализация "спец-эффектов". Что до видеофайла, то у отдельных картинок и качество выше будет и размер суммарный меньше. |