Call to an AS2 function from the AS3 container

孤街醉人 提交于 2019-12-11 16:44:11

问题


I'm trying to call a function from a AS3 container which should call old AS2 SWF that cannot be edited bacause we are talking about 1000 swf files, does exist some way to call a function inside the AS2 SWF from the AS3 container?

I know a possible way by adding a LocalConnection as written here but as I said I can't edit all the swf files, so I just wonder to know if does exist some alternative.


回答1:


If your container absolutely has to be written in AS3, then you could create another intermediary container in AS2 that can communicate with the 1000 existing SWFs directly, and you can then communicate with that using the LocalConnection technique.

The code below is a simple example of this, but due to an issue with the MovieClipLoader seeming to not fire events when loaded into an AS3 AVM1 object I have had to implement a rather ugly polling system. The question relating to this issue can be found be here: Why do MovieClipLoader events not fire when loaded into an AS3 wrapper?.

child_as2.swf - One of a thousand AS2 files that we are trying to load. It has defined functions on it's root that we want to access when it is loaded:

stop();

function playMovie() {
    play();
}

parent_as2.swf - The intermediary AS2 file that contains LocalConnection code to bridge between the AVM1 and AVM2 runtimes. Due to the events issue noted above, this polls child_as2.swf to detect both when it is loaded and when a known function on the root is available. It is important that the first polling call to checkProgress is disregarded as this will return incorrect progress values as noted here: http://help.adobe.com/en_US/AS2LCR/Flash_10.0/00001380.html

var container:MovieClip = createEmptyMovieClip("container", 10);
var mcLoader:MovieClipLoader = new MovieClipLoader();
var loadStarted:Boolean;
var checkingInt:Number;

function checkProgress() {
    var progObj:Object = mcLoader.getProgress(container);
    if(progObj.bytesLoaded == progObj.bytesTotal && loadStarted) {
        //load complete, wait for loadInit
        if(typeof(container.playMovie) == "function") {
            //loadInit
            clearInterval(checkingInt);
            container.playMovie();
        }
    }
    //ensures the first loop is ignored due to inaccuracy with reporting
    loadStarted = true;
}

//LocalConnection code
var myLC:LocalConnection = new LocalConnection();

myLC.loadChild = function() {
    loadStarted = false;
    mcLoader.loadClip("child_as2.swf", container);
    checkingInt = setInterval(checkProgress,5);
}

myLC.connect("AVM");

parent_as3.swf - The outer AS3 wrapper. This loads parent_as2.swf into an AVM1 object, and communicates with it via LocalConnection.

var myLC:LocalConnection = new LocalConnection();

var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.INIT,onLoaded);
loader.load(new URLRequest("parent_as2.swf"));
addChild(loader);


function onLoaded(event:Event):void {
    //setTimeout hack to circumvent #2000 Security context error
    setTimeout(function() {
        myLC.send("AVM", "loadChild");
    },1);
}



回答2:


I do not envy this situation one bit. The only suggestion I have is to decompile the… 1000 SWFs and implement the LocalConnection logic there, perhaps in a shared SWC if architected properly, recompile the SWFs and go from there.




回答3:


You can make a as2 swf to make the localconnections. This swf can call your external as2 files and return responces to as3 file. Example below, hope it helps.

The code block below from a project that i did before. It was using as2 file to connect server. Cut out some block of codes hope you can sort out the solution.

// AS3 FILE
// local connection instance to communicate to AVM1 movie
var AVM_lc:LocalConnection = new LocalConnection();
AVM_lc.client = this;

// loader loads AVM1 movie
var loader:Loader = new Loader();
loader.load(new URLRequest("log2.swf"));
//addChild(loader);
// when AVM1 movie is clicked, call stopPlayback
stage.addEventListener(MouseEvent.CLICK, stopPlayback);

function stopPlayback(event:MouseEvent):void {
    // send login event to "AVM2toAVM1" connection
    AVM_lc.send("AVM2toAVM1", "logIn","test@test.com" , "123123");

}

function resulFunc(a:*){
    trace(a + " *-*-*-*-");
}
AVM_lc.connect("AVM1TO");



// AS2 FILE - log2.swf

var AVM_lc:LocalConnection = new LocalConnection();

AVM_lc.logIn = function(a , b){ 
    trace("login : " , a , " - " , b);

}
AVM_lc.connect("AVM2toAVM1");

function sendDataToAs3():Void{
    AVM_lc.send("AVM1TO", "resulFunc", "test value");
}


来源:https://stackoverflow.com/questions/8064798/call-to-an-as2-function-from-the-as3-container

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!