3

私はプリローダーを書いています:

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)。明らかな何かが欠けていますか?

4

4 に答える 4

4

この「スタイル」でプリローダーを作成すると、実際にはプリローダーがアプリケーションの最初のフレームに配置され、残りは 2 番目のフレームに配置されます。ここで見逃しているのは、Main クラスをコンパイルすることをコンパイラに伝えることです。そのため、現時点では、swf には存在しません。そのため、getDefinition は機能しません。

また、プリローダーが表示される前に最初のフレームに読み込まれるため、プリローダーで単純に参照することもできません。そのため、カスタムの引数マジックが少し必要です。

次の行をコンパイラ オプションに追加すると、準備完了です。

-frame start Main

Main クラスがパッケージ内にある場合は、そこに完全な参照を取得する必要があることに注意してください。

-frame start com.grapefrukt.examples.Main

getDefinition 呼び出しについても同様です。

編集:

これを行う私のコードを見ると、あなたがしたこととは異なるアプローチを使用していることがわかります。

var mainClass:Class = getDefinitionByName("com.grapefrukt.examples.Main") as Class;
addChild(new mainClass() as DisplayObject);

再度編集: ボタンを使用して機能する場合は、何らかの理由で完全なイベントが早すぎると思います。すべてのバイトがロードされているにもかかわらず、すべてが正しく初期化されていない可能性があります。代わりに、このコードを使用して完了を確認してみてください。

if (currentFrame == totalFrames) onLoadingCompleted()

再生ヘッドが問題を起こさないようにするためだけに onLoadingCompleted() メソッドに stop() コマンドを追加することも良い考えかもしれませんが、それは実際には後の問題です。

于 2009-11-18T09:18:47.547 に答える
1

デフォルトのパッケージ (「game.Game」ではなく「Game」) に Game クラスがある場合、違いはありますか?

私は new mainClass( this.root ) のようなものを使用したことがありません。 new mainClass() は問題ないはずです。

また、 Event.COMPLETE の代わりに Event.INIT を使用すると違いはありますか?

于 2009-11-17T23:33:17.093 に答える
1

これはコメントには少し長いですが、実際にはグレープフルーツの答えを拡張したものです。それはかなり遅い答えでもあります。しかし、アドビや他の誰かによってこれが文書化されているのを見たことがありません。

Event.COMPLETE「早い段階で」(次のフレームが実際に準備される前に) トリガーされるように見える理由の 1 つは、ランタイム共有ライブラリを使用している場合です。Event.COMPLETE現在の swf の読み込みが完了したときにトリガーされます。これは、RSL の読み込みが完了する前に発生する可能性があります (通常は発生します)。

「自動的に」読み込まれた RSL は (たとえば、Flash Pro で「ランタイム共有用にインポート」を使用して)、それらにリンクしているライブラリ シンボルが読み込まれるときに読み込まれます。これは、通常のプリローダーの実装では、再生ヘッドがフレーム 2 に入ろうとするときを意味します。

それらの読み込みが完了するまで、フレーム 2 に進むことはできません。進むことができない限り、そのフレームのクラスやインスタンスにアクセスすることはできません。gotoAndStop(2)orを呼び出しnextFrame()てもすぐには効果がありません (つまり、この場合、eLouai の回答は機能しません)。さらに、呼び出しは「キューに入れられる」こともありません。再生ヘッドは単にフレーム 1 にとどまります。FlashPlayer のどこかで飲み込まれた参照エラーが内部的に発生する可能性があります。少なくとも私のテストでは、エラーは報告されません。黙って失敗するだけです。play()ただし、準備ができたら次のフレームに移動します

つまり、グレープフルクトが示唆するように、swf が再生されている場合は、リスナーでcurrentFrame == 2(または任意のフレーム番号) を待つことができます。または、それを検出するまでリスナーでor (または任意のフレーム番号) をENTER_FRAME呼び出すことができます。後者は、プレーヤーが何も出力していなくても、実際には内部でエラーが発生している可能性があるため、将来的に壊れる可能性があるようです。nextFrame()gotoAndStop(2)ENTER_FRAMEcurrentFrame == 2

要するに:

play()フレーム 2 の準備が整うまで待機します。gotoAndStop(2)orは、呼び出されたときにnextFrame()フレーム 2 の準備ができていない限り、何の効果もありません。また、すべてのフレームが表示可能であることを保証するものではありません。特に RSL を使用している場合はそうではありません - 他の理由があるかもしれません。Event.COMPLETE

于 2012-11-18T17:44:08.487 に答える