![]() |
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]() ![]() ![]() |
|
bagos |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 275 Регистрация: 17.6.2006 Репутация: нет Всего: 1 |
Уважаемые поделитесь идеями, как сделать максимально сглаженным эффект передвижения формы по экрану.
то что сделал не устраивает
|
|||
|
||||
Xenag |
|
|||
![]() Шустрый ![]() Профиль Группа: Awaiting Authorisation Сообщений: 51 Регистрация: 6.3.2010 Репутация: нет Всего: нет |
Добавь в оба цикла перед Sleep
Application.ProcessMessages; Это сообщение отредактировал(а) Xenag - 30.11.2010, 23:12 |
|||
|
||||
remax |
|
|||
![]() Доцент ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 686 Регистрация: 7.4.2002 Где: Украина, Харьков Репутация: 1 Всего: 5 |
Sleep надо совсем убрать. Эта безусловная задержка не учитывает, что параллельно с Вашей программой выполняются и другие процессы. Для того, чтобы организовать "нормальную" равномерную задержку - надо использовать функцию GetTickCount.
Да, и конечно использовать Application.ProcessMessages; - иначе не будет нормально отрисовываться форма... =========== function GetTickCount: Longint; Считывает вpемя, пpошедшее с момента запуска системы. Возвpащаемое значение - Пpошедшее вpемя (в миллисекундах). Это сообщение отредактировал(а) remax - 1.12.2010, 00:39 -------------------- Как бы ты не старался быть хорошим и правильным человеком с принципами и уважительным отношением к другим, всегда найдется кто-то, кто бросит в тебя какашку |
|||
|
||||
bagos |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 275 Регистрация: 17.6.2006 Репутация: нет Всего: 1 |
Спасибо за ответы!
также пихал процесмесаг в цикл и геттиккаунт не помогает, шлейф солидный |
|||
|
||||
remax |
|
||||
![]() Доцент ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 686 Регистрация: 7.4.2002 Где: Украина, Харьков Репутация: 1 Всего: 5 |
не-не, GetTickCount нужен не сам по себе, а нужен результат который он возвращает. Именно его использовать при определении задержки между отображением.
Кроме того, скорость отрисовки формы СУЩЕСТВЕННО зависит от ее содержимого. И, самое главное, если недостаточные видеоресурсы или неправильно настроена система, то хоть что делай а толку не будет. Для начала надо убедиться, что, например, окно Блокнота перемещается (мышкой) без шлейфа... Вариант с таймером (интервал = 20)
Вариант с синхронизацией по GetTickCount (интервал перерисовки - те же 20 мс)
Это сообщение отредактировал(а) remax - 1.12.2010, 10:49 -------------------- Как бы ты не старался быть хорошим и правильным человеком с принципами и уважительным отношением к другим, всегда найдется кто-то, кто бросит в тебя какашку |
||||
|
|||||
Snowy |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 192 Всего: 484 |
Как раз в этом и смысл Sleep - замораживать текущий тред на указанное время и передавать уплавление системе. Если его не ставить, то загрузка процессора будет 100% |
|||
|
||||
remax |
|
|||
![]() Доцент ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 686 Регистрация: 7.4.2002 Где: Украина, Харьков Репутация: 1 Всего: 5 |
1. Да, Sleep - замораживает текущий тред. Но, его применение в лоб не позволяет обеспечить одинаковые задержки, особенно когда речь идет о малых временнЫх интервалах. А тем более, если система загружена другими ресурсоемкими приложениями, работающими в параллель. Обратите внимание на параметр Sleep у ТС. Точность 1мс Sleep не обеспечит - обычно речь идет о 10-15 мс. Т.е., при выборе значения параметра менее 15 задержка через Sleep обеспечит либо 15 мс, либо 0. И это без учета паралельных задач.... 2. Для передачи управления системе, обычно, вполне хватает Application.ProcessMessages; И при разумном его использовании ни о каких 100% загрузки проца речь не идет. (см. примеры из моего предыдущего топика). Это сообщение отредактировал(а) remax - 1.12.2010, 15:10 -------------------- Как бы ты не старался быть хорошим и правильным человеком с принципами и уважительным отношением к другим, всегда найдется кто-то, кто бросит в тебя какашку |
|||
|
||||
Snowy |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 192 Всего: 484 |
При постоянных условиях, интервал будет примерно одинаков. Для большинства задач этого за глаза.
В случае 2-х ядерного процессора, загрузка будет 50%... Ты вхолостую крутишь процессор без перерыва. Конечно там 100% загрузка. |
||||
|
|||||
remax |
|
||||
![]() Доцент ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 686 Регистрация: 7.4.2002 Где: Украина, Харьков Репутация: 1 Всего: 5 |
Пишем такой сложнейший код (на форме кнопка и мемо):
Запускаем. И, о чудо, смотрим результат. Результат представляет собой примерно такую повторяющуюся последовательность: 0 0 0 0 0 0 15 0 0 0 0 0 0 0 16 0 ... Что, конечно, практически не отличается от ожидаемой последовательности 1 1 1 1 1 1 ... Может быть эта проблема точности GetTickCount? По крайней мере "0" - это возможно меньше "1". Чтож, проверим - заменим sleep(1) на sleep(5). И что, что мы видим. Наверное ряд 5 или, хотя бы, 4? Нет, мы опять видим 16 0 15 0 0 16 0 0 16 0 15 0 16 0 0 Т.е., можно сделать вывод, что маленькая задержка через sleep либо вообще не делается либо в пределах точности 15 мс. Это при незагруженном процессоре. Теперь запустим наш тест и чем-то еще загрузим. Я, например, потаскаю по экрану окно другой программы. Смотрим результат: 0 63 0 0 125 62 63 62 47 0 16 0 15 32 31 31 .... На мой взгляд, это, во первых, сильно отличается от поставленной задачи. во вторых, далеко не равномерные интервалы. Выводы: 1. Использование Sleep не обеспечивает правильных программных задержек. Реализуемая точность +-15 мс. (зависит от конкретного компьютера) 2. При высокой загрузке системы и использовании Sleep возможны многократные увеличения интервалов паузы. 3. Соответственно, нежелательно использовать Sleep для малых интервалов - величина которых соизмерима с 10-15 мс. Это, если нам нужна точность, то паузу меньше чем 0.1 с через Sleep не делаем. 4. Не используем Sleep и для больших (больших, чем 1 с) интервалов - при этом, внешне прога выглядит как зависшая. т.е. Использовать Sleep можно для неточных пауз в интервале от 0.1 до 1.0 с. -------------------- Как бы ты не старался быть хорошим и правильным человеком с принципами и уважительным отношением к другим, всегда найдется кто-то, кто бросит в тебя какашку |
||||
|
|||||
remax |
|
||||
![]() Доцент ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 686 Регистрация: 7.4.2002 Где: Украина, Харьков Репутация: 1 Всего: 5 |
Я так понял, что уважаемый Snowy не счел нужным запустить указанные примеры. Тогда бы он увидел, что загрузка не все время 100%, а похожа на пилу. Всплески во время движения формы и провалы практически до 0 между движениями. Конечно, абсолютные цифры зависят от параметров каждой конкретной системы. Да и от выбранной дискретности движения. Но, это зависит не от применения/неприменения Sleep, а зависит оттого сколько ресурсов тратится на непосредственно отрисовку движения формы. Что, в прочем, совсем не удивительно, по крайней мере для меня. Поскольку применение Application.ProcessMessages позволяет корректно решить задачу эффективного использования ресурсов во время вынужденного простоя программы. П.С. Кстати, у ТС никак не было оговорена необходимость уменьшения загрузки проца. А необходимо было обеспечить плавность перемещения. Даже, если бы была 100% загрузки при равномерном перемещении, то задача была бы выполнена. В отличие от применения sleep... ![]() -------------------- Как бы ты не старался быть хорошим и правильным человеком с принципами и уважительным отношением к другим, всегда найдется кто-то, кто бросит в тебя какашку |
||||
|
|||||
Snowy |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 192 Всего: 484 |
Я не собираюсь спорить на тему, что Sleep не даёт высокой точности.
Это очевидно. Я говорил о том, что для данной задачи, такая точность совершенно ни к чему. Что касается загрузки. Да, при вызове ProcessMessages она падает. Но потом следует несколько сотен циклов полной нагрузки. То есть мы имеем 100% нагрузку с редкими спадами. Получается вот такая "пила" ![]() А теперь возьмём вариант со Sleep:
![]() |
|||
|
||||
RinOSpro |
|
|||
Unregistered |
remax ты до этого прошивку для атомных часов что ли писал)) Жжешь, смотрю на это "чудо"
и хочется спросить где ты такую траву берешь)? Твой цикл с GetTickCount тоже не обеспечит. Ты слышал что ни будь про вытесняющую многозадачность, и планирование потоков в виндовс? Почитай) Ссылку кидать не буду ибо она прикреплена на очень видном месте) Ах да, прочти еще раз название темы. Автор и в правду не атомные часы делает у него цель менее амбициозная. |
|||
|
||||
remax |
|
||||
![]() Доцент ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 686 Регистрация: 7.4.2002 Где: Украина, Харьков Репутация: 1 Всего: 5 |
Жаль, что приходится объяснять очевидные вещи, но видно без этого не обойтись. 1. Для отображения красивого перемещения формы необходимо обеспечить высокую степень равномерности. Очевидно? 2. Если делать ни с чем не синхронизированные задержки разной величины (от 0 до 15), то равномерности не будет. Очевидно? 3. Мой пример при незагруженном компьютере обеспечивает задержки 20мс с точностью до 1 мс. Очевидно? 4. В случае высокой загрузки компьютера возможны просчеты, которые не нарушат равномерности движения. Почему? Смотрим на код: n:=(n+3*((GetTickCount-tm)div 20)) mod 360; Если для кого не дошло - объясняю: если пауза прошла больше, чем рассчитано в разы, то и перемещение будет выполнено пропорционально больше. Ясно? Кстати, не надо объяснять из каких соображений был выбран интервал 20мс? П.С. Snowy, Вы не будете возражать, что если использовать Sleep(1000) или Sleep(1000000) ![]() П.П.С. Мне казалось, что пора менять свой старенький ноут. Но! Если он настолько быстрее работает, чем компьютер Snowy, тонаверное, еще подожду ![]() -------------------- Как бы ты не старался быть хорошим и правильным человеком с принципами и уважительным отношением к другим, всегда найдется кто-то, кто бросит в тебя какашку |
||||
|
|||||
remax |
|
|||
![]() Доцент ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 686 Регистрация: 7.4.2002 Где: Украина, Харьков Репутация: 1 Всего: 5 |
Ага, понятно почему у Snowy такой график загрузки. На более мощном компе, действительно, пила на уровне 100% ядра (50% проца). И причина понятна - больше "холостых" циклов. Правда, непонятно почему так мало зубьев у пилы. Спишем на дискретность измерений.
Выводы: 1. Точность sleep на малых значениях никуда не годится. Можно с уверенностью говорить, что на значениях интервала меньше 10 мс он вообще практически не делает паузу (при стандартных настройках ОС). А на 20 мс он, в среднем, дает ошибку до 5% даже на "незагруженном" копьютере. Однако, если не использовать sleep, особенно на быстрых компьютерах - возможна необоснованная 100% загрузка компа. 2. Самый эффективный подход - мой вариант с таймером: никаких лишних действий, никакой неравномерности, никакой лишней загрузки системы. Единственное, что в нем надо для 100% правильности тоже надо привязать движение не к событиям таймера, а к GetTickCount. Это сообщение отредактировал(а) remax - 2.12.2010, 19:20 -------------------- Как бы ты не старался быть хорошим и правильным человеком с принципами и уважительным отношением к другим, всегда найдется кто-то, кто бросит в тебя какашку |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: Общие вопросы" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |