|
|
« Предыдущая тема | Следующая тема » |
Опции темы | Опции просмотра |
|
|
|||||
Регистрация: Apr 2010
Сообщений: 170
|
Непонятные вещи с загрузкой изображений и клипов
Всем доброго дня!
Имеется Game.swf, которая лежит в контакте. Она подгружает изображения и другие swf нашего сервера следующим образом: 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; } var displayObject:DisplayObject=Game.resourceManager.getData("wolf",ResourceGroup.GROUP_MONSTER); И после этого произвести его загрузку: При этом я подпишусь на событие и когда произойдёт загрузка либо ошибка, я узнаю об этом. Вот если загрузка произошла успешно, я смогу снова вызвать Game.resourceManager.getData(ID,GROUP) и получить экранный объект (то есть Loader.content). При этом на каждый Game.resourceManager.getData(ID,GROUP) у "изображения" увеличивается счётчик обращения. А когда нам уже не нужен данный ресурс, мы можем вызывать Game.resourceManager.release(ID,GROUP) и для текущего "изображения" будет уменьшен счётчик. А когда счётчик будет равен 0, то я выгружу данные: public function unload():void { if(isLoading) loader.close(); else if(isComplete) loader.unload(); isLoading=false; isComplete=false; } Теперь покажу как я делаю копии (в _displayObject передаём то, что нам выдал Game.resourceManager.getData(ID,GROUP)): 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); } } Если таким образом обрабатывать изображения, то иногда получается, что некоторые копии не создаются. Приведу пример. В самом начале запуска игры я получаю карту и определяю список всех объектов на ней и список для загрузки в менеджер ресурсов. То есть перед отрисовкой карты я уже определяю все объекты на ней и через менеджер ресурсов загружаю их изображения. И когда карта начинает выводится, она уже просто создаёт копию экранного объекта из менеджера ресурсов. Так работает всё нормально. Но вот представим что мы подошли к какому-то NPC поговорить и он нам даёт задание собрать 10 досок. Но к этому моменту на карте их не было и они теперь должны появиться. В менеджере ресурсов их нет. При создании первой доски, она даст менеджеру возможность загрузить туда изображение доски и затем уже все эти 10 досок должны будут сделать из него копию. А на деле получается так, что когда все 10 досок отображаются, а когда только первая. Причём такое происходит только если запускаешь из контакта (при локальном тестировании проблем нет). Теперь что касается клипов. Предположим что 10 этих досок выполнены не как изображение, а как swf. Сейчас речь идёт только про запуск из под контакта (в локалке все отлично). Игра рушится с таким вот сообщением: Цитата:
soObjType=SO_OBJ_CLIP; var mcSource:Class=Object(_displayObject).constructor as Class; soObjMC=new mcSource(); soObjMC.mouseEnabled=false; addChild(soObjMC); То никакой ошибки не возникает. Не странно ли?! Получается что клип загружен, я к нему смог обратиться и отключить мышку, а вот как добавляю на отображение, так ошибка. Кстати, после этого окна с ошибкой сразу появляется вот это: Цитата:
В общем вот такая ерунда происходит с загрузкой. Почему так происходит? |
|
|||||
Регистрация: Feb 2009
Сообщений: 180
|
Цитата:
Что касается данного поста и самой ошибки – очень много воды и мало конкретики, более того, текст ошибки указывает причину вполне ясно, а также функцию в которой эта ошибка возникла, но вы почему-то ее листинг не привели. Приведите листинг след. функций – at d.game.screen.screenGUI::GUIArrow(), at d.game.manager::ArrowManager/addObject(), at d.game.manager::ArrowManager/setArrows() и тогда возможно что-то станет понятно. |
|
|||||
Регистрация: Apr 2010
Сообщений: 170
|
Acrossfy
Цитата:
public function setArrows(_mapArrows:Vector.<MapArrow>):void { var i:uint=0; var len:uint=_mapArrows.length; var mapArrow:MapArrow=null; for(i=0;i<len;i++) { mapArrow=_mapArrows[i]; if(mapArrow.targetObject) addObject(mapArrow.targetObjectType,mapArrow.targetObject); else addCell(mapArrow.targetCell.x,mapArrow.targetCell.y); } } public class MapArrow extends MapObject { public var targetObjectType:uint=0; public var targetObject:String=null; public var targetCell:Vector2=null; public function MapArrow() { type=TYPE_ARROW_OBJECT; } public override function getIsPassability():Boolean { return true; } } Вот функция d.game.manager::ArrowManager/addObject(): public function addObject(_type:uint,_id:String):void { var arrow:GUIArrow=new GUIArrow(ScreenGUI.SO_NAME_GUI_ARROW,Game.screen.soGUI,_type,_id); arrow.x=Game.gameWidth/2; arrow.y=Game.gameHeight/2; arrow.soEnable(); arrow.soShow(); arrows.push(arrow); } public function GUIArrow(_name:String,_parent:ScreenObject,_type:uint,_target:String,_column:uint=0,_row:uint=0) { super(_name,_parent,false,false,null); swType=SW_TYPE_ARROW; mouseEnabled=false; arrow.mouseEnabled=false; var i:uint=0; var j:uint=0; var lenI:uint=0; var lenJ:uint=Game.screen.soMap.dynamics.length; var object:ScreenDraw=null; var mapDynamic:MapDynamic=null; var mapDynamicJ:MapDynamic=null; var mapMonster:MapMonster=null; var mapNPC:MapNPC=null; var screenDynamic:ScreenDynamic=null; if(arrow.numChildren==1 && arrow.getChildAt(0) is Bitmap) { (arrow.getChildAt(0) as Bitmap).smoothing=true; } targetObjectType=_type; targetObject=_target; if(!targetObject) targetCell=new Vector2(_column,_row); soSetContainer(Game.screen.soGUI.layerArrows); Game.screen.soGUI.guis.push(this); if(targetObject) { objects=new Vector.<ScreenDraw>(); if(targetObjectType==MapObject.TYPE_DYNAMIC_OBJECT) { lenI=Game.screen.soMap.dynamics.length; for(i=0;i<lenI;i++) { object=Game.screen.soMap.dynamics[i]; mapDynamic=object.sdGetDesc() as MapDynamic; if(mapDynamic.desc.id==targetObject) { object.sdCreateQuestEffect(); objects.push(object); } } } else if(targetObjectType==MapObject.TYPE_MONSTER_OBJECT) { lenI=Game.screen.soMap.monsters.length; for(i=0;i<lenI;i++) { object=Game.screen.soMap.monsters[i]; mapMonster=object.sdGetDesc() as MapMonster; if(mapMonster.desc.id==targetObject) objects.push(object); } } else { lenI=Game.screen.soMap.npcs.length; for(i=0;i<lenI;i++) { object=Game.screen.soMap.npcs[i]; mapNPC=object.sdGetDesc() as MapNPC; if(mapNPC.desc.id==targetObject) objects.push(object); } } } soResize(Game.gameWidth,Game.gameHeight); } Потому что если её вызов закомментировать, то никакой ошибки нет. А вот что в ней происходит: public function sdCreateQuestEffect():void { if(sdQuestTargetEffect) return; var effectDesc:EffectDesc=Game.description.getEffectOnID("QuestTarget"); if(!effectDesc) return; sdQuestTargetEffect=new ScreenQuestEffect( ScreenMap.SO_NAME_MAP_QUEST_TARGET_EFFECT, Game.screen.soMap, this, effectDesc.id, effectDesc.url); var displayObject:DisplayObject=Game.resourceManager.getData(effectDesc.id,ResourceGroup.GROUP_EFFECTS); if(displayObject) sdQuestTargetEffect.setImage(displayObject); else sdQuestTargetEffect.loadingImage(); var vector:Vector2=Iso.toScreen(sdDesc.column,sdDesc.row); sdQuestTargetEffect.x=vector.x+Game.description.fieldWidth/2-sdQuestTargetEffect.width/2-7; sdQuestTargetEffect.y=vector.y+Game.description.fieldHeight/2+10; sdQuestTargetEffect.soEnable(); sdQuestTargetEffect.soShow(); } sdQuestTargetEffect.setImage(displayObject); ... public function setImage(_displayObject:DisplayObject):void { soUpdateDisplay(_displayObject,0,0); } sdQuestTargetEffect.loadingImage(); ... public function loadingImage():Boolean { Game.resourceManager.addEventListener(GameEvent.RESOURCE_LOAD,onResourceLoadGameEvent); Game.resourceManager.addInGroup(sqeID,sqeURL,ResourceLoad.PARAM_MAIN,ResourceGroup.GROUP_EFFECTS); if(!Game.resourceManager.loadOnIDInGroup(sqeID,ResourceGroup.GROUP_EFFECTS)) { Game.resourceManager.removeEventListener(GameEvent.RESOURCE_LOAD,onResourceLoadGameEvent); return false; } return true; } private function onResourceLoadGameEvent(_event:ResourceLoadGameEvent):void { Game.resourceManager.removeEventListener(GameEvent.RESOURCE_LOAD,onResourceLoadGameEvent); if(_event.status!=EventStatus.STATUS_SUCCESS) return; var displayObject:DisplayObject=Game.resourceManager.getData(sqeID,ResourceGroup.GROUP_EFFECTS); var vector:Vector2=Geom.determinationSize(displayObject.width,displayObject.height,sqeParent.width,sqeParent.height); soUpdateDisplay(displayObject,0,0); } Всё равно попадём в эту функцию: public final function soUpdateDisplay(_displayObject:DisplayObject,_width:uint=0,_height:uint=0):void { var i:uint=0; var len:uint=0; var array:Array=null; var frameLabel:FrameLabel=null; if(soObjBitmap) { removeChild(soObjBitmap); soObjBitmap=null; } if(soObjMC) { removeEventListener(Event.ENTER_FRAME,onEnterFrame); removeChild(soObjMC); soObjMC=null; } soObjType=SO_OBJ_NULL; 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); } } } |
|
|||||
блогер
Регистрация: Oct 2005
Адрес: Днепродзержинск - город Брежнева и других логопедов
Сообщений: 1,421
Записей в блоге: 4
|
Ошибка
>RangeError: Error #1125: Индекс 15 выходит за границы диапазона 0. Не может вылетать на строчке Она вылетает там, где есть доступ по индексу.
__________________
Бобры отвечают на вопросы не потому, что знают на них ответы; они отвечают потому, что их спрашивают. |
|
|||||
Регистрация: Apr 2010
Сообщений: 170
|
-De-
Цитата:
|
|
|||||
блогер
Регистрация: Oct 2005
Адрес: Днепродзержинск - город Брежнева и других логопедов
Сообщений: 1,421
Записей в блоге: 4
|
Скорее всего потому что вы так написали. Нет никаких проблем написать код так, чтоб оно не вылетало при закоментированном addChild(), но вылетало если он написан.
Смотрите, у вас есть там 3 строки, где возможен вылет по неправильному индексу: Судя по тому, что вы упоминаете object.sdCreateQuestEffect(); то в первой. Но возможно и нет - забросайте всё трейсами и найдите точно, где и кто. Или дебаггер подцепите. Ну как всегда в общем. Похоже, кто-то у вас пересоздает Game.screen.soMap.dynamics. Т.к. он доступен глобально, то это может быть кто угодно. Возможно, что это конструктор ScreenQuestEffect, куда передается Game.screen.soMap.
__________________
Бобры отвечают на вопросы не потому, что знают на них ответы; они отвечают потому, что их спрашивают. Последний раз редактировалось -De-; 07.05.2012 в 21:01. |
|
|||||
Регистрация: Apr 2010
Сообщений: 170
|
-De-
Цитата:
|
|
|||||
блогер
Регистрация: Oct 2005
Адрес: Днепродзержинск - город Брежнева и других логопедов
Сообщений: 1,421
Записей в блоге: 4
|
Вполне возможно, что виноваты всё-таки вы, а не адобы, контакт или несовершенство мира. Чтобы трейсить вконтакте можете воспользоваться логгером от инфокоры вон =)
__________________
Бобры отвечают на вопросы не потому, что знают на них ответы; они отвечают потому, что их спрашивают. |
|
|||||
Регистрация: Apr 2010
Сообщений: 170
|
-De-
Можете подсказать на что мне сейчас в первую очередь обратить внимание, что проверить? А я проверю и отпишусь. |
|
|||||
блогер
Регистрация: Oct 2005
Адрес: Днепродзержинск - город Брежнева и других логопедов
Сообщений: 1,421
Записей в блоге: 4
|
Понять, что же ошибка означает. Она значит "попытка получить доступ по индексу 15 в векторе, длина которого 0". В функции GUIArrow.
Вот пишете перед строчками, где есть там доступ по индексу И перед концом цикла тоже можно сразу влепить. Ставите плагин, чтоб трейсы видеть или логгером инфокоровским воспользуйтесь (тогда не трейс, а что там у него в логгере). Тогда между строчками, где length был не 0, а стал 0 - случилась фигня. Делаете то же самое в функциях между теми строчками. Так пока не найдете, где же он обнулился. Может можно подцепиться в дебаггере к флешке в контакте, но я не подскажу как %)
__________________
Бобры отвечают на вопросы не потому, что знают на них ответы; они отвечают потому, что их спрашивают. |
Часовой пояс GMT +4, время: 19:27. |
|
« Предыдущая тема | Следующая тема » |
|
|