0

私は現在ゲームを作成しようとしていますが、問題は、イベントをディスパッチするときに、メイン クラス (エンジン) だけがそれを取得することです。Weapons.as にも拾ってもらいたいです。私のメイン クラスは Engine.as (ステージ クラスに割り当てられています) で、私の Weapons.as は船です。Score.as というクラスからイベントをディスパッチしています。

主な問題は、私の Weapons.as が「gameO」や「gameOver」イベント、score.as ディスパッチを検出しないことです。もう 1 つのことは、if(s_hp == 100) (開始点) を設定すると、Weapons.as はディスパッチされたイベントを取得することができますが、そのときだけ...

より具体的には、Score.as から Weapons.as を介してメイン クラス Engine.as にイベントをバブルしたい/必要があります。Weapons.as の eventListener は、それを拾って船を取り除き、発砲できないようにする必要があります。次に、イベントをさらに Engine.as クラスに渡します。これにより、ステージからほとんどすべてが削除されます。

私が得た助けに感謝します!:)

編集:フルクラス

スコア.as:

package Etys
{

    import flash.display.MovieClip;
    import flash.display.Stage;
    import flash.text.TextField;
    import flash.events.Event;
    import flash.utils.Timer;
    import flash.geom.ColorTransform;

    public class Score extends MovieClip
    {

        private var stageRef:Stage;
        public var s_score:Number = 0;
        public var s_hits:Number;
        public var s_kills:Number = 0;


        public function Score(stageRef:Stage)
        {

            this.stageRef = stageRef;
            s_hits = 100;
            healthBar.width = 100;
            kills.text = "Kills: \n0";
            hits.text = "HP: \n100";
            score.text = "Score: \n0";
            kills.selectable = false;
            hits.selectable = false;
            score.selectable = false;

            x = 10;
            y = stageRef.stageHeight - height;
            addEventListener(Event.ENTER_FRAME, loop, false, 0, true);

        }

        public function updateKills(value:Number) : void
        {
            s_kills += value;
            kills.text = String("Kills: \n"+s_kills);
            trace(s_hits+"I Kills");
        }

        public function updateHits(value:Number) : void
        {
            if(s_hits != 1 || s_hits != 0)
            {
                s_hits -= value;
                healthBar.width -= value;
                hits.text = String("HP: \n"+s_hits);
            }else{
                healthBar.width = 0;
                s_hits = 0;
                hits.text = String("HP: \n"+s_hits);
            }

            if(s_hits == 66 ||s_hits == 67)
            {
                var colorYellow:ColorTransform = healthBar.transform.colorTransform;
                colorYellow.color = 0xFFFF00;
                healthBar.transform.colorTransform = colorYellow;
            }else if(s_hits == 33 || s_hits == 34)
            {
                var colorRed:ColorTransform = healthBar.transform.colorTransform;
                colorRed.color = 0xFF0000;
                healthBar.transform.colorTransform = colorRed;
            }


            s_score -= value;
            score.text = String("Score: \n"+s_score);
            trace(s_hits+"I Hits");

        }


        public function updateScore(value:Number) : void
        {
            s_score += value;
            score.text = String("Score: \n"+s_score);
            trace(s_hits+"I Score");

        }

        public function loop(e:Event)
        {
            if(s_hits == 99 || s_hits == 98)
            {
                this.dispatchEvent(new Event('gameOver', true));
                this.dispatchEvent(new Event('gameO', true));
                removeEventListener(Event.ENTER_FRAME, loop);
            }
        }



    }

}

Weapons.as:

package Etys
{

    import flash.display.MovieClip;
    import flash.display.Stage;
    import com.senocular.utils.KeyObject;
    import flash.ui.Keyboard;
    import flash.events.Event;
    import flash.utils.Timer;
    import flash.events.TimerEvent;

    public class Weapons extends MovieClip
    {

        private var stageRef:Stage;
        private var key:KeyObject;
        private var speed:Number = 2;
        private var vx:Number = 0;
        private var vy:Number = 0;
        private var friction:Number = 0.93;
        private var maxspeed:Number = 8;
        private var target:Stinger;
        public var score:Score;


        private var fireTimer:Timer; 
        private var canFire:Boolean = true;
        private var stopIt:Boolean = false;

        public function Weapons(stageRef:Stage)
        {

            this.stageRef = stageRef;


            score = new Score(stageRef);

            addChild(score);

            score.addEventListener('gameO', lostGame, false, 0, false);
            addChild(score);
            key = new KeyObject(stageRef);


            fireTimer = new Timer(200, 1);
            fireTimer.addEventListener(TimerEvent.TIMER, fireTimerHandler, false, 0, true);

            addEventListener(Event.ENTER_FRAME, loop, false, 0, true);


        }

        public function loop(e:Event) : void
        {

            if (key.isDown(Keyboard.A))
            {
                vx -= speed;
            }else if (key.isDown(Keyboard.D))
            {
                vx += speed;
            }else{
                vx *= friction;
            }
            if (key.isDown(Keyboard.W))
            {
                vy -= speed;
            }else if (key.isDown(Keyboard.S))
            {
                vy += speed;
            }else{
                vy *= friction;
            }
            if (key.isDown(Keyboard.SPACE))
            {
                fireBullet();
            }


            //update position
            x += vx;
            y += vy;

            //speed adjustment
            if (vx > maxspeed)
            {
                vx = maxspeed;
            }else if (vx < -maxspeed)
            {
                vx = -maxspeed;
            }
            if (vy > maxspeed)
            {
                vy = maxspeed;
            }else if (vy < -maxspeed)
            {
                vy = -maxspeed;
            }
            //ship appearance
            rotation = vx;
            scaleX = (maxspeed - Math.abs(vx))/(maxspeed*4) + 0.75;

            //stay inside screen
            if (x > 537)
            {
                x = 537;
                vx = -vx;
            }
            else if (x < 13)
            {
                x = 13;
                vx = -vx;
            }

            if (y > 378)
            {
                y = 378;
                vy = -vy;
            }
            else if (y < 216)
            {
                y = 216;
                vy = -vy;
            }


        }


        public function lostGame(e:Event)
        {
            trace("bash");
            fireTimer.stop();
            fireTimer.reset();
            canFire = false;
            fireTimer.removeEventListener(TimerEvent.TIMER, fireTimerHandler);
            removeEventListener(Event.ENTER_FRAME, loop);   

        }

        private function fireBullet() : void
        {
            //if canFire is true, fire a bullet
            //set canFire to false and start our timer
            //else do nothing.
            if (canFire)
            {
                stageRef.addChild(new LaserBlue(stageRef, x + vx +15, y - 10));
                stageRef.addChild(new LaserBlue2(stageRef, x + vx -15, y - 10));
                canFire = false;
                fireTimer.start();
            }

        }

        //HANDLERS

        private function fireTimerHandler(e:TimerEvent) : void
        {
            //timer ran, we can fire again.
            canFire = true;
        }

        public function hitShip() : void
        {
            dispatchEvent(new Event("hitShipe"));
        }
        public function takeHit() : void
        {
            dispatchEvent(new Event("hit"));
        }

    }

}

エンジン:

  package Etys
{
    import flash.display.MovieClip;
    import flash.display.Stage;
    import flash.events.MouseEvent;
    import flash.events.Event;
    import flash.events.TimerEvent;
    import flash.media.SoundChannel;
    import flash.utils.Timer;
    import flash.display.*;


    public class Engine extends MovieClip
    {


        private var numStars:int = 80;
        private var numAsteroids:int = 4;

        public static var enemyList:Array = new Array();
        public static var enemyListFatso:Array = new Array();

        private var ourShip:Weapons;

        private var quality:qualityButton;
        private var score:Score;

        public function Engine() : void
        {



                ourShip = new Weapons(stage);
                stage.addChild(ourShip);
                ourShip.x = stage.stageWidth / 2;
                ourShip.y = stage.stageHeight / 2;
                ourShip.addEventListener("hit", shipHit, false, 0, true);
                ourShip.addEventListener("hitShip", Hit, false, 0, true);


                for (var i:int = 0; i < numStars; i++)
                {
                    stage.addChildAt(new Star(stage), stage.getChildIndex(ourShip));
                }

                for (var a:int = 0; a < numAsteroids; a++)
                {
                    stage.addChildAt(new Asteroids(stage), stage.getChildIndex(ourShip));
                }
                quality = new qualityButton(stage);             
                stage.addChild(quality);

                score = new Score(stage);//create our HUD
                stage.addChild(score);
                score.addEventListener("gameOver", lostGame, false, 0, true);

                //running a loop now.... so we can keep creating enemies randomly.
                addEventListener(Event.ENTER_FRAME, loop, false, 0, true);

        }




        private function lowQ(e:MouseEvent)
        {
            stage.quality = StageQuality.LOW;
            trace("Low");
        }

        private function highQ(e:MouseEvent)
        {
            stage.quality = StageQuality.BEST;
            trace("High");
        }


        //our loop function
        private function loop(e:Event):void
        {

            if (Math.floor(Math.random() * 90) == 4)
            {
                var enemyFatso:Fatso = new Fatso(stage,ourShip);

                enemyFatso.addEventListener(Event.REMOVED_FROM_STAGE, removeEnemyFatso, false, 0, true);
                enemyFatso.addEventListener("killed", enemyFatsoKilled, false, 0, true);
                enemyFatso.addEventListener("enemyC", enemyCrash, false, 0, true);
                enemyListFatso.push(enemyFatso);
                stage.addChild(enemyFatso);


            }
            //run if condition is met.
            if (Math.floor(Math.random() * 90) == 5 || Math.floor(Math.random() * 90) == 6)
            {
                //create our enemy
                var enemy:Stinger = new Stinger(stage,ourShip);

                enemy.addEventListener(Event.REMOVED_FROM_STAGE, removeEnemy, false, 0, true);
                enemy.addEventListener("killed", enemyKilled, false, 0, true);
                enemy.addEventListener("enemyC", enemyCrash, false, 0, true);
                enemyList.push(enemy);
                stage.addChild(enemy);
            }

        }
        private function enemyFatsoKilled(e:Event)
        {
            score.updateKills(1);
            score.updateScore(e.currentTarget.points);
        }

        private function enemyKilled(e:Event)
        {
            score.updateKills(1);
            score.updateScore(e.currentTarget.points);

        }

        private function enemyCrash(e:Event)
        {
            score.updateHits(2);
        }

        private function removeEnemyFatso(e:Event)
        {
            enemyListFatso.splice(enemyListFatso.indexOf(e.currentTarget), 1);
        }

        private function lostGame(e:Event)
        {
            dispatchEvent(new Event("removeShips", true));
            stage.removeChild(ourShip);
            ourShip.removeEventListener("hit", shipHit);
            ourShip.removeEventListener("hitShip", Hit);
            removeEventListener(Event.ENTER_FRAME, loop);   
        }

        private function removeEnemy(e:Event)
        {
            enemyList.splice(enemyList.indexOf(e.currentTarget), 1);
        }

        private function Hit(e:Event)
        {
            trace("lol");
        }
        private function shipHit(e:Event)
        {
            score.updateHits(1);
        }


    }

}
4

1 に答える 1

0

ActionScript 3 のイベントは、ほとんどの場合、かなり単純です。オブジェクトが Event をディスパッチし、Listener がそれを処理します。2 つの当事者がどのように相互作用するかを実際に示す非常に単純な例を次に示します。

イベント ディスパッチャ クラス

// By extending the EventDispatcher class, we can now dispatch events!  Note that
// Sprite and MovieClip both extend EventDispatcher through inheritance.
public class Dispatcher extends EventDispatcher {
    public function Dispatcher() {
        // Create a simple interval which will call the "dispatchTickleEvent" 
        // method every 1.5 seconds.
        setInterval(dispatchTickleEvent, 1500);
    }

    private function dispatchTickleEvent() {
        // Broadcast an Event of type TICKLE which other classes and listen 
        // out for. 
        dispatchEvent(new Event("TICKLE"));
    }
}

リスナー クラス

// Note that event listeners don't have to extend anything in order to listen 
// out for Events.
public class Listener {
    public function Listener() {
        // Create a new instance of the Dispatcher Class.
        var dispatcher : Dispatcher = new Dispatcher();

        // Here's where we add an EventListener to the Dispatcher instance.
        // This simply means that each time the dispatcher instances emits 
        // an Event of type "TICKLE", the "onDispatcherTickled" function will
        // be called.
        dispatcher.addEventListener("TICKLE", onDispatcherTickled);
    }

    // This is the event handler method which will be called whenever our dispatcher
    // instance broadcasts an Event of type "TICKLE".
    private function onDispatcherTicked(event : Event) : void {
        trace("The dispatcher was Tickled!");
    }
}

これは、クラスが互いに通信するための疎結合の方法を提供するため、非常に強力なシステムです。疎結合とは、イベントがブロードキャストされた原因をリスナー クラスが認識していないことを意味します (上記の場合、間隔によって自動的に発生しました)。Listener クラスを変更せずに動作を変更できるようにします。たとえば、ユーザーがマウスをクリックしたときにのみ Tickle イベントがディスパッチされるようにすることができます。

ここまでは非常に単純ですが、イベントには、表示リストの DisplayObjects がバブリングまたはイベント伝播として知られるイベントのディスパッチを開始するときに作用する、かなり興味深い癖が 1 つあります。

基本的な概念は、アクティブ表示リストに追加された DisplayObject (スプライトなど) がイベントをディスパッチする場合、そのイベントは、最終的にステージに到達するまで、その「親」DisplayObject のそれぞれを通過 (バブル) するというものです。実行中のイベント バブリングの優れた例が、Ruben Swieringa のブログ に示されています。記事の一番下までスクロールすると、イベント バブリングの動作を示す Flash ムービーが表示されます。

以下は、実際のイベント バブリングの非常に単純なコード例です。

イベント ディスパッチャー クラス。今回はバブルするイベントをディスパッチします。

// Note that we have to extend Sprite in order to be added to the Display List,
// but as mentioned before, Sprite itself extends EventDispatcher further down
// its inheritance tree.
public class Dispatcher extends Sprite {
    public function Dispatcher() {
        // The interval will call dispatchTickleEvent every 1.5 seconds.
        setInterval(dispatchTickleEvent, 1500);
    }

    private function dispatchTickleEvent() {
        // Dispatch the Tickle Event, but this time notice how we pass true as 
        // the second argument when constructing the new Event() instance, this
        // tells the Event that it should Bubble up the Display List.  All of
        // the "internal" Flash Event which are dispatched automatically, such as
        // MouseEvent.CLICK, Event.ENTER_FRAME, etc are all set to bubble by default.
        dispatchEvent(new Event("TICKLE", true));
    }
}

表示リストも設定する Listener クラス

public class Listener {
    public function Listener(stage : Stage) {
        // Create the Dispatcher instance.
        const dispatcher : Dispatcher = new Dispatcher();

        // Add the Dispatcher Instance to the Display List by adding it as a
        // child of the Stage.
        stage.addChild(dispatcher);

        // Now we add the EventListeners, but instead of listening directly to
        // the Dispatcher instance, like we did last time, we will instead listen
        // for the Tickle event on the Stage.
        stage.addEventListener("TICKLE", onTickleEvent);
    }

    private function onTickleEvent(event : Event) : void {
        trace("Someone was tickled! :)");
    }
}

そのため、すべてのクラス インスタンスが表示リストに追加する表示オブジェクトである場合、ディスパッチされたイベントを表示リストにバブルアップさせてから、イベント リスナーをステージに追加するだけで済みます。

それが役立つことを願っています!

于 2011-05-08T16:23:01.557 に答える