从 AS3 容器调用 AS2 函数

发布于 12-14 08:47 字数 419 浏览 6 评论 0原文

我正在尝试从 AS3 容器 调用一个函数,该函数应该调用无法编辑的旧 AS2 SWF 因为我们正在谈论 1000 个 swf 文件,确实存在某种方法从 AS3 容器 调用 AS2 SWF 内的函数?

我知道一种可能的方法,将 LocalConnection 添加为 写在这里,但正如我所说,我不能编辑所有 swf 文件,所以我只是想知道是否存在其他选择。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

长伴2024-12-21 08:47:11

如果您的容器绝对必须用 AS3 编写,那么您可以在 AS2 中创建另一个中间容器,它可以直接与 1000 个现有 SWF 通信,然后您可以使用 LocalConnection 技术与其通信。

下面的代码是一个简单的示例,但由于 MovieClipLoader 的问题在加载到 AS3 AVM1 对象时似乎不会触发事件,我不得不实现一个相当丑陋的轮询系统。与此问题相关的问题可以在这里找到:为什么加载到 AS3 包装器时 MovieClipLoader 事件不会触发?

child_as2.swf - 我们尝试加载的一千个 AS2 文件之一。它在其根目录上定义了我们要在加载时访问的函数:

stop();

function playMovie() {
    play();
}

parent_as2.swf - 中间 AS2 文件,包含用于桥接 AVM1 和 AVM2 运行时的 LocalConnection 代码。由于上述事件问题,这会轮询 child_as2.swf 以检测其何时加载以及根上的已知函数何时可用。重要的是,忽略对 checkProgress 的第一次轮询调用,因为这将返回不正确的进度值,如下所示: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 - 外部 AS3 包装器。这会将parent_as2.swf 加载到AVM1 对象中,并通过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);
}

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);
}
坏尐絯2024-12-21 08:47:11

对于这样的情况,我一点也不羡慕。我唯一的建议是反编译…1000 个 SWF 并在那里实现 LocalConnection 逻辑,如果架构正确的话,也许在共享 SWC 中,重新编译 SWF 并从那里开始。

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.

水波映月2024-12-21 08:47:11

您可以制作一个 as2 swf 来建立本地连接。此 swf 可以调用外部 as2 文件并将响应返回到 as3 文件。下面的例子,希望对你有帮助。

下面的代码块来自我之前做过的一个项目。它使用 as2 文件连接服务器。剪下一些代码块希望你能解决问题。

// 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","[email protected]" , "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");
}

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","[email protected]" , "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");
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文