Кук-бук. Рецепт прогресса

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

Вы когда-нибудь загружали «тяжелые» флеш-игры или ролики из Интернета? Единственное, что могло скрасить ожидание – какая-нибудь медленно ползущая полоска индикатора загрузки. Сделать такой прогресс-бар можно несколькими способами, и один из них мы сегодня рассмотрим.

Для начала давайте определимся со средой разработки. Adobe Flash, конечно, замечательная программа для аниматора или дизайнера, но если вы решили сделать, к примеру, игру, то среда Flash будет лишь инструментом второстепенной важности. Серьезный продукт вы в ней не создадите. Идеальным выбором будет система разработки, заточенная именно под программиста, – FDT, Flash Developer или FLEX Builder. Я предпочитаю последний вариант и рекомендую вам если не начать использовать постоянно, то хотя бы ознакомиться с этой программой.

Первым делом создадим во FLEX новый ActionScript-проект. Основной класс приложения назовем «Main». Можно назвать его и иначе, но имя нужно будет использовать позже и лучше выработать у себя привычку к единообразию в своих проектах.

Как правило, создаваемые таким образом flash-ролики имеют всего один кадр, но такое поведение компилятора, собирающего ролик, можно изменить с помощью мета-тегов в тексте программы.

Вот так может выглядеть простейший ролик, который создается исключительно средствами языка программирования ActionScript3:

package
{
import flash.display.Sprite;

public class Main extends Sprite
{
public function Main()
{
}
}
}

Скомпилировав и запустив его, вы получите просто пустое окошко flash-плеера с цветом фона по умолчанию. Теперь давайте модифицируем этот текст:

package
{
import flash.display.Sprite;
import Preloader;

[Frame(factoryClass="Preloader")]
[SWF(pageTitle="Main", width="640", height="480", widthPercent="100", heightPercent="100", frameRate="30", backgroundColor="#000000")]

public class Main extends Sprite
{
[Embed(source="test.tmp", mimeType="application/octet-stream")]
var Src:Class;

public function Main()
{
}
}
}

В тексте появилось несколько мета-тегов. Первый из них [Frame] – самый интересный. Он слабо документирован, но найти информацию о нем все- таки можно, причем даже в официальной документации Adobe. Его назначение – создание нового кадра в клипе Flash. В данном примере он создаст первый кадр во flash-ролике и класс Preloader, который будет работать в этом кадре. Все остальные данные будут грузиться во втором кадре. Второй мета-тег [SWF] задает параметры вашего ролика по умолчанию, в данном случае он определяет Название, размеры, частоту кадров и цвет фона флешки, которую вы создаете исключительно программными средствами, без дизайнерской среды Adobe Flash.
Третий мета-тег [Embed] позволяет включить в ресурсы вашей флешки разнообразные данные – картинки, видео, звуки, другие flash-ролики и двоичные данные, как это сделал я в приведенном примере. Это не обязательно, но я положил в папку проекта файл “test.tmp” размером в несколько десятков мегабайт, чтобы иметь возможность при локальном запуске увидеть прогресс-бар, поскольку flash-ролик с вашего компьютера будет загружаться очень быстро (разумеется, при создании реальной программы это не нужно).
Приведенный пример у вас не скомпилируется и не запустится должным образом, поскольку мы указали еще один класс «Preloader», но нигде его не описали. Давайте создадим в проекте новый файл «Preloader.as» и внесем в него такие строки:

package
{
import flash.display.DisplayObject;
import flash.display.MovieClip;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.utils.getDefinitionByName;

public class Preloader extends MovieClip
{

public function Preloader()
{
stop();
stage.scaleMode=StageScaleMode.NO_SCALE;
stage.align=StageAlign.TOP_LEFT;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
super();
drawPreloader();
}

public function drawPreloader():void
{
var percent:Number=root.loaderInfo.bytesLoaded / root.loaderInfo.bytesTotal;
graphics.lineStyle(2, 0xcccccc)
graphics.drawRect(0, 0, 200, 12);
graphics.lineStyle(2, 0xffffff)
graphics.beginFill(0xffffff);
graphics.drawRect(3, 3, 194 * percent, 6);
graphics.endFill();
}

public function onEnterFrame(event:Event):void
{
graphics.clear();
if (framesLoaded == totalFrames)
{
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
nextFrame();
init();
}
else
{
drawPreloader()
}
}

private function init():void
{
var main:Class=Class(getDefinitionByName("Main"));
if (main)
{
var app:Object=new main();
addChild(app as DisplayObject);
}
}
}
}

Строки import в начале файла указывают, какие стандартные классы Flash мы используем. В этом классе мы создали несколько своих функций: «Preloader» – конструктор класса, т.е. функция, которая инициализирует наш прогресс-бар при его создании.

«drawPreloader» – функция рисования прогресс-бара. Она очищает то, что уже было нарисовано, и рисует заново, определяя размер прогресс-бара в зависимости от количества уже загруженных данных.

«onEnterFrame» – функция, которая вызывается в каждом кадре (т.е. 30 раз в секунду для нашего ролика). Она просматривает количество загруженных данных, и если оно равно размеру всего ролика, дает команду перейти на следующий кадр и вызвать последнюю функцию «init». «init» - функция инициализации. Когда flash-ролик полностью загрузился, она выводит его на экран и запускает на исполнение.

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

Желаю вам успехов!

Поляков Александр, Lecosson@mail.ru


Компьютерная газета. Статья была опубликована в номере 47 за 2009 год в рубрике soft

©1997-2022 Компьютерная газета