в main.swf у тебя есть два кадра. Также на первую swf-ку пихаем все, что всегда есть на остальных страницах и прелоадер. На первом торчит подгрузка всего клипа и создание экземпляров pageManager и dataManger:
Код |
System.useCodepage = true; this.pm = new com.batsuev.managers.pageManager(this['content']); this.dm = new com.batsuev.managers.dataManager(); var preloader_instance:Object = this['preloader']; this.pm.preloader_instance = preloader_instance; this.dm.preloader_instance = preloader_instance; var load_list:Object = new Object(); var ths:Object = this; load_list.onLoad = function() { ths.gotoAndPlay(2); ths.pm.changePages(['./pages/mostokiada.swf']); } preloader_instance.addListener(load_list); preloader_instance.setObject(this); stop();
|
итак, попорядку:
System.useCodepage = true;
включаем использование кодовых страниц, дабы небыло проблем с подгрузкой файлов с различными кодировками (которые не UTF-8)
this.pm = new com.batsuev.managers.pageManager(this['content']);
создаем экземпляр класса pageManager, который занимается тем, что подгружает содержимое внешнего файла в клип this['content']. Почему this.pm = , а не var pm: ?
Просто если мы пропишем через var, то не сможем получить доступ к этой переменной из других клипов, а если пишем this.pm, то мы просто "пришиваем" переменную pm к мувику. В данном случае this и _root - одно и то-же.
this.dm = new com.batsuev.managers.dataManager();
то-же, что и pageManager, но для работы с данными.
var preloader_instance:Object = this['preloader'];
создаем ссылку на объект preloader. Это клип, у него выставлен as2 class com.batsuev.UI.preloader.
this.pm.preloader_instance = preloader_instance;
this.dm.preloader_instance = preloader_instance;
здесь мы указываем нашим мэнеджерам, ссылку на прелоадер.
var load_list:Object = new Object();
var ths:Object = this;
load_list.onLoad = function()
{
ths.gotoAndPlay(2);
ths.pm.changePages(['./pages/mostokiada.swf']);
}
preloader_instance.addListener(load_list);
добавляем листенер события, срабатывающего при загрузке основной swf-ки.
var ths:Object = this; - создаём ссылку на _root, дабы использовать её в событии onLoad.
После загрузки мы пререходим на 2 кадр и из-меняем содержимое клипа this['content'] на ./pages/mostokiada.swf.
preloader_instance.setObject(this);
эта функция пускает отображение загрузки основной страницы.
Итак, теперь посмотрим, что за страшные класс pageManager:
Код |
/** * @author Alex Batsuev */
import com.batsuev.UI.preloader
class com.batsuev.managers.pageManager { private var container_mc:MovieClip; //переменная, содержащая ссылку на клип, в который будут подгружаться все swf private var _pages:Array; //массив подгружаемых клипов public var preloader_instance:preloader;//ссылка на preloader //----------------------------------------------------------- //-- метод, вызывающийся при получении значения pages. //-- возвращает массив urk-ов страниц, находящихся в container_mc public function get pages():Array { return this._pages; } //----------------------------------------------------------- //-- конструктор для класса. Срабатывает при создании экземпляра класса //-- на входе ему передаётся ссылка на клип-контейнер для подгрудаемых swf-ок. public function pageManager(container_mc:MovieClip) { this.container_mc = container_mc; //установка переменной класса container_mc значения передаваемой переменной //this указывает на то, что это переменная, относящаяся к классу } //----------------------------------------------------------- //-- метод, изменяющий стрраницы. То бишь удаляет всё, что есть в container_mc и подгружает новые данные. public function changePages(new_pages:Array):Void { this.preloader_instance.show(); //показываем прелоадер. this._pages = new_pages; //устанавливаем значения текущих страниц this.removePages(); //вызываем private - метод для удаления всего, что есть в container_mc this.showPages(); //подгружаем новые страницы. } //------------------------------------------------------------ //-- метод для удаления содержимого container_mc private function removePages():Void { var j:String; for (j in this.container_mc) { //конструкция типа for (j in smth) перебирает всё, что находится в smth. //метод typeOf возвращает тип переменной, если это - movieclip, то удаляем: if (typeof(this.container_mc[j])=='movieclip') { this.container_mc[j].removeMovieClip(); } } } //-------------------------------------------------------------- //-- метод для подгрузки новых страниц private function showPages():Void { var i:Number; var mcls:Array = new Array(); //массив для объектов MovieClipLoader var mcs:Array = new Array(); //массив для сслок на клипы var list:Object = new Object();//объет, в котором идёт обработка события onLoad var ths:Object = this; //ссылка на экземпляр класса list.onLoad = function():Void { //этот метод срабатывает тогда, когда подгрузятся все новые клипы ths.preloader_instance.hide(); //скрываем preloader var i:Number;//пускаем все клипы. for (i=0;i<mcs.length;i++) { mcs[i].play(); } } //создадим новые клипы и выставим ссылки на них в массиве mcs. Создадим объекты класса MovieClipLoader. for (i=0;i<this._pages.length;i++) { mcs[i] = this.container_mc.createEmptyMovieClip('movie_'+i.toString(),this.container_mc.getNextHighestDepth()); mcls[i] = new MovieClipLoader(); } this.preloader_instance.addListener(list); //добавляем листенер для события onLoad. this.preloader_instance.setMCLArray(mcls); //вызываем метод, отображающий прогресс загрузки нескольких клипов. //загружаем клипы. for (i=0;i<this._pages.length;i++) { mcls[i].loadClip(this._pages[i],mcs[i]); } } }
|
конечно, всё это было-бы грамотнее прописать через static, но тогда возникает проблема размера. Просто данный класс используется во всех swf. И при явном указании в них на его использование, он будет в них подгружен. Соответственно идёт увеличение размера в несколько раз. Как вариант, можно использовать eval, но всё-таки простейший способ - это прописать его не как static.
Теперь следующий класс - preloader:
Код |
/** * @author Alex Batsuev */
class com.batsuev.UI.preloader extends MovieClip { private var load_check_interval:Number; private var obj_target:Object; private var total_bytes:Number; private var list_obj:Object; //-- конструктор класса public function preloader() { //пустой. Ничего нам при создании экземпляра класса не надо. } //-- метод, показывающий preloader public function show():Void { this._visible = true; //так как класс у нас наследует все методы и свойства MovieClip, то просто установи _visible в true this.setCurrentValue(0); //устанавливаем значение текощего состояния в 0. } //-- скрываем прелоадер public function hide():Void { this._visible = false; //так как класс у нас наследует все методы и свойства MovieClip, то просто установи _visible в false //удаляем всё, что надо: delete this.list_obj; //list_obj - ссылка на объект, ханимающийся отловом события onLoad delete this.total_bytes; //total_bytes - общее число подгружаемых байтов delete this.obj_target; //ссылка на объект, который подгружаем delete this.load_check_interval; //интервал для проверки загрузки } //-- добавление объекта, который занимается отловом события onLoad: public function addListener(list:Object):Void { this.list_obj = list; } //-- установка объекта для загрузки: public function setObject(obj:Object):Void { this.obj_target = obj; //устанавливаем объект this.load_check_interval = setInterval(this.objLoadCheck,1,this); //вызываем метод objLoadCheck через 1/100 секунды (или 1/1000, не помню ) и передаем ему ссылку на экземпляр класса. Зачем? просто в методе, который вызывается в setInterval обращение this будет вести в undefined. } //-- установа массива объектов класса MovieClipLoader для загрузки: public function setMCLArray(mcls:Array):Void { var i:Number; var lists:Array = new Array(); //листенеры для событий класса MovieClipLoader var calls:Array = new Array(); //а вот это хер зает зачем написал. var ths:Object = this; //создаем ссылку на экземпляр клипа this.total_bytes = new Number(); //обнуляем значение общего количества байтов for (i=0;i<mcls.length;i++) { lists[i] = new Object(); lists[i]['totalSet'] = false; //установлено-ли общее количество байтов в i-ом клипе? lists[i]['loaded'] = false; //загружен-ли i-й клип lists[i].onLoadProgress = function(target_mc,loaded:Number,total:Number):Void { //это событие вызывается в процессе загрузки if ((!this['totalSet'])&&(total>0)) { //если не установлено общее количество ьайтов в клипе, и при этом количество байтов в клипе больше 0, то добавим к общему количеству байтов это количество и установим переменную this['totalSet'] в true. ths.total_bytes += Number(total); this['totalSet'] = true; } if (this['totalSet']) { this['loadedBytes'] = Number(loaded); //устанавливаем, сколько байтов мы уже загрузили } } lists[i].onLoadInit = function(target:Object):Void { //событие, срабатывающее при начале проигрывания подгружаемого клипа. По-хорошему надо это нахер снести и переписать всё на onLoadComplete или как его там... this['loaded'] = true; //устанавливаем, что клип загружен } mcls[i].addListener(lists[i]); //добавляем MovieClipLoader-у листенер на все вышеобозванные события } this.load_check_interval = setInterval(this.MCLLoadCheck,1,this,lists); //устанавливаем вызов метода MCLLoadCheck через 1/хрен-знает-какую секунды и переддаём ссылку на экхемпляр клипа. } //-- check object loading private function objLoadCheck(ths:Object):Void { //это метод, вызываемый при подгрузке единичного объекта и методу сему передаётся ссылка на экземпляр сего грёбаного класса. if (ths.obj_target.getBytesTotal()>60) { //если количество байтов общее больше 60, то вот тогда можно работать. А иначе этот грёбаный flash считает, что в подгружаемом объекте 0. И событие onLoad работает странно... так-что будем предохраняться проверкой количества тотального байтов. if (ths.obj_target.getBytesTotal()!=ths.obj_target.getBytesLoaded()) { //если всего в obj_target загруженных байтов не столько-же, сколько всего в нём байтов, то устанавливаем значение прогресса: ths.setCurrentValue(ths.obj_target.getBytesLoaded()/ths.obj_target.getBytesTotal()); }else { //а иначе убиваем наш грёбаный интервал, в котором идёт проверка, вызываем событие onLoad и устанавливаем текущее значение в 100% (1) clearInterval(ths.load_check_interval); ths.setCurrentValue(1); ths.list_obj.onLoad(); } } } //-- метод, который надзирает над загрузкой многжественного числа объектов.... о мля задвинул... вообщем этот метод мсотрит, сколько байтов из массива клипов загрузилося, а сколько осталося private function MCLLoadCheck(ths:Object,lists:Array):Void { var i:Number; var is_loaded:Boolean = true; //всё-ли загрцжено? пусть наш метод сначала помечтает и в нём хрянится значение, что всё var is_total_set:Boolean = true; //ну и ессно пусть он мечтает, что flash не ключит, и установлено общее количество байтов во всех клипах var loaded:Number = new Number(); //а вот в этой переменной пусть будет значение, сколько всего подгружено. Ну и пусть оно будет нулевым. //теперь обойдём-ка мы все листенеры объектов класса MovieClipLoader из массива for (i=0;i<lists.length;i++) { if (!lists[i]['loaded']) { //если хоть какая-то падла не загрузилася, обломаем наш метод и выставим, что нихера не загружено is_loaded = false; } if (!lists[i]['totalSet']) { //если хоть какая-то падла не выставила общего количества байтов в себе (шифруется наверное сволочь), обломаем наш метод и выставим, что нихера не знаем про общее количество байтов is_total_set = false; }else { //а иначе увеличим количество загруженных байтов loaded += lists[i]['loadedBytes']; } } if (is_total_set) { //если известно, что везде установлено общее количество байтов, то установим текущее значение прогресса: ths.setCurrentValue(loaded/ths.total_bytes); } if (is_loaded) { //а если свершилось чудо, и всё загрузилося, то на радостях снесём нах интервал, вызовем событие листенера onLoad и установим, что значение - 100%, то бишь 1. clearInterval(ths.load_check_interval); ths.setCurrentValue(1); ths.list_obj.onLoad(); } } //установка текущего значения прогресса... от 0 до 1. private function setCurrentValue(v:Number):Void { this['status_field'].text = String(Math.round(v*100))+'%'; } }
|
так... меня уже помаленьку прёт... не люблю я столько комментов писать

итак, пока можно забыть про третий класс, который с данными работает...
Вообщем теперь вроде всё должно быть понятно... или нет? Если нет, спрашивай...