Adding multiple instances of a Sprite?

2019-03-06 09:46发布

问题:

I am building a Custom Image Picker, that shows 6 alternative versions. However the photo is only showing on the 6th item.

_model.selectedPhoto returns a Sprite, and does not let the app function correctly.

However when I use _model.photos[ii], A photo is added to each item - Why is this? I need to add _model.selectedPhoto to each s:Sprite

        for (var ii:int; ii < 6; ii++)
        {
            //Create BG
            var s:Sprite = new Sprite();
            s.graphics.beginFill(Math.random() * 0xffffff, 0.4);
            s.graphics.drawRect(0, 0, 291, 184);
            //add Photo
            var p:Sprite = new Sprite();
            p.addChild(_model.selectedPhoto);
            p.scaleX = p.scaleY = 0.2;
            p.x = 0;
            p.y = 0;
            s.addChild(p);
            cards.push(s);
        }

回答1:

Ummm it's only showing the one photo on the 6th item because you're running a for loop 6 times and adding the selected photo to each new sprite in succession. You see when you add a display object to another display object, and then add that same display object to something else, the original item is pulled from the first display object and added to the next. I know that might be hard to understand when written that way so lets break to down this way:

var photo:Sprite = new Sprite();

var container1:Sprite = new Sprite();

var container2:Sprite = new Sprite();

//Add to the first container
container1.addChild(photo);

//At this point when you add to the next container, the object is removed from container1 and placed inside container 2
container2.addChild(photo);

That is why when you use _model.photos[ii] you add a unique picture to each of the 6 new container sprites you're making in your for loop, because there are unique items to add to each container. You're accessing these unique items by using an array index (the ii var) which increments with each loop.

If you want to add the same picture to each six items, then you're going to need to duplicate the data of the original picture 6 times. One way you can do this is by using a URLLoader object and reloading the binary data that makes up the original picture. You'd do this like so:

var originalPictureLoader:URLLoader = new URLLoader();

originalPictureLoader.addEventListener(Event.COMPLETE, originalPictureLoaded);

originalPictureLoader.dataFormat = URLLoaderDataFormat.BINARY;

originalPicture.load(new URLRequest("http://www.mysite.com/picture.jpg"));

private function originalPictureLoaded(e:Event):void
{
    var pictureBytes:ByteArray = URLLoader(e.currentTarget).data as ByteArray;

    var imageDiplicateLoader:Loader;

    for (var ii:int; ii < 6; ii++)
    {
        //Create BG
        var s:Sprite = new Sprite();
        s.graphics.beginFill(Math.random() * 0xffffff, 0.4);
        s.graphics.drawRect(0, 0, 291, 184);
        //add Photo
        var p:Sprite = new Sprite();

        imageDiplicateLoader = new Loader();
        imageDiplicateLoader.loadBytes(pictureBytes);

        p.addChild(imageDiplicateLoader);
        p.scaleX = p.scaleY = 0.2;
        p.x = 0;
        p.y = 0;
        s.addChild(p);
        cards.push(s);
    }
}

Now keep in mind this is just one method AND I've written this off the top of my head. So, I'm not sure but you MAY need to duplicate the pictureBytes data inside the for loop but I don't believe so. If you did have to, this is how you'd do it:

var bytesCopy:ByteArray = new ByteArray();
pictureBytes.position = 0;
bytesCopy.writeBytes(pictureBytes);


回答2:

I'm not sure I understand your code completely, but one thing is for sure; A DisplayObject (in your case a Sprite) cannot have more than one parent, thus, if you try to addChild it in a second place it will fail. This is likely your problem.