DispatchEvent получает только мой основной класс (Engine.as), а не класс кораблей (Weapons.as).

В настоящее время я пытаюсь создать игру, но теперь проблема в том, что, когда я отправляю событие, его подхватывает только мой основной класс (движок). Я хочу, чтобы мое Weapons.as тоже подобрало его. Мой основной класс - Engine.as (относится к классу stage), а мой weapon.as - это корабль. Я отправляю событие из класса Score.as.

Основная проблема в том, что мой Weapons.as не принимает ни событие «gameO», ни событие «gameOver», которое отправляет score.as. Другое дело, что если я установил if (s_hp == 100) (это то, с чего он начинается), моему Weapons.as удается получить отправленное событие, но только тогда ...

Чтобы быть более конкретным, я хочу / должен передать событие из Score.as через Weapons.as в мой основной класс Engine.as. EventListener в Weapons.as должен поднять его и удалить корабль и сделать его неспособным стрелять, а затем передать событие дальше классу Engine.as, который удаляет почти все со сцены.

Оцените любую помощь, которую я получаю! :)

РЕДАКТИРОВАТЬ: полные классы

Score.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);
        }


    }

}

person Kasper    schedule 08.05.2011    source источник
comment
Можете ли вы опубликовать весь класс, а не только методы класса.   -  person Taurayi    schedule 08.05.2011
comment
Отредактировал пост, теперь добавил весь класс для всех троих   -  person Kasper    schedule 08.05.2011


Ответы (1)


События в ActionScript 3 по большей части довольно просты. Объект отправляет событие, и прослушиватель будет его обрабатывать, вот очень простой пример этого, показывающий, как взаимодействуют две стороны:

Класс диспетчера событий

// 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 в списке отображения начинают отправку событий, известных как восходящая цепочка или распространение событий.

Основная концепция заключается в том, что если DisplayObject (например, Sprite), который был добавлен в Active Display List, отправляет событие, это событие будет проходить (пузыриться) через каждый из своих «родительских» DisplayObject, пока наконец не достигнет Stage. Прекрасный пример всплытия событий в действии - показан в блоге Рубена Свиринги. Если вы прокрутите статью до конца, вы увидите 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));
    }
}

Класс слушателя, который также устанавливает список отображения

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! :)");
    }
}

Итак, если все ваши экземпляры класса являются отображаемыми объектами, которые вы добавляете в список отображения, это должно быть так же просто, как сделать отправленные события всплывающим в списке отображения и затем добавить ваших прослушивателей событий в рабочую область.

Надеюсь, это поможет!

person JonnyReeves    schedule 08.05.2011
comment
Спасибо за хороший, длинный, подробный ответ. Заставил меня немного лучше понять весь процесс dispatchEvent и его сбор. Но проблема в том, что я пробовал большинство из этих вещей. My Weapons.as, похоже, не замечает, что я отправляю событие в моем Score.as, даже несмотря на то, что мой Engine.as подбирает его. Это потому, что класс Engine.as является классом сцены? .. - person Kasper; 08.05.2011
comment
Мне нужно, чтобы игра прошла через мой Weapons.as, а ЗАТЕМ дальше - через Engine.as. Было бы здорово, если бы кто-нибудь мог объяснить еще немного! :) - person Kasper; 09.05.2011