简体   繁体   中英

AS3 How to remove objects from the stage from various classes

So I'm Creating a game that generates different types of fish. I have the main class initilize everything then the fish are generated with another class. I then have another class listen for when they are added to the stage that controls their movement. After the fish leaves the scene I have gotten them to be deleted but I cannot get them all to be deleted once the fish is clicked. I have a listener that gets when a fish is clicked but I am having trouble deleting all the other generated fish so that I can load the fish information.

I probably have tons of problems but here is my Main class:

 package 
{

    import flash.display.MovieClip;
    import flash.display.SimpleButton;
    import flash.display.*;
    import flash.events.*;
    import flash.ui.*;
    import Crappie;
    /*import Bass;
    import Bluegill;
    import LongGar;
    import Muskellunge;
    import Perch;
    import PumpkinSeed;
    import ShortGar;
    import SpotGar;*/
    import GenerateFish;

    public class FishGame extends MovieClip
    {

        private var randomFish:Number;

        public function FishGame() //First function to be called
        {
            startMenu();
        }


        public function startMenu() //Loads the start menu
        {
            gotoAndStop("Start Menu");
            StartButton.addEventListener(MouseEvent.CLICK, gotoStartGame);
        }

        private function gotoStartGame(evt:MouseEvent) //links to the start of th game
        {
            StartButton.removeEventListener(MouseEvent.CLICK, gotoStartGame);
            gotoAndStop("Game");
            game();

        }

        public function game() /generates fish
        {
            var genFish:GenerateFish = new GenerateFish();
            this.addChild(genFish);
            var genFish2:GenerateFish = new GenerateFish();
            this.addChild(genFish2);
        }

//This is where I need help. All the fish are children of other class. I tried deleting them in their own class but it seems like it would work best if it was in this class but I'm having trouble calling this class.

        public function removeFish()
        {
            trace("Here");
        }
    }
}

Here is the generating fish class:

    package  {

        import flash.display.MovieClip;
        import flash.events.*;
        import flash.display.*;
        import Crappie;
        //import Bass;
        //import Bluegill;
        //import LongGar;
        //import Muskellunge;
        //import Perch;
        //import PumpkinSeed;
        //import ShortGar;
        //import SpotGar;
        import FishGame;

        public class GenerateFish extends MovieClip {

            private var randomFish:Number;


            public function GenerateFish()  //When this is added via addchild it adds a fish
            {
                this.addEventListener(Event.ADDED_TO_STAGE, addFish, false, 0, true);
                //addFish();
            }

            private function addFish(e:Event) //adds fish to scrence
            {                       
                this.removeEventListener(Event.ADDED_TO_STAGE, addFish);
                randomFish = Math.floor(Math.random() * 2);
                randomFish = 0; //for testing purposes
                    switch(randomFish) 
                    { 
                        case 0: 
                            var crappie:Crappie = new Crappie();
                            this.addChild(crappie); //Calls the crappy funciton
                            break;
                        case 1: 
                            var longgar:LongGar = new LongGar();
                            this.addChild(longgar);
                            break; 
                        case 2: 
                            var bluegill:Bluegill = new Bluegill();
                            this.addChild(bluegill);
                            break; 
                        case 3: 
                            var spotgar:SpotGar = new SpotGar();
                            this.addChild(spotgar);
                            break; 
                        case 4: 
                            var muskellunge:Muskellunge = new Muskellunge();
                            this.addChild(muskellunge);
                            break; 
                        case 5: 
                            var pumpkinseed:PumpkinSeed = new PumpkinSeed();
                            this.addChild(pumpkinseed);
                            break; 
                        case 6: 
                            var bass:Bass = new Bass();
                            this.addChild(bass);
                            break;
                        case 7: 
                            var perch:Perch = new Perch();
                            this.addChild(perch);
                            break; 
                        case 8: 
                            var pike:Pike = new Pike();
                            this.addChild(pike);
                            break; 
                        default: 
                            break; 
                    }

            }


        }

    }

And here is one of the specific fish classes:

package 
{
    import flash.display.MovieClip;
    import flash.events.*;
    import flash.display.*;
    import FishGame;
    import GenerateFish;


    public class Crappie extends MovieClip
    {

        private var Speed:Number;
        private var randomBoolean:Boolean = (Math.random() > .5) ? true : false;
        private var fishOnScreen:Boolean = false;
        //public var remFish:FishGame = new FishGame();


        public function Crappie() //Adds event listeners to control the fish
        {
            this.addEventListener(Event.ADDED_TO_STAGE, Setup, false, 0, true);
            this.addEventListener(MouseEvent.CLICK, GoToFishInfo);
            fishOnScreen =true;

        }

        public function GoToFishInfo(evt:MouseEvent):void //When fish is clicked Info pops up. It is here i want every fish to be deleted.
        {   
            this.removeEventListener(Event.ADDED_TO_STAGE, Setup);

            /*while (MovieClip(root).numChildren >= 1) //What I tried to delete all objects
            {
                MovieClip(root).removeChildAt(1);
            }*/
            var remFish:FishGame = new FishGame(); //Creates  The SWF file file:///FishGame/classes/FishGame.swf contains invalid data.
            remFish.removeFish();

            MovieClip(root).gotoAndStop("FishInfo", "Scene 1");
            var crappieinfo:CrappieInfo = new CrappieInfo();
            stage.addChild(crappieinfo);
            crappieinfo.x = 512;
            crappieinfo.y = 384;
            crappieinfo.alpha = 100;

        }

        private function Setup(e:Event) //Setup the fish position and adds info for movement
        {
            var randomBoolean:Boolean = (Math.random() > .5) ? true : false;
            //true forwards
            //false is backwards
            if (randomBoolean)
            {
                this.x = 1030;
            }
            else
            {
                this.scaleX = -1;
                this.x = -10;
            }

            this.y = this.GetRandomYPosition();

            this.alpha = 100;

            this.addEventListener(Event.ENTER_FRAME, MoveCircle);
            Speed = GetRandomSpeed();
            if (randomBoolean)
            {
                Speed *= -1
            }
        }

        private function GetRandomSpeed():Number
        {

            return (Math.floor(Math.random() * 5) +5);
        }

        private function GetRandomYPosition():Number
        {
            //
            //basic formula: Math.floor(Math.random()*(1+High-Low))+Low; 
            //
            return (Math.floor(Math.random() * (650-this.height)) + 230);
        }

        public function MoveCircle(e:Event) //Moves the fish
        {

                if (fishOnScreen)
                {
                    this.x +=  Speed;
                    if (this.x >1024 || this.x < -10 || this.y >768 || this.y < 200) 
                    {
                        var genExtraFish:GenerateFish = new GenerateFish();
                        stage.addChild(genExtraFish);
                        this.parent.removeChild(this);
                        fishOnScreen = false;
                        this.removeEventListener(MouseEvent.CLICK, GoToFishInfo);

                    }
                }


        }
    }
}

Thanks I'd appreciate all the help I can get!

////////

//Edit//

////////

I have modified my main class to package

{

    import flash.display.MovieClip;
    import flash.display.SimpleButton;
    import flash.display.*;
    import flash.events.*;
    import flash.ui.*;
    import BaseFish;
    import GenerateFish;

    public class FishGame extends MovieClip
    {
        private var randomFish:Number;
        private var basefish:BaseFish = new BaseFish();

        public function FishGame()
        {
            startMenu();
        }


        public function startMenu()
        {
            gotoAndStop("Start Menu");
            StartButton.addEventListener(MouseEvent.CLICK, gotoStartGame);
        }

        private function gotoStartGame(evt:MouseEvent)
        {
            StartButton.removeEventListener(MouseEvent.CLICK, gotoStartGame);
            gotoAndStop("Game");
            basefish.StartFish();

        }       
    }
}

And I Created the basefish class as so:

package  
{
    import flash.display.MovieClip;
    import flash.events.*;
    import flash.display.*;
    import FishGame;

    public class BaseFish extends MovieClip 
    {
        public var FishOnScreen:Array = new Array(); 
        public var FishSpeed:Array = new Array();
        private var Speed:Number;
        private var randomBoolean:Boolean = (Math.random() > .5) ? true : false;
        public var NumFish:int = -1;
        private var randomFish:Number;

        public function BaseFish() 
        {           

        }

        public function StartFish()
        {
            addFish(5);
            this.addEventListener(Event.ENTER_FRAME, MoveCircle);
        }

        public function addFish(NumAdd:Number)
        {                       
            for (var i:Number = 0; i < NumAdd; i++)
            {
                randomFish = Math.floor(Math.random() * 2);
                randomFish = 0;
                switch(randomFish) 
                { 
                    case 0: 
                        var crappie:Crappie = new Crappie();
                        this.addChild(crappie);
                        crappie.addEventListener(MouseEvent.CLICK, GoToFishInfo);
                        FishOnScreen.push(crappie);
                        trace(FishOnScreen[1]);
                        Setup(crappie);
                        NumFish += 1;
                        break;
                    case 1: 
                        var longgar:LongGar = new LongGar();
                        this.addChild(longgar);
                        longgar.addEventListener(MouseEvent.CLICK, GoToFishInfo);
                        FishOnScreen.push(longgar);
                        Setup(longgar);
                        NumFish += 1;
                        break; 
                    case 2: 
                        var bluegill:Bluegill = new Bluegill();
                        this.addChild(bluegill);
                        bluegill.addEventListener(MouseEvent.CLICK, GoToFishInfo);
                        FishOnScreen.push(bluegill);
                        Setup(bluegill);
                        NumFish += 1;
                        break; 
                    case 3: 
                        var spotgar:SpotGar = new SpotGar();
                        this.addChild(spotgar);
                        spotgar.addEventListener(MouseEvent.CLICK, GoToFishInfo);
                        FishOnScreen.push(spotgar);
                        Setup(spotgar);
                        NumFish += 1;
                        break; 
                    case 4: 
                        var muskellunge:Muskellunge = new Muskellunge();
                        this.addChild(muskellunge);
                        muskellunge.addEventListener(MouseEvent.CLICK, GoToFishInfo);
                        FishOnScreen.push(muskellunge);
                        Setup(muskellunge);
                        NumFish += 1;
                        break; 
                    case 5: 
                        var pumpkinseed:Pumpkinseed = new Pumpkinseed();
                        this.addChild(pumpkinseed);
                        pumpkinseed.addEventListener(MouseEvent.CLICK, GoToFishInfo);
                        FishOnScreen.push(pumpkinseed);
                        Setup(pumpkinseed);
                        NumFish += 1;
                        break; 
                    case 6: 
                        var bass:Bass = new Bass();
                        this.addChild(bass);
                        bass.addEventListener(MouseEvent.CLICK, GoToFishInfo);
                        FishOnScreen.push(bass);
                        Setup(bass);
                        NumFish += 1;
                        break;
                    case 7: 
                        var perch:Perch = new Perch();
                        this.addChild(perch);
                        perch.addEventListener(MouseEvent.CLICK, GoToFishInfo);
                        FishOnScreen.push(perch);
                        Setup(perch);
                        NumFish += 1;
                        break; 
                    case 8: 
                        var pike:Pike = new Pike();
                        this.addChild(pike);
                        pike.addEventListener(MouseEvent.CLICK, GoToFishInfo);
                        FishOnScreen.push(pike);
                        Setup(pike);
                        NumFish += 1;
                        break; 
                    default: 
                        this.addChild(crappie);
                        crappie.addEventListener(MouseEvent.CLICK, GoToFishInfo);
                        FishOnScreen.push(crappie);
                        Setup(crappie);
                        NumFish += 1;
                        break; 
                }
            }
        }
        private function Setup(mc: MovieClip)
        {
            var randomBoolean:Boolean = (Math.random() > .5) ? true : false;
            //true forwards
            //false is backwards
            if (randomBoolean)
            {
                MovieClip(mc).x = 1030;
            }
            else
            {
                MovieClip(mc).scaleX = -1;
                MovieClip(mc).x = -10;
            }

            MovieClip(mc).y = GetRandomYPosition();

            MovieClip(mc).alpha = 100;

            FishSpeed[NumFish] = GetRandomSpeed();
            if (randomBoolean)
            {
                FishSpeed[NumFish] *= -1
            }
        }

        private function GetRandomSpeed():Number
        {

            return (Math.floor(Math.random() * 5) +5);
        }

        private function GetRandomYPosition():Number
        {
            //
            //basic formula: Math.floor(Math.random()*(1+High-Low))+Low; 
            //
            return (Math.floor(Math.random() * (650-this.height)) + 230);
        }

        public function MoveCircle(e:Event)
        {
            //trace(FishOnScreen.length);

                for (var i:Number = 0; i < FishOnScreen.length; i++)
                {
                    if (FishOnScreen[i]!=null)
                    {
                    MovieClip(FishOnScreen[i]).x +=  FishSpeed[i];
                    if (MovieClip(FishOnScreen[i]).x >1024 || MovieClip(FishOnScreen[i]).x < -10 || MovieClip(FishOnScreen[i]).y >768 || MovieClip(FishOnScreen[i]).y < 200) 
                    {
                        addFish(1);
                        this.removeChild(MovieClip(FishOnScreen[i]));
                        MovieClip(FishOnScreen[i]).removeEventListener(MouseEvent.CLICK, GoToFishInfo);
                        FishOnScreen.splice(i, 1);
                        FishSpeed.splice(i,1);

                    }
                    }
                    //else trace("null");
                }


        }

        public function GoToFishInfo(evt:MouseEvent):void
        {   
            dispose();
            MovieClip(root).gotoAndStop("FishInfo", "Scene 1");
            var crappieinfo:CrappieInfo = new CrappieInfo();
            stage.addChild(crappieinfo);
            crappieinfo.x = 512;
            crappieinfo.y = 384;
            crappieinfo.alpha = 100;

        }

        public function dispose():void
        {
            for (var i : int = this.numChildren-1 ; i >= 0 ; i--)
            {
                if(this.getChildAt(i) is MovieClip)
                {
                    this.removeChildAt(i);
                    MovieClip(FishOnScreen[i]).removeEventListener(Event.ADDED_TO_STAGE, Setup);
                    MovieClip(FishOnScreen[i]).removeEventListener(MouseEvent.CLICK, GoToFishInfo);
                }
            }
        }

    }

}

It doesn't give me any errors but it doesn't display any fish. If you could take a look at my updated code I would be grateful!

To make things better and avoid duplication of code, extend all your classes such as Crappie , Bass etc from a Base Class, call it BaseFish for example. You should create a dispose() method in this base class. That way this dispose method will be automatically available to all classes extending it. In fact, you can use this method to write common code at one place and avoid duplication.

Also, if you feel it suits the need, extend GenerateFish also from the base class, or create a similar method called dispose() in this class.

Then when you call your removeFish() method, you can call these dispose methods for your individual classes.

Create the method like this (this is just to get you started):

public function dispose():void
{
    for (var i : int = this.numChildren-1 ; i >= 0 ; i--)
    {
        if(this.getChildAt(i) is MovieClip)
        {
            this.removeChildAt(i);
        }
    }
}

This code removes every child which is a movie clip. You may also want to remove any Event Listeners which are added in your class inside this method.

Then, move your variables genFish and genFish2 to class variables, and not declare them inside your method game()

Now in your removeFish() method do this:

public function removeFish()
{
    genFish.dispose();
    genFish2.dispose();
}

Follow the same logic inside your GenerateFish class to dispose all the children as they will now be instances of the same base class.

Another thing, which could be very important from a performance perspective is the ENTER_FRAME event that you are adding. Notice that this event is being added to each instance that you create inside GenerateFish . So, every instance will have its own enter frame. Maybe it will work ok in your current situation as the number of instances may be less, but this approach is not scalable, and tomorrow if you have many instances, it will certainly hinder performance.

Ideally, you should try to have only one ENTER_FRAME event listener in your main class and use the handler to change things inside your child classes.

Hope this helps you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM