0

エラー #1009 のデバッグに関する MJW のガイドに従って、ヌル ステージ エラー全体を修正することができました。しかし、弾丸を初期化する関数が呼び出されなくなりました。

切れ端:

if (stage) {
 init();
} else {
addEventListener(Event.ADDED_TO_STAGE, init);               
}

...

private function init(event:Event = null) {

    removeEventListener(Event.ADDED_TO_STAGE, init);
    stage.addEventListener(Event.ENTER_FRAME, shoot);


}

...

private function shoot(event:Event) {

    var bullet:EnemyBullet = new EnemyBullet();

    stage.addChild(bullet);

    bullet.x = enemy.x;
    bullet.y = enemy.y;

    bullet.theta = Math.random() * 360;

    bManager.bulletVector.push(bullet);


}

2 番目の 2 つの関数内に trace() を配置すると、何も起こらないことに注意してください。ただし、最初のスニペットの addEventListener() は呼び出されます (またはそう思う)。

4

2 に答える 2

1

一般的な慣行として、stage 参照しないでください。特に、弾丸クラスのインスタンスを追加するためだけに参照する場合は特にそうです。z-index の問題である場合は、代わりに、表示リストの他の表示オブジェクトの上に箇条書きを配置するレイヤーを使用できます。

1 つのステージに複数の SWF をロードする複雑さのほかに、表示オブジェクトを表示リストの独自の階層に追加することで、コードは適切に分離された機能単位になります。または、コントローラーがビューを操作する MVC パターンを利用することもできます。

コードが機能するためには、そのクラスが SWF のメイン関数であるか、ステージに追加されている必要があります。

SWF のメイン関数である場合は、init()が呼び出されます。

それ以外の場合は、 を介して表示リストに追加されることを確認してaddChild()ください。

本当に毎フレーム弾丸を発射するつもりですか?それは毎秒24から60発の弾丸になる可能性があります。弾丸が発火するかどうかにかかわらず、ある程度の確率でそれを抑制したい場合があります。

これが戦場で、バトルフィールド クラスがステージに追加されたとします。これは次のように実装できます。

package
{
    import flash.display.Sprite;
    import flash.events.Event;

    [SWF(percentWidth = 100, percentHeight = 100, backgroundColor = 0x0, frameRate = 30)]
    public class Battlefield extends Sprite
    {
        public function Battlefield()
        {
            if (stage)
                init();
            else
                addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
        }

        protected function addedToStageHandler(event:Event):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
            init();
        }
        protected function init():void
        {
            addEventListener(Event.ENTER_FRAME, frameHandler);
        }

        protected function frameHandler(event:Event):void
        {
            var odds:Number = Math.random();

            trace((odds < 0.1 ? "Fire!   " : "Skip...") + "Odds were: " + odds);
        }

    }
}

どちらが出力されますか:

Skip... Odds were: 0.3539872486144304
Skip... Odds were: 0.742108017206192
Fire!   Odds were: 0.025597115512937307
Skip... Odds were: 0.7608889108523726
Fire!   Odds were: 0.08514392375946045 
Skip... Odds were: 0.27881692815572023

Stage3D 以外では、次のようなステージ イベントに簡単に依存できるため、この初期化パターンが好きではありませんでした。

package
{
    import flash.display.Sprite;
    import flash.events.Event;

    [SWF(percentWidth = 100, percentHeight = 100, backgroundColor = 0x0, frameRate = 30)]
    public class Battlefield extends Sprite
    {
        public function Battlefield()
        {
            addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
        }

        protected function addedToStageHandler(event:Event):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
            addEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);

            addEventListener(Event.ENTER_FRAME, frameHandler);
        }

        protected function removedFromStageHandler(event:Event):void
        {
            removeEventListener(Event.ENTER_FRAME, frameHandler);

            removeEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);
            addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
        }

        protected function frameHandler(event:Event):void
        {
            var odds:Number = Math.random();

            trace((odds < 0.1 ? "Fire!   " : "Skip...") + "Odds were: " + odds);
        }

    }
}

したがって、ステージに追加されると、クラスはそのアクションを開始し、ステージから削除されると、クラスはそのアクションを終了します。

于 2012-10-30T00:26:20.160 に答える
0

問題は最初のブロックにあると思います。

ステージをチェックしています。ステージが null でない場合は、追加されたステージ リスナーを使用します。

あなただけを使用する必要がありますaddEventListener(Event.ADDED_TO_STAGE, init);

ただし、これはクラスが DisplayObject サブクラスであることを前提としており、ステージに追加されないオブジェクトは ADDED_TO_STAGE リスナーを呼び出すことができません

于 2012-10-29T23:04:07.967 に答える