AS3 - 使用removeChild()函数删除MovieClip的特定实例

时间:2014-03-04 06:14:45

标签: actionscript-3 flash

我正在为一项任务开发Flash游戏。这是一种非常标准的导弹防御型游戏,在中心有一个旋转导弹发射器向上方的轰炸机发射。导弹和​​轰炸机本身运作正常,但当我试图让两者进行互动时,我遇到了一个问题。具体来说,当导弹击中轰炸机时,我希望将导弹和轰炸机的特定实例从屏幕上移除并移除各自的事件监听器,但我尝试过的所有内容都失败了,我似乎无法想象如何做到这一点。

以下是我正在使用的主要,轰炸机和导弹课程:

主要类别:

    package {
    import flash.display.Stage;
    import flash.display.MovieClip;
    import flash.events.Event;
    import flash.events.MouseEvent;

    public class Main extends MovieClip {

        public var background:Background;
        public var launcher:Launcher;
        public var mount:Mount;
        public var missile:Missile;
        public var salvo:Array = [];
        public var bomber:Bomber;
        public var squadron:Array = [];



        /* 
         * This function sets up the permanent items (items that remain on-stage for
         * the duration of the game) and adds event listeners that call functions to
         * add non-permanent items to the stage
         */

        public function Main() {

            // Add background to the stage
            background = new Background(stage);
            stage.addChild(background);
            stage.setChildIndex(background, 0);

            // Add the rotating launcher to the stage
            launcher = new Launcher(stage);
            stage.addChild(launcher);
            stage.setChildIndex(launcher, 1);

            // Add the static mount to the stage (on top of launcher)
            mount = new Mount(stage);
            stage.addChild(mount);
            stage.setChildIndex(mount, 2);

            // Call loop() every new frame
            stage.addEventListener(Event.ENTER_FRAME, loop);

            // Call fire() every time the mouse is clicked
            stage.addEventListener(MouseEvent.CLICK, fire);
        }



        /*
         * This function runs every time the program enters a new frame, or 60 times
         * every second.  Each time this function runs, it tries to add a new Bomber
         * to the squadron array and checks to see if there are any Missiles or
         * Bombers currently in their respective arrays (and if so, calls a function
         * to make them move).
         */

        public function loop(evt:Event) {

            // If the random number generated by Math.random() is less than
            // waveLimiter, create a new Bomber and add it to the squadron array.
            if(Math.random() < 0.02 /* Change this number to change how fast bombers spawn */) {
                bomber = new Bomber(stage);
                bomber.addEventListener(Event.REMOVED_FROM_STAGE, removeBomber); // If the Bomber is removed from the stage, call removeBomber() to remove its event handler.
                squadron.push(bomber);
                stage.addChild(bomber);
                stage.setChildIndex(bomber, 1);
            }

            // Check to see if there is at least one missile in the salvo array, and
            // if so, call Missile.velocity() to make it move.
            if(salvo.length > 0) {
                for(var i:int = salvo.length - 1; i >= 0; i--) {
                    salvo[i].velocity();
                }
            }

            // Check to see if there is at least one bomber in the squadron array,
            // and if so, call Bomber.fly() to make it move.
            if(squadron.length > 0) {
                for(var j:int = squadron.length - 1; j >= 0; j--) {
                    squadron[j].fly();
                }
            }
        }



        /*
         * This function checks for a mouse click, and if it detects one, creates a 
         * new Missile and adds it to the salvo array.
         */

        public function fire(evt:MouseEvent) {

            missile = new Missile(stage, launcher.rotation);
            missile.addEventListener(Event.REMOVED_FROM_STAGE, removeMissile); // If the Missile is removed from the stage, call removeMissile() to remove its event handler. 
            salvo.push(missile);
            stage.addChild(missile);
            stage.setChildIndex(missile, 1);
        }



        /*
         * This function removes the EVENT LISTENER for the current Missile instance.
         * It does not remove the Missile itself from the stage.
         */

        public function removeMissile(evt:Event):void {
            evt.currentTarget.removeEventListener(Event.REMOVED_FROM_STAGE, removeMissile);
            salvo.splice(salvo.indexOf(evt.currentTarget), 1);
        }



        /*
         * This function removes the EVENT LISTENER for the current Bomber instance.
         * It does not remove the Bomber itself from the stage.
         */

        public function removeBomber(evt:Event) {
            evt.currentTarget.removeEventListener(Event.REMOVED_FROM_STAGE, removeBomber);
            squadron.splice(squadron.indexOf(evt.currentTarget), 1);
        }
    }
}

轰炸机课程:

    package  {

    import flash.display.Stage;
    import flash.display.MovieClip;

    public class Bomber extends MovieClip {

        var stageInstance:Stage;
        var randomNumber:Number = Math.round(Math.random() * 1);

        public function Bomber(stageInstance:Stage):void {

            this.stageInstance = stageInstance;
            if(randomNumber == 1) {
                x = -39;
                y = (Math.random() * 120) + 30;
            }

            else if(randomNumber == 0) {
                scaleX *= -1;
                x = 679;
                y = (Math.random() * 120) + 30;
            }
        }

        public function fly():void {

            if(randomNumber == 1) {
                x = x + 4;
            }

            else if(randomNumber == 0) {
                x = x - 4;
            }

            if(x > 680 || x < -40) {
                this.parent.removeChild(this);
            }
        }
    }
}

导弹类:

package {

    import flash.display.Stage;
    import flash.display.MovieClip;

    public class Missile extends MovieClip {

        var stageInstance:Stage;
        var velocityX:Number;
        var velocityY:Number;
        var speed:Number = 10;
        var rotationRadians:Number;
        var rotationDegrees:Number;

        public function Missile(stageInstance:Stage, rotationDegrees:Number):void {
            this.stageInstance = stageInstance;
            x = 320;
            y = 363;
            rotation = rotationDegrees;
            rotationRadians = rotationDegrees * Math.PI / 180;
        }

        public function velocity():void {
            velocityX = Math.cos(rotationRadians) * speed;
            velocityY = Math.sin(rotationRadians) * speed;

            x += velocityX;
            y += velocityY;

            if(x > 640 || x < 0 || y > 480 || y < 0) {
                this.parent.removeChild(this);
            }   
        }
    }
}

在Main Class中,我尝试添加这样的东西:

if(squadron.length > 0) {
    for(var j:int = squadron.length - 1; j >= 0; j--) {
        squadron[j].fly();

        if(salvo.length > 0) {
            if(missile.hitTestObject(squadron[j])) {
                this.parent.removeChild(this);
            }
        }
    }
}

但没有运气。我也试过使用trace语句,它甚至没有给我一个输出,这让我觉得它甚至都没有检测到碰撞。有什么想法吗?

3 个答案:

答案 0 :(得分:0)

更新:我添加了一些细节。

this表示调用该函数的对象。所以 在主类中编写时,this.parent.removeChild(this);没有任何意义。 当你在导弹类中编写它时,this是导弹实例,而this.parent是舞台。

尝试在您发布的最后一个代码示例中将其替换为:stage.removeChild(missile),然后立即调用removeMissile()。

答案 1 :(得分:0)

尝试使用stage.removeChild而不是this.parent.removeChild(this);

答案 2 :(得分:0)

实际上你的代码中有很多问题。首先,您不需要使用Stage。您可以使用主容器Main。将对象添加到显示列表时,请勿在{{1​​}}之后执行。在你的代码中它没有任何意义。您也不需要任何长度条件。并通过扩展Sp​​rite创建轻量级对象,而不是MovieClip。

你的循环代码,用于导弹:

setChildIndex