0

I'm creating a Flash movie that loads some XML containing details of some text and a image URL, that needs to replace a existing MovieClip in a Flash movie.

Is there a way in Flash to replace a existing MovieClip or to update it so that the updated/new display object keeps the original look of the original display object and any Tweening for the original display object still works we the new or updated display object.

Thanks

Stephen

Update: here is the code I'm using to load this:


import flash.events.IOErrorEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.display.DisplayObject;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.display.Loader;
import flash.text.TextField;
import flash.events.ProgressEvent;


// get the number of children in display list
var count:uint = numChildren;

// get the url for the Ceres server
//var configUrl:String = loaderInfo.parameters.configUrl;

// load the config file from the server using the configUrl
var configUrl:String = "C:\development\projects\ReadXMLInFlash\example_xml_ceres_response.xml";   //loaderInfo.parameters.configFileUrl;
var defaultImgUrl:String = loaderInfo.parameters.defaultImgUrl;
var urlRequest:URLRequest = new URLRequest( configUrl );

// create the XML loader
var urlLoader:URLLoader = new URLLoader();
urlLoader.load( urlRequest );
urlLoader.addEventListener(Event.COMPLETE, onDataLoaded);
//Error handling    ;
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
//Could be an error or just a message;
urlLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, onHTTPStatus);

function onDataLoaded(evt:Event):void
{
    var myXML:XML = new XML(evt.target.data);
    var node:XML;
    // loop through the XML
    for each (node in myXML.dynamicGroups.DynamicGroup.assets.Asset.elements.Element)
    {
        // check the assetValue of the XML, if contains http then a link use 'createNewImageLoader'
        if(String(node.assetTagName) == 'Image' )
        {
            createNewImageLoader( node.assetValue, node.elementName );
        }
        else
        {
            // else it is text (e.g. a product descrition) use createNewTextLoader
            createNewTextLoader( node.assetValue, node.elementName );
        }

    }

}

//error callbacks
function onIOError(evt:IOErrorEvent)
{
    trace("IOError: "+evt.text);
    // if an error load the default image
    var defaultImgLoader:Loader = new Loader();
    var defaultImgUrl:URLRequest = new URLRequest( defaultImgUrl );
    defaultImgLoader.load( defaultImgUrl );
    addChild( defaultImgLoader );

}
function onHTTPStatus(evt:HTTPStatusEvent)
{
    //trace("HTTPStatus: "+evt.status);
}
function onSecurityError(evt:SecurityErrorEvent)
{
    trace("SecurityError: "+evt.text);
}

// loads a image asset
function createNewImageLoader(loadURL:String, elementname:String):void
{
    for(var i:uint=0;i<numChildren;i++)
    {
        var display:DisplayObject = getChildAt(i);
        if (elementname == display.name)
        {
            var loader:Loader = new Loader();
            var urlRequest:URLRequest = new URLRequest(loadURL);
            loader.addEventListener(Event.COMPLETE, function(){
                                    loader.x = display.x;
                                    loader.y = display.y;
                                    addChild( loader );
                                    removeChild(display);
                                    });
            loader.load( urlRequest );

        }
    }
}
// adds new text to a display object
function createNewTextLoader( textToLoad:String, elementname:String):void
{
    trace( "elementname:" + elementname );

    for(var i:uint=0;i<count;i++)
    {
        var display:DisplayObject = getChildAt(i);

        trace( "displayName:" + display.name );
        if (elementname == display.name)
        {
            var textToDisplay:TextField = new TextField();
            textToDisplay.text = textToLoad;
            textToDisplay.x = display.x;
            textToDisplay.y = display.y;
            addChild(textToDisplay);
            removeChild(display);
            break;
        }
    }
}
Corey
  • 5,818
  • 2
  • 24
  • 37
StephenAdams
  • 521
  • 2
  • 9
  • 26
  • what do you mean by "the updated/new display object keeps the original look of the original display object"? – Kodiak Dec 15 '11 at 10:22
  • If a MovieClip contains blue text any new text added to that MC is also the same colour etc. I'm trying to inject new data into these MovieClips at runtime. So someone else can create a simple Flash Movie then my code loads the XML and injects new data into the Flash Movie. – StephenAdams Dec 15 '11 at 10:35
  • You can change pretty much anything but constants at runtime - what exactly are you trying to do? – weltraumpirat Dec 15 '11 at 11:03
  • Hi,I'm trying to dynamic inject text into existing MovieClips in a running Flash movie. So at runtime we can inject text/images that make the content of a Flash movie optimised for who ever is looking at it. – StephenAdams Dec 15 '11 at 11:13
  • What is the problem when you try to bind the data with your movieclip the second time? It's almost strictly the same thing as doing it once... – Kodiak Dec 15 '11 at 11:25
  • There are a couple of problems, one how to properly bind the data to the movieclip and two, if I do add the new data will it still work with the same Tweening effects and have the same colour (if a piece of text is added as a MovieClip that is Blue) will the updated clip still have the same colour e.g. Blue. – StephenAdams Dec 15 '11 at 11:40
  • I can't go further about this without seeing any code of yours. – Kodiak Dec 15 '11 at 12:50
  • Added the code to the original question – StephenAdams Dec 15 '11 at 13:50

2 Answers2

0

I'm not really sure what your problem is, or what you are trying to achieve, but I'll try to answer your question to the best of my ability.

From what I have read in the comments and your code, what you are trying to do is change the text and image inside a movieclip. To do this just change this code:

function createNewTextLoader( textToLoad:String, elementname:String):void
{
    trace( "elementname:" + elementname );

    for(var i:uint=0;i<count;i++)
    {
        var display:DisplayObject = getChildAt(i);

        trace( "displayName:" + display.name );
        if (elementname == display.name)
        {
            var textToDisplay:TextField = new TextField();
            textToDisplay.text = textToLoad;
            textToDisplay.x = display.x;
            textToDisplay.y = display.y;
            addChild(textToDisplay);
            removeChild(display);
            break;
        }
    }
}

to:

function createNewTextLoader( textToLoad:String, elementname:String):void
{
// If the display object by the name of the value of "elementname" exists and it is a text field
    if (getChildByName(elementname) != undefined &&
        getChildByName(elementname) is TextField)
    {
        var textToDisplay:TextField = (TextField)getChildByName(elementname);// I dont know if you need a cast here but just in case
        textToDisplay.text = textToLoad;// change the text in the text field
    }
}

and replace this:

function createNewImageLoader(loadURL:String, elementname:String):void
{
    for(var i:uint=0;i<numChildren;i++)
    {
        var display:DisplayObject = getChildAt(i);
        if (elementname == display.name)
        {
            var loader:Loader = new Loader();
            var urlRequest:URLRequest = new URLRequest(loadURL);
            loader.addEventListener(Event.COMPLETE, function(){
                                    loader.x = display.x;
                                    loader.y = display.y;
                                    addChild( loader );
                                    removeChild(display);
                                    });
            loader.load( urlRequest );
        }
    }
}

with this:

function createNewImageLoader(loadURL:String, elementname:String):void
{
    if (getChildByName(elementname) != undefined &&
        getChildByName(elementname) is Loader)
    {
        var loader:Loader = (Loader)(getChildByName(elementname);
        var urlRequest:URLRequest = new URLRequest(loadURL);
        loader.load( urlRequest );
    }
}

I haven't actually tested any of this code yet but it's difficult to tell if I'm even answering the right question.

annonymously
  • 4,708
  • 6
  • 33
  • 47
0

i don't really get why you already have the MCs on stage and have to update them after loading the XML ... can't you just create them after you loaded the XML?

in both cases it would be best to create two own classes (subclasses of MovieClip): TextLoader and ImageLoader with an update method.

package   
{
    import flash.display.MovieClip;

    public class TextLoader extends MovieClip 
    {
        private var _txt:TextField;

        public function TextLoader() 
        {
            _txt = new TextField();
            // do TextFormat stuff, set size and position of _txt
            addChild(_txt);

            // you could also set some initial text like:
            _txt.text = "loading ...";
            // this will be overwritten later
        }

        public function update(label:String):void 
        {
            _txt.text = label;
        }
    }
}

ImageLoader would also look like this but instead of the TextField got the Loader that is updated via the update(url:String) method.

create the MCs before loading the XML like this:

var allTxts:Array = [];
for (var i:int=0;i<10;++i)
{
    var txt:TextLoader = new TextLoader();
    txt.x = 50;
    txt.y = (i+1) * 50;
    txt.name = "txt_" + i;  // the names you got in your xml
    addChild(txt);

    allTxts.push(txt);
}

when the XML is loaded, update all MCs:

function getTxtWithName(name:String):TextLoader
{
    for (var i:int=0;i<allTxts.length;++i)
    {
        var txt:TextLoader = allTxts[i] as TextLoader;
        if (txt != null && txt.name == name)
        {
            return txt;
        }
    }
    return null;
}

function onDataLoaded(evt:Event):void
{
    var myXML:XML = new XML(evt.target.data);
    var node:XML;
    // loop through the XML
    for each (node in myXML.dynamicGroups.DynamicGroup.assets.Asset.elements.Element)
    {
        // check the assetValue of the XML, if contains http then a link use 'createNewImageLoader'
        if(String(node.assetTagName) == 'Image' )
        {
            var txt:TextLoader = getTxtWithName(node.elementName);
            if (txt != null)
            {
                txt.update(node.assetValue);
            }
        }
        else
        {
            // else it is text (e.g. a product descrition) use createNewTextLoader
            var img:ImageLoader = getImageWithName(node.elementName);
            if (img != null)
            {
                img.update(node.assetValue);
            }
        }
    }
}
Philipp Kyeck
  • 18,402
  • 15
  • 86
  • 123