AS2 - 用预加载器加载外部swf后,我无法控制它

时间:2013-12-02 13:32:52

标签: flash actionscript-2 preloader

我为一个项目制作了一个教育工具,现在是时候把它放到网上了。它的大小约为12 Mb,所以我认为预加载器是一个好主意。我发现这个漂亮的外部预加载器显示进度条,百分比并加载主swf,但后来我无法控制主swf。它上面的所有内容都显示为没有任何代码的MC(鼠标光标变为显示手指的那只手:))因此,不响应输入。有谁知道如何修理它? 预加载器的代码:

import flash.geom.*
import flash.display.*

var loadurl:String = "project.swf";
var nDepth:Number = 0;
var nWidth:Number = 200;
var nHeight:Number = 20;
var nPadding:Number = 3;
var cLoader:MovieClipLoader = new MovieClipLoader();
var oListener:Object = {onLoadInit:onContentLoaded};
var mcLoader:MovieClip = this.createEmptyMovieClip("Loader_MC", 0);
var mcContent:MovieClip = this.createEmptyMovieClip("Content_MC", 1);
var mcLoadBarBg:MovieClip = mcLoader.createEmptyMovieClip("LoadBarBg_MC", nDepth++);
var mcLoadBar:MovieClip = null; //Duplicated later with mcLoadBarBg 
var txtPercLoad:TextField = null; //Create after duplication
var cMatrix:Matrix = new Matrix();
mcLoader._alpha = 0;
cMatrix.createGradientBox(nWidth, nHeight, 0, nPadding, nPadding);
cLoader.addListener(oListener);
mcLoader.lineStyle(1, 0x000066, 100);
DrawRect(mcLoader, 0, 0, nWidth, nHeight);
mcLoadBarBg.lineStyle(1, 0x0000FF, 0);
mcLoadBarBg.beginGradientFill("linear", [0x006699, 0x0066FF], [100,100], [0, 255], cMatrix, SpreadMethod.PAD);
DrawRect(mcLoadBarBg, 0, 0, nWidth - nPadding*2, nHeight - nPadding*2);
mcLoadBarBg.endFill();
mcLoadBar = mcLoadBarBg.duplicateMovieClip("LoadBar_MC", nDepth++);
txtPercLoad = mcLoader.createTextField("PercLoad_TXT", nDepth++, 0, 0, nWidth, nHeight);
mcLoadBar._alpha = 80;
mcLoadBarBg._alpha = 30;
Translate(mcTextMask, nPadding, nPadding);
Translate(mcLoadBarBg, nPadding, nPadding);
Translate(mcLoadBar, nPadding, nPadding);
mcLoadBar._xscale = 0;
mcContent._alpha = 0;
mcContent._lockroot = true;
mcLoader._x = Stage.width/2 - mcLoader._width/2;
mcLoader._y = Stage.height/2 - mcLoader._height/2;
txtPercLoad._x = mcLoader._width/2 - txtPercLoad._width/2;
txtPercLoad._y = mcLoader._height/2 - txtPercLoad._height/2;
SetTextFormat(txtPercLoad, "0%");
mcLoader._alpha = 100;
cLoader.loadClip(loadurl, mcContent);

_root.onEnterFrame = function()
{
   var nBytesLoaded:Number = mcContent.getBytesLoaded();
   var nBytesTotal:Number = mcContent.getBytesTotal();
   var nPercLoaded:Number = Math.round(nBytesLoaded / nBytesTotal * 100);
   if(nPercLoaded > 0)
   {
      SetTextFormat(txtPercLoad, nPercLoaded.toString() + "%");
      mcLoadBar._xscale = nPercLoaded;
   }
}

function onContentLoaded(Void):Void
{
   //trace(_root + "::onContentLoaded");
   SetTextFormat(txtPercLoad, "100%");
   cLoader.removeListener(oListener);
   delete _root.onEnterFrame;
   delete oListener;
   delete cLoader;
   _root.onEnterFrame = function()
   {
      //trace(_root + "::onContentLoaded::_root.onEnterFrame");
      var nInc:Number = 5;
      mcLoader._alpha -= nInc;
      mcContent._alpha += nInc;
      if(mcLoader._alpha <= 0) startLoadedContent();
   }
}

function startLoadedContent(Void):Void
{
   delete _root.onEnterFrame;
   mcLoader.removeMovieClip();
   mcContent._alpha = 100;
}

function DrawRect(mc:MovieClip, nX:Number, nY:Number, nW:Number, nH:Number, nR:Number)
{
   //trace("DrawRect in: " + mc);
   if(nR == undefined) nR = 6;
   mc.moveTo(nX+nR,nY);
   mc.lineTo(nX+nW-nR,nY);
   mc.curveTo(nX+nW,nY,nX+nW,nY+nR);
   mc.lineTo(nX+nW,nY+nH-nR);
   mc.curveTo(nX+nW,nY+nH,nX+nW-nR,nY+nH);
   mc.lineTo(nX+nR,nY+nH);
   mc.curveTo(nX,nY+nH,nX,nY+nH-nR);
   mc.lineTo(nX,nY+nR);
   mc.curveTo(nX,nY,nX+nR,nY);
}

function SetTextFormat(txtField:TextField, sText:String)
{
   var txtFmt:TextFormat = new TextFormat();
   sText = "Loading... " + sText;
   txtFmt.font = "Verdana";
   txtFmt.align = "center";
   txtFmt.size = 11;
   txtFmt.color = 0x000066;
   txtFmt.bold = true;
   txtField.selectable = false;
   txtField.text = sText;
   txtField.setTextFormat(txtFmt);
   txtFmt = null;
}

function Translate(mc:MovieClip, nX:Number, nY:Number):Void
{
   mc._x = nX;
   mc._y = nY;
}

编辑:为了更好地可视化问题,我上传了我的内容。这是没有预加载器的版本(给它一些时间来加载):Without preloader。这是使用预加载器的主程序发生的事情:With preloader

1 个答案:

答案 0 :(得分:0)

您附加的代码非常有效。 它不会干扰你加载的任何文件。 我打赌你的问题是原始文件中的脚本使用绝对路径写入对象(_root和东西)。但是当您使用此加载器在新的加载原始swf时,会出现新的层次结构。你现在所有的对象都在名为mcContent的MovieClip中。你应该考虑在主文件中的脚本中。 否则,您可以使用_lockroot属性。 在主项目文件的第一帧中写:

this._lockroot = true;

现在,即使这个swf文件将被加载到其他文件中,所有来自它的_root调用都将以它自己的顶层为目标。我可以解决你的问题。 如果没有,请从加载文件中的按钮和内容中添加一些代码示例。

现在我确信问题出在那个根源上。使用时应使用相对关键字来访问您的对象。将您的按钮代码更改为at

on(release){
    this.help = true;
    this.gotoAndStop("mainVideo");
}

应该有所帮助。 如果不是,那么几乎没有理由。

  1. 写入代码(on(release){...})的实例不在主时间轴上。如果它在另一个对象(例如,MovieClip)中,那么代码中的相对路径应该是另一个。
  2. 编写代码的实例不是Button的实例,而是MovieClip的实例。在这种情况下,使用on(...)处理程序 - 是一种可接受的黑客攻击。
  3. this的使用存在差异。 在this实例的on(...)内使用的关键字Button会将您引导到放置实例的对象。如果此按钮位于主时间轴中任何帧的某个位置,则this将返回主时间轴的ID。 如果您在this的{​​{1}}内使用on(...),则会返回此MovieClip的ID。

    要确定对象的确切位置以及如何从它们的位置引用到对象,您需要使用MovieClip方法。

    在按钮代码中添加

    trace(...);

    之后,从Flash Professional预览主SWF( Ctrl + Enter ) 按下按钮。在输出窗口中,您将获得相对于您的代码的trace(this); trace(_root); this的引用。把它保存在某个地方。 然后打开您的加载器项目并预览它。我应该用你的按钮在里面加载主SWF。按下。看看输出。保存。 现在,您可以比较跟踪结果,以确定独立主文件和加载器swf中加载的主文件之间的更改。

    在第一次追踪中你会得到类似的东西

    _root

    第二次

    _level0.someInstanceName
    _level0
    

    此引用将有助于调用正确的对象。 如您所见,_level0.mcContent.someInstanceName _level0 this会导致不同的地方。对于我们来说,_root变量之前的部分地址和help方法应该导致主swf的顶级对象。我们希望在第一个跟踪中访问的顶级是gotoAndStop()。正如我之前所说的“_level0.mcContent”中的第二个跟踪。现在你明白为什么我们不能使用_level0。在这两种情况下,它将引导我们到最顶层的对象。 但现在我们在层次结构中看到“这个”的位置。它保持不变(即使对它的引用看起来更长,我们仍然在_root的跟踪结果中看到相同的对象); 我们看到this内部相对于主swf中的顶层对象(第一个跟踪结果)有多深。它是this之后的第一级。所以我们现在需要的是爬上层次结构。 为此,我们应该使用_root关键字。 如果我们想要从_parent升级到_level0.someInstanceName,我们将使用

    _level0

    因此,如果您的输出类似于我猜您的按钮代码应该类似于

    this._parent
    

    正如你可能猜到的那样on(release){ this._parent.help = true; this._parent.gotoAndStop("mainVideo"); } 在内部加载的swf中使用时会导致相同的正确对象this._parent,并且代码会在您怀疑应该正确的情况下正常工作。