Просмотр полной версии : Запись в массив?
Добрый день
Как сделать что бы , загружались картинки (через xml) и загружались в массив, так будто бы они находятся в буффере(Library) ??
Подробнее:
Так сделано,когда подгружает из библиотеке по Linkage:
var linksID:Array=["1","2","3","4","5","6","7"];
после парсинга xml, я получаю массив
image[i]
for(j=0;j<total;j++)
{
trace("j: "+j + " , " + "im: "+image[j]);
}
trace :
j: 0 , im: src/1.JPG
j: 1 , im: src/2.JPG
j: 2 , im: src/3.JPG
j: 3 , im: src/4.JPG
j: 4 , im: src/5.JPG
j: 5 , im: src/6.JPG
j: 6 , im: src/7.JPG
Соответвенно как мне сразу загрузить в буффер и работать как-будто я импортировал из в Библиотеку вручную ( получить массив ссылок на Linkage/Inditefier):wacko:
Я делал так - сразу после загрузки отрисовывал мувик с картинкой в BitmapData и добавлял новый полученный экземпляр BitmapData в массив. Исходный загрузочный мувик-контейнер тут же удалялся. При необходимости аттачил картинки из массива. Так реально можно хранить растровые данные в памяти и их использовать.
Спасибо за подсказку попробуем реализовать это)
Добавлено через 24 минуты
Вопрос как добавить ?
function bit()
{
var linkageId:String = "pic.jpg";
var myBitmapData:BitmapData = BitmapData.loadBitmap(linkageId);
trace(myBitmapData instanceof BitmapData); // true
var mc:MovieClip = this.createEmptyMovieClip("mc", this.getNextHighestDepth());
mc.attachBitmap(myBitmapData, this.getNextHighestDepth());
}
Такой код и не будет работать, т.к.
public static loadBitmap(id:String) : BitmapData
Возвращает новый экземпляр BitmapData, который содержит растровое изображение символа, определенного в библиотеке под указанным идентификатором (ID).
Xml , дает нам лишь массив путей. , как загрузить в экземпляр BitmapData?
Mooncar, скажите что вы записывали в массив? Часто сталкивался с подобным, но приходилось решать проблему кустарным способом...
Возможно я плохо знаю Класс BitmapData. Отсюда подобние вопроссы.
Вот кусок кода.
В проекте есть лента событий. Функция загружает картинку к определенному событию за определенный год. Данный кусок кода работает в этом проекте в составе общего прелоадера для всего ролика (проект большой). Привожу как есть.
var EVENTSBITMAP:Array = new Array(); //массив фото событий
......
var mcLoaderEventsFoto:MovieClipLoader = new MovieClipLoader();
var listenerEFoto:Object = new Object();
mcLoaderEventsFoto.addListener(listenerEFoto);
function loadEventsSlide (year, n) {
this.createEmptyMovieClip('eventFoto' + year + n, this.getNextHighestDepth());
this['eventFoto' + year + n]._alpha = 0; //чтобы в прелоадере на виду не мелькали загружаемые картинки
listenerEFoto.onLoadInit = function (target_mc:MovieClip) {
var myImg:BitmapData = new BitmapData(target_mc._width, target_mc._height, false);
myImg.draw(target_mc);
target_mc.unloadMovie();
EVENTSBITMAP[target_mc._name] = myImg;
if (year >= yearsTotal) {
loadEventsStatus = 1; //состояние этого триггера проверяется механизмом общего лоадера
}
};
listenerEFoto.onLoadError = function (target_mc:MovieClip) {//если нет фото к событию
if (year >= yearsTotal) {
loadEventsStatus = 1; //конец
}
};
mcLoaderEventsFoto.loadClip(EventsPath + 'foto/' + year + '.' + n + '.jpg' + suffix, this['eventFoto' + year + n]);
};
Тут у меня:
n - это номер события у конкретного года.
EventsPath - путь на сервере к директории с данными шкалы событий
suffix - зависит от способа загрузки - важен для отладки - в начале определяется: если загрузка с web-сервера, то suffix - рандомная приставка для предотвращения кэширования, если локально - то suffix = пусто.
Функция вызывается из другой по определенному алгоритму загрузки общих данных шкалы событий.
В нужный момент, когда юзер проходит по ленте событий года, из массива картинки приаттачиваются в мувик-контейнер:
...
mc.createEmptyMovieClip('image', 0);
mc.image.attachBitmap(_root.EVENTSBITMAP['eventFoto' + year + n], 0);
mc - это объектная ссылка для некого контейнера для иллюстрации...
А за тем как массив набит:
clip.attachBitmap(EVENTSBITMAP[номер], this.getNextHighestDepth());
?
Совершенно верно, в нужный момент в нужной функции аттачим картинку а контейнер.
Только у меня были не номерные элементы массива, а именованные.
Такой алгоритм в том же проекте работает еще в паре мест для загрузки других наборов изображений.
Ресурсоемко, конечно в битмапу загонять, но заказчик очень хотел - сперва чтобы загрузилось все-все-все, потом работала презентация.
Если проект не очень большой, то так можно. Тем более у меня это не для инета было, а для инфомата в вестибюле.
Возьму этот метод на заметку. Спасибо!
Как там пишут - Enjoy it! :)
Не совсем я понял как это работает, если можно подсобить..
добавил своих комментов,где ошибся?
import flash.display.BitmapData;
var EVENTSBITMAP:Array = new Array(); //массив фото событий
//......
var mcLoaderEventsFoto:MovieClipLoader = new MovieClipLoader();
var listenerEFoto:Object = new Object();
mcLoaderEventsFoto.addListener(listenerEFoto);
loadEventsSlide(1999,5);
function loadEventsSlide (year, n) {
//создание пустого мувиклипа
this.createEmptyMovieClip('eventFoto' + year + n, this.getNextHighestDepth());
this['eventFoto' + year + n]._alpha = 100; //чтобы в прелоадере не мелькали загружаемые картинки
//когда объект загружен ,создаем функции с входным аргументом - муви,клип
listenerEFoto.onLoadInit = function (target_mc:MovieClip) {
//создаем объект типа BitmapData, под подгружаемый mc
var myImg:BitmapData = new BitmapData(target_mc._width, target_mc._height, false);
//отборжение эффекта
myImg.draw(target_mc);
//выгрузка мувиклипа из контейнера
//target_mc.unloadMovie();
//Массив муикльипа ,с имееными индексами заполнеяеться конкретной картикой
EVENTSBITMAP[target_mc._name] = myImg;
if (year >= yearsTotal) {
loadEventsStatus = 1; //состояние этого триггера проверяется механизмом общего лоадера
}
};
listenerEFoto.onLoadError = function (target_mc:MovieClip) {//если нет фото к событию
if (year >= yearsTotal) {
trace("ERROR, can't find file");
loadEventsStatus = 1; //конец
}
};
trace("ROUTE!::"+EventsPath + "foto/" + year + "." + n + ".jpg" + suffix );
mcLoaderEventsFoto.loadClip("fon.JPG", 1);
//p1.loadClip("fon.JPG",1);
};
p1.attachBitmap(EVENTSBITMAP[target_mc._name], this.getNextHighestDepth());
for(j=0;j<4;j++)
{
trace(" " + EVENTSBITMAP[j]);
}
откуда берется target_mc?
что делает listenerEFoto.onLoadInit?
и правильно ли я понял, что это массив EVENTSBITMAP
будет выглядеть так EVENTSBITMAP=["ссылка на fon.jpg , загруженный динамически в библиотеку"]
Если я не ошибаюсь то target_mc - это аргумент функции метода onLoadInit.
mooncar Пардон за глупый вопрос, а как это именованые элементы массива? Можете привести пример?
onLoadInit = function([target_mc]) {}
target_mc: [optional] - A movie clip loaded by a MovieClipLoader.loadClip() method.
Art_133,
Если я не ошибаюсь то target_mc - это аргумент функции метода onLoadInit. Верно. Внутри обработчика метода этот аргумент у меня и используется.
Когда загружаем картинку в контейнер через loadClip, он равен
this['eventFoto' + year + n]
И теперь у метода onLoadInit его анонимная функция знает, какой именно контейнер загружен картинкой. Внутри этой функции, как я уже сказал, он и используется для дальнейших действий с картиночным контейнером. Функция-обработчик события onLoadInit именно так и работает.
Насчет массива с именованными элементами - посмотрите материалы в любом справочнике или учебнике по флешу на тему "Ассоциативные массивы".
Кстати, любой мувик, или даже сам _root, если внутри него есть еще какие-то элементы - другие мувики, переменные, функции, свойства - это также ассоциативный массив, доступ элементам которого осуществляется по их именам. Например:
_root['movie_mc'];
this['movie' + 2 + 'mc'];
movie_mc['_alpha'] = 75;
btn.onRelease = this._parent['doIt'];
и т.д.
Это - основы.
sy555,
откуда берется target_mc?
target_mc - это аргумент, который, когда наступает onLoadInit, внутри функции его метода равен мувику-контейнеру, куда грузили.
что делает listenerEFoto.onLoadInit?
Дает возможность работать с мувиком-контейнером с загруженным контентом дальше - гарантирует, что загрузка завершилась. В силу асинхронности AS какие-либо действия с мувиком-контейнером с загруженной картинкой можно предпринимать дальше только внутри этого метода (точнее, его функции) - он дает гарантию завершения загрузки. Без него нельзя.
Кстати, а зачем вы альфу контейнера приравняли 100? Для отладки? Эти мувики ведь временные, они будут мельтешить при загрузке картинок. Они вообще не нужны в дальнейшем.
_____________________
Читайте о классе MovieClipLoader и его методах, смотрите примеры.
да хотел отладить, увидеть картинку.. в итоге закомментил unLoadMovie;
Так вроде понятно , еще один вопросик созрел по ходу отладки .
В теле onLoadInit :
EVENTSBITMAP[num] = myImg;
trace(" name : "+num+ " :" + EVENTSBITMAP[num] + " hey: " );
num++;
заменил на числовые.
output:
name : 0 :[object Object] hey:
name : 1 :[object Object] hey:
name : 2 :[object Object] hey:
Вроде верно.
Но когда выношу в другую функцию данные теряются.. хотя переменная описана глобально..
var linksID:Array=["1","2","3","4","5","6","7","p1","p2","p3"];
trace("linksId: " + linksID);
trace ("\n");
for(u=0;u<3;u++)
{
linksID[u]=EVENTSBITMAP[num];
}
output
linksId: 1,2,3,4,5,6,7,p1,p2,p3
totalundefined,undefined,undefined,4,5,6,7,p1,p2,p3
Какая переменная описана глобально? Куда что выносите?
Может ВЕСЬ код приведете, догадываться сложно, помощь вам затрудняется.
import flash.display.BitmapData;
import mx.controls.Button;
var EVENTSBITMAP:Array = new Array(); //массив фото событий , глобальная переменная
var num :Number= new Number();
var massiv:Array;
num=0;
//......
var mcLoaderEventsFoto:MovieClipLoader = new MovieClipLoader();
var listenerEFoto:Object = new Object();
var timeout:Number= new Number();
var totals:Number= new Number();
var effect:String= new String();
timeout=5000;
effect="oval";
//EVENTSBITMAP=["gf","fdf","sdf"];
//XML
var my_lv:LoadVars = new LoadVars();
function loadXML(loaded) {
if (loaded) {
xmlNode = this.firstChild;
image = [];
description = [];
total = xmlNode.childNodes.length;
totals=total;
for (i=0; i<total; i++) {
image[i] = xmlNode.childNodes[i].childNodes[0].firstChild.nodeValue;
description[i] = xmlNode.childNodes[i].childNodes[1].firstChild.nodeValue;
}
firstImage();
} else {
content = "file not loaded!";
}
}
xmlData = new XML();
xmlData.ignoreWhite = true;
xmlData.onLoad = loadXML;
xmlData.load("images.xml");
gogo();
//setInterval(pic_preview(5),100);
function gogo()
{
filesize = picture.getBytesTotal();
loaded = picture.getBytesLoaded();
}
//
function firstImage() {
if (true) {
for(j=0;j<total;j++)
{
loadMovie(image[j], 1);
trace("j: "+j + " , " + "im: "+image[j]);
}
}
}
//END XML
//array tranclate
mcLoaderEventsFoto.addListener(listenerEFoto);
loadEventsSlide(1999,5);
function loadEventsSlide (year, n) {
//создание пустого мувиклипа
this.createEmptyMovieClip('eventFoto' + year + n, this.getNextHighestDepth());
this['eventFoto' + year + n]._alpha = 100; //чтобы в прелоадере не мелькали загружаемые картинки
//когда объект загружен ,создаем функции с входным аргументом - муви,клип
listenerEFoto.onLoadInit = function (target_mc:MovieClip) {
//создаем объект типа BitmapData, под подгружаемый mc
var myImg:BitmapData = new BitmapData(target_mc._width, target_mc._height, false);
//отборжение эффекта
myImg.draw(target_mc);
//выгрузка мувиклипа из контейнера
//target_mc.unloadMovie();
//Массив муикльипа ,с имееными индексами заполнеяеться конкретной картикой
EVENTSBITMAP[num] = myImg;
trace(" name : "+num+ " :" + EVENTSBITMAP[num] + " hey: " );
num++;
return EVENTSBITMAP;
};
listenerEFoto.onLoadError = function (target_mc:MovieClip) {//если нет фото к событию
if (year >= yearsTotal) {
trace("ERROR, can't find file");
loadEventsStatus = 1; //конец
}
};
trace("ROUTE!::"+EventsPath + "foto/" + year + "." + n + ".jpg" + suffix );
mcLoaderEventsFoto.loadClip("fon.JPG", 1);
mcLoaderEventsFoto.loadClip("fon2.JPG", 2);
mcLoaderEventsFoto.loadClip("fon3.JPG", 3);
//p1.loadClip("fon.JPG",1);
p1.attachBitmap(EVENTSBITMAP[1], this.getNextHighestDepth());
};
//array traclate end
var linksID:Array=["1","2","3","4","5","6","7","p1","p2","p3"];
trace("linksId: " + linksID);
trace ("\n");
for(u=0;u<3;u++)
{
linksID[u]=EVENTSBITMAP[num];
}
//linksID=image[];
trace("total" +linksID);
for (var i:Number = 0; i < linksID.length; i++) {
bitmaps[i]=BitmapData.loadBitmap(linksID[i]);
}
//по сути надо что бы было
//bitmaps[i]= EVENTSBITMAP[i]
Вот это зачем?
return EVENTSBITMAP;
Возврат значения функции делаем только при такой записи:
b = my_functon (a);
и после return дальнейшие вычисления в функции останваливаются
Добавлено через 4 минуты
Что-то у вас в коде каша какая-то - зачем вы закомментировали загрузку loadClip, у вас же ничего грузится не будет теперь.
Потом, функция за раз грузит одну картинку, вот так делать нельзя:
mcLoaderEventsFoto.loadClip("fon.JPG", 1);
mcLoaderEventsFoto.loadClip("fon2.JPG", 2);
mcLoaderEventsFoto.loadClip("fon3.JPG", 3);
Вызывайте функцию в цикле.
Добавлено через 1 час 18 минут
Едем дальше.
Еще раз - вот в сжатом виде алгоритм:
var BITMAPDATA:Array = new Array(); //массив фото событий
......
var mcLoaderEventsFoto:MovieClipLoader = new MovieClipLoader();
var listenerEFoto:Object = new Object();
mcLoaderEventsFoto.addListener(listenerEFoto);
function loadEventsSlide (num) {
this.createEmptyMovieClip('foto' + num, this.getNextHighestDepth());
this['foto' + num]._alpha = 0; //чтобы в прелоадере на виду не мелькали загружаемые картинки
listenerEFoto.onLoadInit = function (target_mc:MovieClip) {
var myImg:BitmapData = new BitmapData(target_mc._width, target_mc._height, false);
myImg.draw(target_mc);
target_mc.unloadMovie();
BITMAPDATA[target_mc._name] = myImg;
};
mcLoaderEventsFoto.loadClip(num + '.jpg', this['foto' + num]);
};
//вызов загрузки, например, так:
for (i = 1; i < 11; i++) {
loadEventsSlide(i);
}
Все лишнее я убрал.
Загружаем, заполняем массив.
Дальше. Если записать проверку наполненности массива сразу после этого кода, то все должно быть undefined, потому что AS асинхронно работает с данными.
Поэтому проверку наполненности массива мы имеем право делать:
- либо внутри метода onLoadInit
- либо только спустя какое-то время, когда загрузка гарантированно завершена.
Для эксперимента можно нарисовать кнопку, на нее повесить вызов цикла обхода элементов массива:
test_btn.onRelease = function () {
for (k in BITMAPDATA) {
trace(k + ' ' + BITMAPDATA[k]);
}
}
Спасибо большое, буду разбираться, как раз почитал про класс MovieClipLoader.
Добавлено через 6 часов 10 минут
Разобрал код, потестил ,работает.. Возник вопрос, как это сделать без кнопки ,
надумал повесить слушатель, мол когда закончит чтение xml, запускать тоже самое что в кнопке ..
var array_test:Array=new Array();
var array_test1:Array=new Array();
var image:Array=new Array();
var lisen:Object=new Object();
function array_return(loaded)
{
array_test=['el1','el2','el3'];
for(i=0;i<array_test.length;i++)
trace ("array element: " + i + " content: " + array_test[i]);
// return array_test;
if (loaded) {
xmlNode = this.firstChild;
image = [];
description = [];
total = xmlNode.childNodes.length;
for (i=0; i<total; i++) {
image[i] = xmlNode.childNodes[i].childNodes[0].firstChild.nodeValue;
trace("image["+i+"]= "+image[i]);
description[i] = xmlNode.childNodes[i].childNodes[1].firstChild.nodeValue;
}
} else {
trace("file not loaded!");
}
return image;
}
//start function
xmlData = new XML();
xmlData.ignoreWhite = true;
xmlData.onLoad = array_return;
xmlData.load("images.xml");
lisen.onChanged =function() //Вопрос что поставить вместо onChanged
{
trace ("lisen is working");
}
btn1.onPress=function()
{
array_test1=array_return();
for(j=0;j<array_test1.length;j++)
trace ("j: " + j + " con: " + array_test1[j]);
}
array_return.addListener(lisen);
правильно ли я понял как работает слушатель?
Там не он onChanged понятное дело должен быть, а что то типо onComplete) не смог найди, хелп перестал работать.
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.