0

我目前正在尝试制作游戏,但现在的问题是,当我 dispatchEvent 时,只有我的主类将其拾取(引擎)。我希望我的 Weapons.as 也能把它捡起来。我的主要课程是Engine.as(分配给舞台课程),而我的武器是船。我从一个名为 Score.as 的类中分派事件。

主要问题是我的 Weapons.as 没有接收到 score.as 调度的“gameO”或“gameOver”事件。另一件事是,如果我设置 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);
            }
        }



    }

}

武器.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 中的事件都相当简单。一个对象分派一个事件,一个监听器将处理它,下面是一个非常简单的例子,它实际上展示了两方如何交互:

事件调度程序类

// 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 Class不知道是什么原因导致Event被广播(在上面的例子中,它是由间隔自动引起的);这样就可以修改行为而无需更改 Listener 类 - 例如,我们可以使 Tickle 事件仅在用户单击鼠标时才被调度。

到目前为止,一切都很简单,但是当显示列表上的 DisplayObject 开始调度称为冒泡或事件传播的事件时,事件有一个相当有趣的怪癖开始发挥作用。

基本概念是,如果已添加到活动显示列表的 DisplayObject(例如 Sprite)调度事件,则该事件将通过(冒泡)通过其每个“父”显示对象,直到最终到达舞台。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));
    }
}

侦听器类,它还设置了显示列表

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 回答