Actionscript 3 Как загрузить PNG на сцену на основе значения веб-службы?

#flash #actionscript-3 #switch-statement

#flash #actionscript-3 #оператор переключения

Вопрос:

Доброе утро,

Я запрашиваю weather.com Веб-служба XML для получения текущей температуры выглядит как значок температуры и текущего состояния. У меня есть первые два значения, которые будут разделять текстовые поля на сцене, и это отлично работает. Однако сейчас я пытаюсь реализовать оператор switch таким образом, чтобы значение текущего значка состояния в XML считывалось моим скриптом, а соответствующий PNG становился исходным значением UILoader.

Прежде всего, является ли UILoader лучшим компонентом для использования при отображении PNG на сцене?

Вот мой код на данный момент:

 var src: UILoader.source=uicondicon.source;
switch(src){
case "0 PNG":                   
src=trace(resultXML.cc.icon)=0;
break;
case "11 PNG":
src=trace(resultXML.cc.icon)=11;
break;
default src=trace(resultXML.cc.icon)=0:
}
  

Когда я компилирую приведенный выше код, я получаю ошибку 1084, ожидающую, что в последней строке кода перед src будет двоеточие (мое назначение по умолчанию).

Учитывая, что может потребоваться отобразить 47 различных значков, является ли это лучшим способом реализации этой функциональности?

Наконец, как мне заставить компонент UILoader отображаться только во время определенного набора кадров в приложении?

Большое спасибо!!

Ответ №1:

1) Ошибка, которую вы получаете, вероятно, связана с тем, что последняя строка в вашем операторе switch заканчивается двоеточием вместо точки с запятой — «src по умолчанию = trace(resultXML.cc.icon) = 0:»

2) Я на самом деле никогда не использовал UILoader — обычно я просто использую Loader:

 var loader:Loader = new Loader;
var images:Array = [];
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);

loader.load(new URLRequest("image url here.jpg"));

protected function completeHandler(e:Event):void {
 // you can pull out the loader content and cast it as a bitmap...
 images.push(loader.content as Bitmap);

 // or you can simply add the loader to the stage
 addChild(loader);
 clearListeners();

}

protected function errorHandler(e:IOErrorEvent):void {
 trace("Error loading image! Here's the error:n"   e);
 clearListeners();
}

protected function progressHandler(e:ProgressEvent):void {
 trace("Load is "   (100 * e.bytesLoaded / e.byteTotal)   " percent complete...");
}

protected function clearListeners():void {
 loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, completeHandler);
 loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, errorHandler);
 loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
}
  

3) Если вы загружаете несколько изображений одновременно, вы должны знать, что порядок, в котором вызываются ваши загрузки, не имеет ничего общего с порядком их завершения. Таким образом, вы не можете предполагать, что, поскольку вы загружаете изображение A затем изображение B, это изображение A завершится первым. Итак, вам нужно выполнить некоторую логику для отслеживания ваших загрузчиков — например, у вас может быть настройка, подобная этой:

 var urls:Array = [this array has all of your urls in it];
var loaders:Array = [];
var images:Array = [];

protected function initLoaders():void {
 for (var i:int = 0; i < urls.length; i  ) {
  var loader:Loader = new Loader();
  loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
  // you'll want to add your other handlers here too for IOErrorEvent and Progress.
  loader.load(new URLRequest(urls[i]));
  loaders[i] = loader;
 }
}

protected function completeHandler(e:Event):void {
 var loaderIndex:int = loaders.indexOf(e.currentTarget); // this tells you which loader finished
 images[loaderIndex] = e.currentTarget.content as Bitmap; // I think this will work, you may have to play with Array syntax to make sure you're not adding tons of empty items and screwing up your order.

 if (images.length == urls.length) {
  trace("All images loaded!");
 }
}
  

4) Наконец, не используйте фреймы. Вы хотите написать свой код во внешнем классе. Если он должен быть привязан к заданному фрейму, используйте visible = true или visible = false в зависимости от текущего фрейма. Но все это может и должно обрабатываться в коде, поскольку это действительно бизнес-логика и не должно быть тесно связано с вашим представлением (то есть визуальным отображением, которое может быть привязано к фреймам).

Надеюсь, это поможет!

Комментарии:

1. Большое спасибо за ваш совет. Я хочу добавлять только по одному изображению за раз, основываясь на значении trace (resultXML.cc.icon). Итак, если trace (resultXML.cc.icon) = 11, то 11.png должен быть загружен на сцену, если trace (resultXML.cc.icon) = 12, то 12.png должен быть загружен на сцену и т.д….

2. Я бы использовал механизм, подобный тому, который я описал, чтобы загрузить все ваши изображения заранее и установить туда предварительный загрузчик. Затем, как только все ваши изображения будут загружены, остается просто добавить дочерний элемент (images[index]) для любого из них, который вы хотите отобразить. Кроме того, вы могли бы изучить что-то вроде «LoaderMax» от Greensock, который представляет собой пользовательский фреймворк, разработанный, чтобы помочь вам загружать множество элементов без проблем. Приветствия!