Actionscript 3 actionscript 3中的预加载程序-getDefinition()上的引用错误
我正在写一个预加载程序:Actionscript 3 actionscript 3中的预加载程序-getDefinition()上的引用错误,actionscript-3,preloader,Actionscript 3,Preloader,我正在写一个预加载程序: package { import flash.display.DisplayObject; import flash.display.Sprite; import flash.text.TextField; import flash.display.LoaderInfo; import flash.events.MouseEvent; import flash.events.Event; import flash.
package {
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.text.TextField;
import flash.display.LoaderInfo;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.system.System;
public class Preloader extends Sprite {
private var t:TextField = new TextField();
private var ver:String = "1000";
public function Preloader() {
t.y = 570;
addChild( t );
t.text = ver;
addEventListener( Event.ADDED_TO_STAGE, init );
}
private function init( e:Event ):void {
this.root.loaderInfo.addEventListener( ProgressEvent.PROGRESS, onLoadingProgress );
this.root.loaderInfo.addEventListener( Event.COMPLETE, onLoadingCompleted );
// See if it's already completed
var percent:int = int( root.loaderInfo.bytesLoaded / root.loaderInfo.bytesTotal );
if ( percent == 1 )
onLoadingCompleted();
}
private function onLoadingProgress( event:Event ):void {
var percent:int = int(root.loaderInfo.bytesLoaded / root.loaderInfo.bytesTotal * 100);
t.text = "Loading.. " + percent + "%";
}
private function onLoadingCompleted( event:Event = null ):void {
root.loaderInfo.removeEventListener( ProgressEvent.PROGRESS, onLoadingProgress );
root.loaderInfo.removeEventListener( Event.COMPLETE, onLoadingCompleted );
var mainClass:Class = loaderInfo.applicationDomain.getDefinition("Main") as Class;
var main:DisplayObject = new mainClass() as DisplayObject;
parent.addChild( main );
parent.removeChild( this );
}
}
}
以此为主要类:
package {
import flash.display.Sprite;
public class Main extends Sprite {
public function Main() {
}
}
}
所以这几乎是我所能做到的
然而,它用一句话问候我:
ReferenceError: Error #1065: Variable Main is not defined.
at flash.system::ApplicationDomain/getDefinition()
at ...
我已经使用frames.frame插入了Main。我直接使用ant和linux SDK(mxmlc)进行编译。我是否遗漏了任何明显的内容?如果在默认包中有Game类(“Game”而不是“Game.Game”),是否有什么不同 我从未使用过像new mainClass(this.root)这样的东西,new mainClass()应该可以
另外,如果您使用Event.INIT而不是Event.COMPLETE,是否有什么区别?当您以这种“样式”制作预加载程序时,真正发生的是预加载程序放在应用程序的第一个帧中,其余的放在第二个帧中。这里缺少的是告诉编译器您希望编译主类,所以现在它甚至不存在于swf中。这就是为什么getDefinition不起作用 也不能简单地在预加载程序中引用它,因为这会使它在显示预加载程序之前加载到第一帧中。所以,你需要一个小小的自定义参数魔法 将这一行添加到编译器选项中,您就可以开始了:
-frame start Main
请记住,如果主类位于包中,则需要在其中获取完整引用:
-frame start com.grapefrukt.examples.Main
getDefinition调用也是如此
编辑:
当查看我的代码时,我发现我使用了与您不同的方法,也许这更有效:
var mainClass:Class = getDefinitionByName("com.grapefrukt.examples.Main") as Class;
addChild(new mainClass() as DisplayObject);
再次编辑:
如果它使用一个按钮工作,我猜由于某种原因,整个事件触发得太早了。虽然所有的字节都是loaderd,但可能所有的事件都没有正确初始化。请尝试使用此代码检查是否完成:
if (currentFrame == totalFrames) onLoadingCompleted()
在onLoadingCompleted()方法中添加一个stop()命令可能也是一个好主意,只是为了使playhead不会把事情搞砸,但这确实是后面的问题。您缺少nextFrame()在函数onLoadingComplete中添加nextFrame() 下面是一个简单的版本:
这篇评论有点长,尽管它实际上是对Grapefrakt答案的扩展。这也是一个相当晚的答案。但我还没有看到Adobe或其他人在任何地方记录了这一点:
使用运行时共享库时,Event.COMPLETE
可能会“提前”(在下一帧实际就绪之前)触发的一个原因是<代码>事件。完成将在当前swf完成加载时触发-这可能(通常)发生在任何RSL完成加载之前
加载链接到RSL的库符号时,将加载RSL的“自动加载”(例如,在Flash Pro中使用“导入用于运行时共享”),这在通常的预加载程序实现中意味着播放头尝试进入第2帧时
在它们完成加载之前,您不能前进到第2帧-并且只要您不能前进,您就不能访问该帧上的任何类或实例。对gotoAndStop(2)
或nextFrame()
的任何调用都不会立即产生任何效果(即,在这种情况下,eLouai的回答不起作用),而且,调用也不会“排队”。playhead将只停留在第1帧上。可能是内部发生了一些引用错误,这些错误在FlashPlayer中的某个地方被吞没了。至少在我的测试中,从未报告过错误。它只是默默地失败了<代码>播放(),但是,当它准备好时,将转到下一帧
换句话说,正如grapefrukt建议的那样,如果swf正在播放,您可以在输入帧
侦听器中等待currentFrame==2
(或任何帧编号)。或者,您可以在ENTER\u frame
侦听器中调用nextFrame()
或gotoAndStop(2)
(或任何帧编号),直到检测到currentFrame==2
。后者看起来像是未来可能发生的事情,因为,同样,错误实际上可能是在内部发生的,尽管玩家没有输出任何错误
简言之:
play()
将等待第2帧准备就绪gotoAndStop(2)
或nextFrame()
将(看起来)没有任何效果,除非调用时frame 2已准备就绪。和Event.COMPLETE
不能保证所有帧都已准备好显示。特别是如果使用RSL,则不会这样做-可能还有其他原因。移动包=相同的结果。我将根作为变量传递给类(以便读取flashvars)Event.INIT没有更改任何内容。谢谢。集体游戏是公开的吗?还有,这方便吗?是的,这是公共的。我发现,如果我添加了一个按钮或计时器,它似乎找到了它。这几乎就像它在实际准备就绪之前触发事件一样..谢谢链接,但不可以=(酷!我不知道。我希望这能解决Timmy的问题。不幸的是,我已经这么做了。当我说“我使用frames.frame插入Main”时,我不清楚。不,运气不好。我想知道是否涉及到一些计时问题-我加了一个“开始”用onclick按钮,每次都有效。但仍然试图避免走这条路,上面的代码非常简单。该代码在FlashDevelop中似乎也能工作,但在我直接从mxmlc中执行时就不行了。奇怪。是的,我也在想同样的事情。我重写了它(作为电影剪辑)检查一下镜框,现在看起来还可以了。谢谢!
public class Preloader extends MovieClip
{
public function Preloader()
{
stop();
addEventListener(Event.ENTER_FRAME, onEnterFrame);
this.loaderInfo.addEventListener(Event.COMPLETE, startup);
// Set up progress bar / graphics
}
private function onEnterFrame(e:Event):void
{
// Display progress bar, loadedbytes, animation, etc...
}
private function startup(e:Event):void
{
nextFrame();
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
loaderInfo.removeEventListener(Event.COMPLETE, startup);
var gameClass:Class = getDefinitionByName("Main") as Class;
if (gameClass) addChild(new gameClass() as Sprite);
}
}