Пример простого Flash приложения на Action Script 3, компилируемого с помощью MXMLC
09-10-2010 14:35:51
Недавно мне нужно было сделать небольшой SWF-ролик с парой кнопок и несколькими картинками. Так как мой основной рабочий инструмент - Linux, то и делать ролик решил с помощью "открытого" программного обеспечения. Кстати, это же программное обеспечение доступно и под Windows.
Компания Adobe в данный момент предоставляет Flex4 SDK - бесплатное программное обеспечение для компиляции SWF-файлов из исходников, написанных на Action Script 3.0 (далее - AS3). Flex4 SDK содержит все библиотеки Flex, библиотеки Flash MX, и компилятор mxmlc, с помощью которого можно компилировать в формат SWF как файлы *.mxml (формат Flex), так и AS3-программы.
Сразу скажу пользователям Windows - Flex4 SDK есть и под Windows, однако лучше сразу установить и среду FlashDevelop. Это удобная OpenSource среда разработки, которая после правильной настройки включает в себя все нужные части из Flex SDK. Она предназначена для комфортного написания и компилирования AS3-кода. Так как FlashDevelop завязан на Win API и библиотеку .NET, его портирование под Linux затруднено, поэтому в Linux приходится довольствоваться только Flex4 SDK. В любом случае, приведенный в статье код скомпилируется не только в "чистом" Flex4 SDK, но и в настроенном FlashDevelop.
В этой статье я приведу код небольшого приложения, которое компилируется с помощью компилятора mxmlc в SWF файл. Называться программа будет "Просмотрщик картинок". Окно программы будет содержать следующие элементы:
В коде будет показано, как реализуются следующие вещи:
Как импортировать картинки вовнутрь SWF
Как сделать простую кнопку
Как сделать функцию-обработчик клика по кнопке
Как сделать кнопку, при клике на которую следует переход на заданный URL
Как показать и двигать картинку на экране
Как сделать основной цикл программы (main loop)
Как сделать прелоадер (preloader)
Полученных знаний будет достаточно, чтобы написать небольшую Flash-игру на чистом Action Script v.3.0. Итак, начнём.
* * *
Приложение будет состоять из трех файлов:
Main.as - основной файл программы
PushButton.as - класс, реализующий кнопку
Preloader.as - класс, реализующий прелоадер
Назначение файлов Main.as и Preloader.as, в принципе, понятно. А зачем нужен PushButton.as? Неужели во Flash нет готовой реализации обычной кнопки? Да, нет. На дворе 2010 год, а во Flash добавить обычную кнопку одной командой невозможно. Точнее, классическая кнопка есть, но находится она в библиотеке Flex. А использовать одновременно объекты Flex и более привычные объекты Flash нельзя. Мы будем реализовывать программу с помощью объектов Flash (ибо Flex - это отдельная большая песня), так что кнопку нам придется сделать самостоятельно.
// Интегрирование прелоадера, лежащего в Preloader.as [Frame(factoryClass="Preloader")]
// Основной класс программы public class Main extends Sprite {
// Картинки кадров (будут храниться в массиве как DisplayObject) public var kadr:Array=new Array();
// Параметры картинок-кадров public var kadr_num:int=3; // Количество картинок-кадров public var kadr_current_num:int=1; public var kadr_move_step:int=10; public var kadr_size_x:int=464; public var kadr_size_y:int=380;
// Текущее состояние программы public var state:String="wait_action";
// Конструктор основного класса public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); }
// Точка входа, после того как загрузился весь ролик public function init(e:Event = null):void { var i:int;
// Библиотека картинок [Embed(source="logo.png")] var symbol_logo:Class; [Embed(source="kadr_1.png")] var symbol_kadr_1:Class; [Embed(source="kadr_2.png")] var symbol_kadr_2:Class; [Embed(source="kadr_3.png")] var symbol_kadr_3:Class;
// Загрузка (создание инстанта) картинки логотипа из библиотеки var logo:DisplayObject=new symbol_logo();
// Загрузка (создание инстанта) картинок с кадрами из библиотеки kadr[1]=new symbol_kadr_1(); kadr[2]=new symbol_kadr_2(); kadr[3]=new symbol_kadr_3();
// Для загрузки (создание инстанта) можно попробовать другой код: /* for(i=1; i<=kadr_num; i++) { var img:Class=getDefinitionByName("symbol_kadr_" + i.toString()) as Class; kadr[i]=new img(); } */
// Логотип добавляется в список отображения Sprite, // от которого наследован класс Main // Другими словами, логотип просто добавляется на холст addChild(logo); logo.x=kadr_size_x+27; // Задаются координаты logo.y=25;
// Картинки кадров добавляются на холст с координатами 0:0 // и делаются невидимыми for(i=1; i<=kadr_num; i++) { addChild(kadr[i]); kadr[i].visible=false; }
// Первая картинка-кадр делается видимой kadr[kadr_current_num].visible=true;
// Надпись на логотипе добавляется на холст var display_txt:TextField = new TextField(); display_txt.text = "ImageView"; display_txt.selectable=false; display_txt.x=kadr_size_x+15; display_txt.y=5; addChild(display_txt);
// Добавляем кнопку "Назад", указываем ее обработчик var back_button:PushButton=new PushButton(kadr_size_x+30,150,24,24,"ᐃ"); back_button.addEventListener(MouseEvent.CLICK, back_click); addChild(back_button);
// Добавляем кнопку "Вперед", указываем ее обработчик var forward_button:PushButton=new PushButton(kadr_size_x+30,180,24,24,"ᐁ"); forward_button.addEventListener(MouseEvent.CLICK, forward_click); addChild(forward_button);
// Добавляем кнопку "Site", указываем ее обработчик var go_button:PushButton=new PushButton(kadr_size_x+23,kadr_size_y-18,42,16,"Site"); go_button.addEventListener(MouseEvent.CLICK, go_click); addChild(go_button);
// Запускаем основной цикл (main loop) addEventListener(Event.ENTER_FRAME, main_loop); }
// Основной цикл public function main_loop(event:Event):void { if(state=="wait_action") return;
// Если происходит движение вперед (кадры движгаются вверх) if(state=="roll_forward") { // Y-координата кадров уменьшается на нужный шаг kadr[kadr_current_num].y-=kadr_move_step; kadr[kadr_current_num+1].y-=kadr_move_step;
// Когда кадр полностью перемотан if(kadr[kadr_current_num].y<=(-kadr_size_y)) { // Уехавший кадр скрывается kadr[kadr_current_num].y=0; kadr[kadr_current_num].visible=false;
// Если происходит движение назад (кадры двигаются вниз) if(state=="roll_back") { // Y-координата кадров увеличивается на нужный шаг kadr[kadr_current_num].y+=kadr_move_step; kadr[kadr_current_num-1].y+=kadr_move_step;
// Когда кадр полностью перемотан if(kadr[kadr_current_num].y>=kadr_size_y) { // Уехавший кадр скрывается kadr[kadr_current_num].y=0; kadr[kadr_current_num].visible=false;
// Обработка кнопки перехода по указанному URL private function go_click(event:MouseEvent):void { var url:String="https://webhamster.ru"; var url_request:URLRequest=new URLRequest(url); navigateToURL(url_request, "_self"); }
// Геометрия SWF файла private var swf_w:int=550; private var swf_h:int=380;
// Инициализация загрузчика public function Preloader() { if (stage) { stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; } addEventListener(Event.ENTER_FRAME, checkFrame); loaderInfo.addEventListener(ProgressEvent.PROGRESS, progress); loaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioError);
// Текст о состоянии загрузки выводится на экран preloader_text=new TextField(); preloader_text.text="Load 0 % "; preloader_text.textColor=0xA0A0A0; preloader_text.selectable=false; preloader_text.autoSize=TextFieldAutoSize.CENTER; preloader_text.x=swf_w/2-preloader_text.width/2; preloader_text.y=swf_h/2; addChild(preloader_text); }
private function ioError(e:IOErrorEvent):void { trace(e.text); }
// Метод, вызываемый при изменении количества загруженных байт private function progress(e:ProgressEvent):void { // Обновляется текст загрузчика preloader_text.text="Load "+(Math.round((loaderInfo.bytesLoaded*100)/loaderInfo.bytesTotal))+" %"; }
private function checkFrame(e:Event):void { if (currentFrame == totalFrames) { stop(); loadingFinished(); } }
// Текст загрузчика скрывается preloader_text.visible=false;
startup(); }
private function startup():void { var mainClass:Class = getDefinitionByName("Main") as Class; if (parent == stage) stage.addChildAt(new mainClass() as DisplayObject, 0); else addChildAt(new mainClass() as DisplayObject, 0); } } }
public class PushButton extends SimpleButton { private var button_x:Number=0; private var button_y:Number=0; private var button_width:Number=0; private var button_height:Number=0; private var button_text:String="";
public function PushButton(buttonX:Number, buttonY:Number, buttonWidth:Number, buttonHeight:Number, buttonText:String) { button_x=buttonX; button_y=buttonY; button_width=buttonWidth; button_height=buttonHeight; button_text=buttonText;
Пара пояснений. Весь ролик существует в одном кадре. Основной цикл (main loop) организован с помощью обработки события перехода на начало кадра. Так как ролик состоит из одного кадра, то main loop вызывается с частотой смены SWF-кадров, обычно это 12 раз в секунду.
Основной класс программы (класс Main) унаследован от объекта Sprite. Поэтому основной объект можно рассматривать как холст, на котором происходят всякие преобразования. На него можно ложить элементы с помощью метода addChild(). Эти элементы можно скрывать и показывать, можно перемещать, меняя их координаты.
Запустить компиляцию можно с помощью следующей команды:
mxmlc -debug Main.as
Опция -debug нужна, чтобы нормально работала функция trace(). Путь к компилятору mxmlc нужно добавить в переменную PATH, либо указывать полный путь к бинарнику компилятора. В данный момент, в Flex4 SDK компилятор располагается в подкаталоге /bin каталога, куда был установлен Flex4 SDK.