Индикатор загрузки
Господа, не будет ли здесь кого-нибудь, кто разъяснит мне принцип работы loading_bara и метод его создания в Blitz3D? Заранее благодарю :@
|
Re: Индикатор загрузки
При создании программ вы рано или поздно сталкиваетесь с проблемой: программа выполняет какую-то неинтерактивную процедуру слишком долго. Причём в ходе написания она не раз зависала на этой процедуре, а вы тупо сидели минут пятнадцать в ожидании успешной загрузки; в более поздних стадиях, вы думали – «ну ещё секунд 20, и готово!» - на деле: вы сидели и ждали, вместо того, чтобы пройтись по комнате (в особо тяжких случаях – перекусить); и, наконец, когда игра была роздана друзьям-тестерам вы не раз наблюдали, как «тестер», посмотрев несколько секунд ваш чёрный экран (или, что того ещё хуже – застывший с выбранной кнопкой «START» GUI), кричал – «О, Боже! Всё повисло!»- и, в мгновение ока, дважды клацал по ctrl-alt-del.
Всё это из-за отсутствия визуализации процесса. А ведь всего этого бы не произошло, если бы вы заметили, что кол-во процентов выполненной части процедуры подозрительно долго не меняется, или индикатор загрузки, ещё не скоро дойдёт до конца, или перед тестером висела надпись «LOAD…» и крутились красивые шестеренки. Самый простой и привычный способ визуализации – прогресс бар (progress bar). Давайте посмотрим на наш гипотетический код: [highlight=blitzbasic] For i=1 To 100 m(i)=LoadAnimMesh(MODEL_FOLDER$+"car"+i+".x") Next [/highlight] Очевидно, что время уходит в нём на загрузку моделей (car1.x,car2.x и т.д.). Допустим, одна модель грузиться 10 мсек., т.е. наш цикл эквивалентен: [highlight=blitzbasic] For i=1 To 100 Delay 10 Next [/highlight] Премудростей здесь искать не надо – я просто избавил код от конкретики, чтобы упростить объяснение. Теперь нам надо чтобы определённая область закрашивалась соразмерно ходу выполнения цикла. Допустим область – это прямоугольник со сторонами 10 на 202 пикселей: [highlight=blitzbasic] Graphics 800,600 size_y%=10 size_x%=202 Color 255,0,0 For i=1 To 100 Rect 20,20,size_x,size_y,0 Flip Delay 10 Next [/highlight] Степень проникновения в процесс загрузки у нас вообще никакая: мы модем только что-то сделать ДО и ПОСЛЕ. Следственно – обновить прогресс бар (сообщить о ходе загрузки) мы сможем только 100 раз. Значит, за один раз мы будем закрашивать 100-ую часть области. Размеры этой части соответственно: [highlight=blitzbasic] ind_size_x%=(202-2)/100 ind_size_y%=10-2 [/highlight] А вот так мы будем рисовать индикатор: [highlight=blitzbasic] Graphics 800,600 SetBuffer BackBuffer() size_y%=10 size_x%=202 ind_size_x%=(202-2)/100 ind_size_y%=10-2 For i=1 To 100 Color 255,0,0 Rect 20,20,size_x,size_y,0 Color 120,120,120 Rect 20+1+ind_size_x*(i-1),20+1,ind_size_x,ind_size_y Flip Delay 10 Next [/highlight] Собственно – индикатор можно закрашивать и по-другому. Например, не 10 раз по одной 10ой со смещением, а 1/10 – затем, поверх неё, 2/10 и так далее. Или вывести в область картинку и поверх неё нарисовать чёрный прямоугольник, который будет всё время уменьшаться, однако на чёрном фоне окна, это создаст эффект появления картинки. Можно использовать различные абстрактные формы и траектории движений – всё зависит от конкретики игры и вашей фантазии. Единственное – не надо увлекаться: Время расчёта и вывода индикатора должно быть намного меньше времени выполнения одной итерации цикла. Если это никак не получается – обновляйте индикатор не каждый проход, а раз в N проходов. Или, возможно, вы выбрали неудачный масштаб? Например, при большом кол-ве вложенных циклов – обновлять прогресс бар в самом вложенном, почти всегда нерационально. Если у вас несколько громоздких операций (к примеру – 2 цикла), рассчитайте коэффициенты для закраски соответствующим образом. |
Re: Индикатор загрузки
Прогресс бар обычно является объектом GUI и для него предусмотрены уже готовые функции. Вот, например, как это может выглядеть на С++ с использованием MFC:
Мы создаём (в коде или редакторе) на форме объект – прогресс-бар, затем получаем на него указатель: [highlight=cpp] CProgressCtrl *PROG1=(CProgressCtrl*)GetDlgItem(IDC_PROGRESS1); [/highlight] Устанавливаем диапазон принимаемых значений: [highlight=cpp] PROG1->SetRange(0,COUNT); [/highlight] Устанавливаем величину шага: [highlight=cpp] PROG1->SetStep(1); [/highlight] Ставим сам индикатор на 0 [highlight=cpp] PROG1->SetPos(0); [/highlight] И каждую итерацию делаем один шаг индикатора: [highlight=cpp] PROG1->StepIt(); [/highlight] |
Re: Индикатор загрузки
[highlight=blitzbasic]
Graphics3D800,600,32,2 size_y# = 10 size_x# = 202 min# = 1 max# = 100 For i# = min To max Color 255,0,0 Rect 20, 20, size_x, size_y, 0 Rect 22, 22, (i/max)*size_x-4, size_y-4, 1 Delay 30 Flip Next[/highlight] А вот модифицированный вариант. Намного эффективнее. |
Re: Индикатор загрузки
И вот так ещё:
[highlight=blitzbasic] Graphics3D 800,600,32,2 size_y# = 10 size_x# = 202 min# = 1 max# = 100 Color 255,0,0 Rect 20, 20, size_x, size_y, 0 For i# = min To max Rect 22, 22, (i/max)*size_x-4, size_y-4, 1 Delay 30 Flip Next [/highlight] |
Re: Индикатор загрузки
Цитата:
Да и прогрессбар по идее должен весь перерисовываться, а не по отдельности. |
Часовой пояс GMT +4, время: 06:27. |
vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot