views:

642

answers:

3

I need to load a set of images with from XML and assign Interactivity to them

first I load the XML

import flash.display.Loader;
import flash.net.URLRequest;
    var loader:Loader      = new URLLoader();
    var request:URLRequest = new URLRequest("myXML.xml");
    loader.load(request);

loader.addEventListener(Event.Complete, proessFile);
function processFile(e:Event):void
{
 var loadedXML:XML = (e.target.data);
}

//load set of images from XML file

for (var i:uint = 0; i < loadedXML.image.length(); i++)
{
    var imgLoader:Loader      = new Loader();
    var imgRequest:URLRequest = new URLRequest (loadedXML.img[i].attribute("filepath"));
    imgLoader.load(imgRequest);
    addChild(imgLoader);
}

here I need to make every single image draggable. Is it possible to change it into another data type, b/c I can't work with Loader?

I've tried assign them .name property, but I was unable to call them later.

I don't know If I'm clear enough, but essentially I need to work with every single loaded image as new object. Is it possible to assign variable to every single image?

Any suggestion for thework flow here would be much appreciated.

+2  A: 

Because you add them to the stage, you could try naming them and then calling them via the stage's getChildByName method.

Or you could build an array of loaders or, better yet, movieClips. Something like: import flash.display.Loader; import flash.net.URLRequest;

var loader:Loader      = new URLLoader();
var request:URLRequest = new URLRequest("myXML.xml");
loader.load(request);

var images:Array = new Array();

loader.addEventListener(Event.Complete, proessFile);
function processFile(e:Event):void
{
 var loadedXML:XML = (e.target.data);
}

//load set of images from XML file

for (var i:uint = 0; i < loadedXML.image.length(); i++)
{
    // create a new movie clip
    var tmpMovieClip:MovieClip = new MovieClip();
    var imgLoader:Loader      = new Loader();
    var imgRequest:URLRequest = new URLRequest (loadedXML.img[i].attribute("filepath"));
    imgLoader.load(imgRequest);
    // add the loader to the movie clip's display list
    tmpMovieClip.addChild(imgLoader);
    // add the movieclip to the previously declared array
    images.push(tmpMovieClip);
}

This way, you can call and use any element of the Array when you need them. If you don't need the MoviClips, you could just add the Loader instances into the Array.

evilpenguin
thank you for help. I've put objects in Sprite, and access them with an array.
dd
you're welcome. if it was useful, please accept my answer by clicking on the checkmark next to the beginning of my post.
evilpenguin
+1  A: 

I'm afraid I am having trouble understanding some your questions.

Is it possible to change it into another data type, b/c I can't work with Loader?

First, what data type would you like to change it to. Second, why can't you work with Loader?

I've tried assign them .name property, but I was unable to call them later.

Why did you want to call them and how did you try to?

I need to work with every single loaded image as new object.

Each loader object encapsulates a single image object. The image is actually inside the Loader (on the .content property).


evilpenguin describes how you can store references to the loader objects inside an array so that you can access them later. That is the correct basic approach. The real question is: "What exactly are you trying to do?"

You say:

here I need to make every single image draggable.

If it is that simple, then add events directly to the loader (which encapsulates the image).

for each(var image:XML in loadedXML.image)
{
    var imgLoader:Loader = new Loader();
    var imgRequest:URLRequest = new URLRequest(image.@filepath);
    imgLoader.load(imgRequest);
    addChild(imgLoader);

    // NOTE: you may want to wait until it is done loading
    // before you add drag and drop behaviour although
    // that isn't strictly necessary
    makeDraggable(imgLoader);
}


function makeDraggable(loader:Loader):void
{
    loader.addEventListener(MouseEvent.MOUSE_DOWN, startDrag);
    loader.addEventListener(MouseEvent.MOUSE_UP, stopDrag);

    // NOTE: I'll leave it up to you to decide
    // how you want to implement drag and drop
}

Note: I've also changed your loop to use E4X which is a much nice way of dealing with XML in Actionscript.

James Fassett
Adding events to the loader is more efficient, theoretically, but poses a usability problem: the Loader class does not have the .buttonMode property, hence it doesn't change the mouse cursor on hover. That means the user doesn't necessarily realize there are mouse actions on the object. That's why, if performance is not an absurde concern, I'd rather enclose the loaders in movieclips. Am I missing something, is there an other way to do this?
evilpenguin
On question what exactly am I trying to do. I want to make a Class which would extend functionality of every loaded item. I want to to put all interactivity in that Class. Single Class for all items.
dd
A: 

To create a 'copy' of your images simply do the following.

private function contentLoaderInfo_completeHandler(event:Event):void
{
    var loaderInfo:LoaderInfo = event.target as LoaderInfo;
    var originalBitmap:Bitmap = loaderInfo.content as Bitmap;
    var newBitmap:Bitmap = new Bitmap(originalBitmap.bitmapData.clone());
    images.push(addChild(newBitmap));
}

This way you are completely detached from the loader object and can dispose of them completely. Obviously as evilpenguin suggested you could then instead add them to Sprites or MovieClips and then add these to the stage (the Bitmap class is not a DisplayObjectContainer and so you can not add extra children to them).