我为一个项目制作了一个教育工具,现在是时候把它放到网上了。它的大小约为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
答案 0 :(得分:0)
您附加的代码非常有效。
它不会干扰你加载的任何文件。
我打赌你的问题是原始文件中的脚本使用绝对路径写入对象(_root
和东西)。但是当您使用此加载器在新的加载原始swf时,会出现新的层次结构。你现在所有的对象都在名为mcContent
的MovieClip中。你应该考虑在主文件中的脚本中。
否则,您可以使用_lockroot
属性。
在主项目文件的第一帧中写:
this._lockroot = true;
现在,即使这个swf文件将被加载到其他文件中,所有来自它的_root调用都将以它自己的顶层为目标。我可以解决你的问题。 如果没有,请从加载文件中的按钮和内容中添加一些代码示例。
现在我确信问题出在那个根源上。使用时应使用相对关键字来访问您的对象。将您的按钮代码更改为at
on(release){
this.help = true;
this.gotoAndStop("mainVideo");
}
应该有所帮助。 如果不是,那么几乎没有理由。
on(release){...}
)的实例不在主时间轴上。如果它在另一个对象(例如,MovieClip)中,那么代码中的相对路径应该是另一个。Button
的实例,而是MovieClip
的实例。在这种情况下,使用on(...)
处理程序 - 是一种可接受的黑客攻击。 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
,并且代码会在您怀疑应该正确的情况下正常工作。