简体   繁体   English

AS2-使用预加载器加载外部SWF文件后,我无法控制它

[英]AS2 - after loading external swf with a preloader, I cannot control it

I have made an educational tool for a project and now it's time to put it online. 我已经为一个项目制作了教育工具,现在是时候将该软件发布到网上了。 It's about 12 Mb in size, so I thought a preloader would be a great idea. 它的大小约为12 Mb,所以我认为预加载器是个好主意。 I found this nice external preloader which shows progress bar, percentage and loads the main swf, but then I have no control over the main swf. 我找到了一个不错的外部预加载器,它显示进度条,百分比并加载主瑞士法郎,但后来我无法控制主瑞士法郎。 Everything on it appears as an MC without any code (mouse cursor changes to that hand showing a finger :) ) and, thus, does not respond to input. 它上的所有内容都显示为没有任何代码的MC(鼠标光标变为显示手指的那只手:)),因此不响应输入。 Does anyone know how to fix it? 有谁知道如何修理它? The code of the preloader: 预加载器的代码:

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;
}

EDIT: To better visualise the problem, I uploaded what I have. 编辑:为了更好地可视化问题,我上传了我所拥有的。 This is the version without preloader (give it some time to load): Without preloader . 这是没有预加载器的版本(给它一些加载时间): 没有预加载器 And this is what happens to the main program with preloader: With preloader 这就是使用预加载器对主程序进行的处理: 使用预加载器

The code you attached works perfectly well. 您附加的代码效果很好。 It can't interfere with you loaded file in any kinds. 它不会以任何形式干扰您加载的文件。 I bet your problem is that your scripts in original file wrote using absolute path to objects (with _root and stuff). 我敢打赌,您的问题是原始文件中的脚本是使用对象的绝对路径(带有_root和东西)编写的。 But when you load your original swf in new one with this loader, the new hierarchy appears. 但是,当您使用此加载程序将原始SWF文件加载到新的SWF文件中时,就会出现新的层次结构。 All you objects now inside MovieClip named mcContent . 现在,您在MovieClip中的所有对象都名为mcContent And you should consider that in you scripts inside main file. 您应该在主文件中的脚本中考虑到这一点。 Otherwise you could use _lockroot property. 否则,您可以使用_lockroot属性。 In first frame of your main project file write: 在主项目文件的第一帧中编写:

this._lockroot = true;

Now, even if this swf file will be loaded inside other one, all _root calls from it will target it own top level. 现在,即使此swf文件将被加载到其他文件中,来自该文件的所有_root调用也将以其自己的顶层为目标。 I might solve your problem. 我可以解决您的问题。 If its not, please add some code samples from buttons and stuff from your loaded file. 如果不是,请从按钮添加一些代码示例,并从加载的文件中添加内容。

Now I am sure that problem is in that roots. 现在我可以确定问题根源于此。 Use should use relative keywords to access your object. 使用应使用相对关键字来访问您的对象。 Change your button code to at to 将您的按钮代码更改为at

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

It should help. 应该会有所帮助。 If it not when there can be few reasons for this. 如果没有,原因可能很少。

  1. Instance on which code ( on(release){...} ) was written is not on main timeline. 编写代码( on(release){...} )的实例不在主时间轴上。 If it is inside another object (MovieClip, for example) then relative path in code should be other. 如果它在另一个对象(例如,MovieClip)中,则代码中的相对路径应该是另一个。
  2. The instance on which code was written is not instance of Button , but instance of MovieClip . 编写代码的实例不是Button实例,而是MovieClip实例。 In that case, using the on(...) handler on it - is kind of acceptable hack. 在这种情况下,在其on(...)使用on(...)处理程序-是一种可以接受的技巧。

There is differences in use of this . 使用this存在差异。 Keyword this used inside on(...) of Button instance lead you to the object where instance a placed. 关键字this里面用on(...)Button实例带领您到实例的放置的对象。 If this button lay somewhere in main timeline in any frame then this return id of main timeline. 如果此按钮位于任何帧中主时间轴中的某个位置,则this返回主时间轴的ID。 If you use this inside on(...) of MovieClip then it return id of this MovieClip . 如果on(...) MovieClip on(...)内部使用this ,则它将返回此MovieClip ID。

To determine exactly where the objects are and how you could refer from they location to object you need you should use trace(...); 要确定对象的确切位置以及如何从它们的位置引用到需要的对象,应使用trace(...); method. 方法。

Inside your button code add 在您的按钮代码中添加

trace(this);
trace(_root);

After that make preview of your main swf from Flash Professional ( Ctrl + Enter ) Press your button. 之后,从Flash Professional预览主SWF文件( 按Ctrl + Enter )按下按钮。 In output window you will get references to this and _root relatively to your code. 在输出窗口中,您将获得this引用和相对于您的代码的_root Save it somewhere. 将其保存在某处。 Then open your loader project and make preview of it. 然后打开您的加载程序项目并对其进行预览。 I should load you main swf with you button inside. 我应该在内部将您的按钮加载到主SWF文件中。 Press it. 按下。 Look at output. 看输出。 Save it. 保存。 Now you could compare trace results to determine changes between main file standalone and loaded inside your loader swf. 现在,您可以比较跟踪结果,以确定主文件独立文件与加载程序swf内部加载文件之间的更改。

In first trace you will get something like this 在第一个跟踪中,您将获得如下内容

_level0.someInstanceName
_level0

In second 在第二

_level0.mcContent.someInstanceName
_level0

This references will help to call right objects. 该引用将有助于调用正确的对象。 As you see, this and _root lead to different places. 如您所见, this_root指向不同的位置。 For us part of address before help variable and gotoAndStop() methods should lead to the top level object of your main swf. 对于我们来说, help变量和gotoAndStop()方法之前的地址部分应指向主swf的顶级对象。 Top level which we want access to in first trace is _level0 . 我们要在第一条跟踪中访问的顶级是_level0 In second trace as I said earlier '_level0.mcContent'. 正如我先前所说的那样,在第二个跟踪中是“ _level0.mcContent”。 And now you see why we can't use _root . 现在您了解了为什么我们不能使用_root It will guide us to the topmost object in both cases. 在两种情况下,它将引导我们到达最高的对象。 But now we see place of 'this' in hierarchy. 但是现在我们看到“ this”在层次结构中的位置。 It stay the same (even if reference to it object looks longer we still see same object in trace results of this ); 它保持不变(即使对它的引用看起来更长,我们仍然可以在this跟踪结果中看到相同的对象); And we see how deep inside our this relatively to our top object in main swf (first trace result). 并且我们看到相对于主swf中的顶部对象(第一跟踪结果), this对象的深度有多深。 It is first level after _root . 它是_root之后的第一级。 So all we need now is to climb up the hierarchy. 因此,我们现在需要的只是爬升层次结构。 And for this we should use _parent keyword. 为此,我们应该使用_parent关键字。 If we want climb up form _level0.someInstanceName to _level0 we will use 如果我们想从_level0.someInstanceName形式爬升到_level0我们将使用

this._parent

So if you outputs is similar to what I guess you code for your button should look like 因此,如果您的输出与我想的相似,则您的按钮代码应类似于

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

As you may guess this._parent when it used inside loaded swf will lead to same right object _level0.mcContent and code will work right as you suspect it should. 您可能会猜到这this._parent在已加载的swf中使用时,将导致正确的对象_level0.mcContent并且代码将按您怀疑的方式正确运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM