如何定义一个孩子应该只出现在一个场景中?

时间:2015-06-03 16:13:53

标签: actionscript-3 flash state

我们正在制作太空影响游戏。这是我们的3个课程。我们的问题是,当我们创建InimigoNoite时,它们会出现在整个游戏中(菜单,其他级别等),而不是仅出现在我们想要的场景中。我们应该如何限制孩子只出现在CenárioCidade? 我们尝试使用gotoandPlayaddChildAt,并尝试创建不在Main类中的Inimigo,但是在Inimigo类本身中,但它根本没有出现。有人可以帮助我们吗?非常感谢你!

KEY.as

package {

  import flash.display.Stage;
  import flash.events.Event;
  import flash.events.KeyboardEvent;

    public class Key {

        private static var initialized:Boolean = false;
        private static var keysDown:Object = new Object();

        public static function initialize(stage:Stage) {
            if (!initialized) {
                stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
                stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased);
                stage.addEventListener(Event.DEACTIVATE, clearKeys);

                initialized = true;
            }
        }


        public static function isDown(keyCode:uint):Boolean 
        {
            return Boolean(keyCode in keysDown);
        }


        private static function keyPressed(event:KeyboardEvent):void {
            keysDown[event.keyCode] = true;
        }


        private static function keyReleased(event:KeyboardEvent):void {
            if (event.keyCode in keysDown) {
                delete keysDown[event.keyCode];
            }
        }

        private static function clearKeys(event:Event):void {

            keysDown = new Object();
        }
    }
} 

INIMIGO NOITE.as

package{

    import flash.display.MovieClip;
    import flash.events.Event;
    import flash.utils.Timer;

    public class InimigoNoite extends MovieClip{

        var speed:Number;
        static var list:Array = new Array();
        var balaTimer: Timer;

        function InimigoNoite(){

            list.push(this);
            this.x = 1160;
            this.y = 150 + (450-150) * Math.random();
            speed = Math.random()*5 + 5;
            addEventListener("enterFrame", enterFrame);
            var intervalo: Number = Math.random()*500 + 1000;
            balaTimer = new Timer(intervalo);
            balaTimer.addEventListener("timer", bala);
            balaTimer.start();

        }

        function enterFrame (e:Event){

            this.x -= speed;
            if(this.x < -100){
                matar();
                return;
            }

            if(this.hitTestObject(SpaceImpact.navecnoite)){
                matar();
            }
        }

        function matar(){

            var explosao = new ExplosaoNoite();
            stage.addChild(explosao);
            explosao.x = this.x;
            explosao.y = this.y;

            balaTimer.stop();
            balaTimer.removeEventListener("timer",bala);

            removeEventListener("enterFrame", enterFrame);
            stage.removeChild(this);

            for(var i in list){
                if(list[i] == this){
                    delete list[i];
                }
            }
        }

        function bala(e:Event){

            var b = new BalaInimigo();
            b.x = this.x -50;
            b.y = this.y;
            stage.addChild(b);
        }
    }
}

MAIN.as

package{

    import flash.display.MovieClip;
    import flash.events.Event;
    import flash.utils.Timer;

    public class SpaceImpact extends MovieClip{

    static var navecnoite:MovieClip;
    var inimigoNoiteTimer:Timer;

        function SpaceImpact(){
            Key.initialize(stage);
            inimigoNoiteTimer = new Timer(8000);
            inimigoNoiteTimer.addEventListener("timer", criaInimigo);
            inimigoNoiteTimer.start();
        }

        function criaInimigo(e:Event){
            var inimigo = new InimigoNoite();
            stage.addChild(inimigo);
            addChildAt(inimigo, 3);         
        } 
    }
}

2 个答案:

答案 0 :(得分:1)

你永远不会停止计时器。所以你的inimigo每8秒创建并添加一次。 在criaInimigo中停止计时器和/或使用timerComplete事件

 function SpaceImpact(){
    Key.initialize(stage); 
    inimigoNoiteTimer = new Timer(8000,1);
    inimigoNoiteTimer.addEventListener(TimerEvent.TIMER_COMPLETE, criaInimigo);
    inimigoNoiteTimer.start();
}

function criaInimigo(e:Event){
    //inimigoNoiteTimer.stop();//only needed if you use the 'timer'-Event
    var inimigo = new InimigoNoite();
    stage.addChild(inimigo);
    addChildAt(inimigo, 3);         
} 

答案 1 :(得分:1)

当应用程序启动时,您每8秒创建一个新的InimigoNoite。由于您要将它们添加到stage,因此它们会显示在时间轴上的所有内容之上。

问题(除了在应用程序启动时创建它们并且永不停止计时器),当您通过代码使用addChild时,该子项将保留在屏幕上,直到通过removeChild明确删除它(或其中一个父母是 - 但由于父母stage不会发生)。

我看到你在InimigoNoite类中有一个可能会删除它的命中测试,但我没有看到你删除它的任何地方(所以如果命中测试永远不会发生,它将永远不会无论场景如何都从舞台上移除。

似乎问题的解决方案是关于如何构建应用程序的更多建议。

请勿使用场景。

您最好的选择是为游戏的每个不同状态创建一个类文件。所以像这样的基本例子:

  1. 主菜单状态
  2. 游戏状态(包含所有级别的1个游戏状态,或每个级别的一个状态 - 或两者 - 取决于级别之间功能的变化)
  3. Game Over State
  4. 让您的游戏状态类文件扩展为SpriteMovieClip,如果您愿意,您甚至可以在flash专业版中创建一个新的MovieClip并将该类附加到该文件中(从而能够删除时间线上的视觉资产。)

    那么你的Main类将负责管理状态(以及任何其他对应用程序来说是全局的)

    package{
    
        import flash.display.MovieClip;
        import flash.events.Event;
    
        public class SpaceImpact extends MovieClip {
    
            private var menu:Menu; //Assumes you have a Menu.as class file
            private var game:MainGame; //MainGame.as file
            private var gameOver:GameOver; //GameOver.as file
    
            public function SpaceImpact(){
                Key.initialize(stage);
                goMenu();
            }
    
            public function goMenu(e:Event = null):void {
                removeAll();
    
                menu = new Menu();
                addChild(menu);
                menu.addEventListener(Event.COMPLETE, startGame,false,0,true);
            }
    
            private function removeMenu():void {
                if(menu){
                    if(menu.parent) removeChild(menu); //remove it from the screen
                    menu = null;
                }
            }
    
            public function startGame(e:Event = null):void {
                removeAll();
    
                game = new MainGame();
                addChild(game);
                game.addEventListener(Event.COMPLETE, gameOver,false,0,true);
            }
    
            private function removeGame():void {
                if(game){
                    if(game.parent) removeChild(game); //remove it from the screen
                    game = null;
                }
            }
    
            public function gameOver(e:Event = null):void {
                removeAll();
    
                gameOver = new GameOver();
                addChild(gameOver);
                gameOver.addEventListener(Event.COMPLETE, goMenu,false,0,true);
            }
    
            private function removeGameOver():void {
                if(gameOver){
                    if(gameOver.parent) removeChild(gameOver); //remove it from the screen
                    gameOver = null;
                }
            }
    
            private function removeAll():void {
                removeGameOver();
                removeMenu();
                removeGame();
            }
        }
    }
    

    然后,您的游戏状态例如: 的 MainGame.as

    package{
    
        import flash.display.MovieClip;
        import flash.events.Event;
        import flash.utils.Timer;
    
        public class MainGame extends MovieClip {
    
            private var inimigoNoiteTimer:Timer;
    
            public function MainGame() {
                this.addEventListener(Event.ADDED_TO_STAGE, addedToStage, false, 0, true); //don't do anything until this object has been added to the screen
            }
    
            private function addedToStage(e:Event):void {
                this.removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
    
                //start spawning
                inimigoNoiteTimer = new Timer(8000);
                inimigoNoiteTimer.addEventListener("timer", criaInimigo);
                inimigoNoiteTimer.start();
            }
    
            function criaInimigo(e:Event){
                var inimigo = new InimigoNoite();
                addChild(inimigo);       
            } 
    
            //when whatever happens that makes your game finished
            function gameComplete():void {
                dispatchEvent(new Event(addEventListener.COMPLETE));
            }
        }
    }