Всем доброго дня!
Имеется Game.swf, которая лежит в контакте. Она подгружает изображения и другие swf нашего сервера следующим образом:

Код AS3:
public function load():Boolean
{
if(isLoading || isComplete) return false;
isLoading=true;
isComplete=false;
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onComplete);
loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR,onSecurityError);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,onIOError);
try
{
if(url.search(".swf")!=-1 && Game.socialAPI.isLocal)
{
loaderContext.checkPolicyFile=false;
loaderContext.applicationDomain=ApplicationDomain.currentDomain;
loaderContext.securityDomain=null;
}
else if(url.search(".swf")!=-1 && !Game.socialAPI.isLocal)
{
loaderContext.checkPolicyFile=false;
loaderContext.applicationDomain=ApplicationDomain.currentDomain;
loaderContext.securityDomain=null;
}
else
{
loaderContext.checkPolicyFile=true;
loaderContext.applicationDomain=null;
loaderContext.securityDomain=null;
}
loader.load(urlRequest,loaderContext);
}
catch(_error:Error)
{
onCallError();
}
return true;
}
В переменной isLocal в Game.socialAPI лежит значение false, если игра была запущена из социальной сети, либо true - если игра была запущена локально. Вот собственно как я это всё гружу. Я написал менеджер загрузок. Вся его соль в том, что он позволяет распределять Loader'ы по группам и давать для каждого идентификатор. Таким образом, если мне нужно получить экранный объект волка, я укажу:

Код AS3:
var displayObject:DisplayObject=Game.resourceManager.getData("wolf",ResourceGroup.GROUP_MONSTER);
Если экранного объекта в этой группе и с таким идентификатором нету, то в ответ я получу null и смогу вручную добавить его для загрузки:

Код AS3:
Game.resourceManager.add("wolf",URL,ResourceGroup.GROUP_MONSTER);
И после этого произвести его загрузку:

Код AS3:
Game.resourceManager.load("wolf",ResourceGroup.GROUP_MONSTER);
При этом я подпишусь на событие и когда произойдёт загрузка либо ошибка, я узнаю об этом. Вот если загрузка произошла успешно, я смогу снова вызвать Game.resourceManager.getData(ID,GROUP) и получить экранный объект (то есть Loader.content). При этом на каждый Game.resourceManager.getData(ID,GROUP) у "изображения" увеличивается счётчик обращения. А когда нам уже не нужен данный ресурс, мы можем вызывать Game.resourceManager.release(ID,GROUP) и для текущего "изображения" будет уменьшен счётчик. А когда счётчик будет равен 0, то я выгружу данные:

Код AS3:
public function unload():void
{
if(isLoading)
loader.close();
else if(isComplete)
loader.unload();
isLoading=false;
isComplete=false;
}
Всё это нужно для того, чтобы мгновенно отображать те объекты, которые уже были загружены. Вот представим что на карте есть дерево, камень и дом. И вот мы что-то сделали что нам пришло событие вывести на карту ещё одно дерево. Так как у нас уже в менеджере ресурсов есть это изображение, то мы быстро его выведем. А если бы его не было, то нам пришлось бы его грузить. С другой стороны нам придётся его грузить снова, если все деревья к тому моменту были удалены с карты (но это довольно таки вполне нормальный вариант).
Теперь покажу как я делаю копии (в _displayObject передаём то, что нам выдал Game.resourceManager.getData(ID,GROUP)):

Код AS3:
if(_displayObject)
{
if(_displayObject is Bitmap)
{
soObjType=SO_OBJ_BITMAP;
soObjBitmap=new Bitmap((_displayObject as Bitmap).bitmapData);
soObjBitmap.smoothing=true;
if(_width!=0) soObjBitmap.width=_width;
if(_height!=0) soObjBitmap.height=_height;
addChild(soObjBitmap);
}
else if(_displayObject is MovieClip)
{
soObjType=SO_OBJ_CLIP;
var mcSource:Class=Object(_displayObject).constructor as Class;
soObjMC=new mcSource();
soObjMC.mouseEnabled=false;
addChild(soObjMC);
soLastFrame=soObjMC.currentFrame;
if(_width!=0) soObjMC.width=_width;
if(_height!=0) soObjMC.height=_height;
soObjLabels=new Vector.<String>();
array=soObjMC.currentLabels;
len=array.length;
for(i=0;i<len;i++)
{
frameLabel=array[i];
soObjLabels.push(frameLabel.name);
}
addEventListener(Event.ENTER_FRAME,onEnterFrame);
}
}
Вот в общем и получается что после такой обработке у меня будет либо в soObjBitmap, либо в soObjMC экранный объект. А теперь о проблемах...
Если таким образом обрабатывать изображения, то иногда получается, что некоторые копии не создаются. Приведу пример. В самом начале запуска игры я получаю карту и определяю список всех объектов на ней и список для загрузки в менеджер ресурсов. То есть перед отрисовкой карты я уже определяю все объекты на ней и через менеджер ресурсов загружаю их изображения. И когда карта начинает выводится, она уже просто создаёт копию экранного объекта из менеджера ресурсов. Так работает всё нормально. Но вот представим что мы подошли к какому-то NPC поговорить и он нам даёт задание собрать 10 досок. Но к этому моменту на карте их не было и они теперь должны появиться. В менеджере ресурсов их нет. При создании первой доски, она даст менеджеру возможность загрузить туда изображение доски и затем уже все эти 10 досок должны будут сделать из него копию. А на деле получается так, что когда все 10 досок отображаются, а когда только первая. Причём такое происходит только если запускаешь из контакта (при локальном тестировании проблем нет).
Теперь что касается клипов. Предположим что 10 этих досок выполнены не как изображение, а как swf. Сейчас речь идёт только про запуск из под контакта (в локалке все отлично). Игра рушится с таким вот сообщением:
Цитата:
RangeError: Error #1125: Индекс 15 выходит за границы диапазона 0.
at d.game.screen.screenGUI::GUIArrow()
at d.game.manager::ArrowManager/addObject()
at d.game.manager::ArrowManager/setArrows()
at d.game.screen::UpdateMap$/analysis()
at d.game.screen::ScreenMap/onGetMapInfoNetworkEvent()
at d.game.network.gameAPI::ParsingGetMapInfo$/success()
at d.game.network::GameAPI/onComplete()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.net::URLLoader/onComplete()
|
Но когда я в коде:

Код AS3:
soObjType=SO_OBJ_CLIP;
var mcSource:Class=Object(_displayObject).constructor as Class;
soObjMC=new mcSource();
soObjMC.mouseEnabled=false;
addChild(soObjMC);
Закомментирую строчку:

Код AS3:
// addChild(soObjMC);
То никакой ошибки не возникает. Не странно ли?! Получается что клип загружен, я к нему смог обратиться и отключить мышку, а вот как добавляю на отображение, так ошибка. Кстати, после этого окна с ошибкой сразу появляется вот это:
Цитата:
|
Error #2044: Необработанный AsyncErrorEvent:. text=Error #2095: flash.net.LocalConnection не удалось осуществить обратный вызов apiCallback. error=TypeError: Error #1006: value не является функцией.
|
Собственно тут я даже не понимаю что это и откуда.
В общем вот такая ерунда происходит с загрузкой. Почему так происходит?