Search code examples
actionscript-3flash

AS3 || Using same function with different variables


I'm very new to AS3 and I'm trying to learn by experimenting in flash, by making a simple 2D farming game with very simple code.

I've made one crop field out of 6 that works, which is a movieclip with different frames for each fruit growing. For example, frame 1-5 is a strawberry growing where frame 5 is when it's ready to be picked, and then 6-10 is of carrots, etc

Is there a way for me to make it so that I don't have to write the exact same code for the next crop field, and instead change the variables in this code depending on which crop field you click on?

Here's an example of the code

if (field1.currentFrame == 1)
        {
            field1.nextFrame();
            infoText.text = "You've watered the crop. Let's wait and see how it turns out!";
            function plantStrawberry():void
            {
                field1.nextFrame();
                if (field1.currentFrame == 5)
                {
                    clearInterval(strawberryInterval);
                }
            }
            var strawberryInterval = setInterval(plantStrawberry,5000);
        }

pls no judgerino, as said, I'm very new to AS3, lol.


Solution

  • There are a few ways to go about being DRY (don't repeat yourself) with your code in this scenario. The best way, would be to learn to use classes. Classes are blueprints, and are made for these very scenarios.

    Here is an example of a simple class to do what you'd like. In Flash/Animate, go to file, then new, then 'ActionScript 3.0 Class' - give it a name of Crop.

    In the document that comes up, there should be some basic boilerplate code. Everything should wrapped in a package. The package tells flash where to find this class - so this example, leave it as is (just package {) and save this file in the same folder as your .fla. All functions need to be wrapped in a class declaration, this should be generated for you based off the name you put in (Crop). Next you'll see one function, that has the same name as the class. This is called a constructor, and this function runs whenever you create a new instance of this class. Since classes are blueprints, you create instances of them that are objects - those objects then get all the code you put in this class.

    So, to start, you should have this:

    package  {
        public class Crop {
            public function Crop() {
                // constructor code
            }
        }
    }
    

    Let's go ahead and put your code in. See the code comments for details:

    package  {
        //imports should go here
        import flash.display.MovieClip;
        import flash.events.Event;
        import flash.events.TimerEvent;
        import flash.utils.Timer;
    
        //lets make this class extend MovieClip - that means it will be a MovieClip in addition to everything else you add below
        public class Crop extends MovieClip {
    
            //instead of setInterval, use a timer - it's easier to manage and cleanup
            //in class files, variables and functions have access modifiers, that's what the public and private words are about
            //private means only this class can ever use the var/function
            private var timer:Timer;
    
            public function Crop() {
                //initialize the timer - have it tick every 5 seconds, and repeat 4 times (to move you from frame 1 - 5)
                timer = new Timer(5000, 4);
                //listen for the TIMER event (which is the tick) and call the function 'grow' when the timer ticks
                timer.addEventListener(TimerEvent.TIMER, grow);
            }
    
            //a function that starts the timer ticking
            public function startGrowing():void {
                timer.start();
            }
    
            //this function is called every timer tick.
            private function grow(e:Event):void {
                this.nextFrame(); //go to the next frame of your crop
            }
        }
    }
    

    Save the file. Now that you have this class, you need to attach it to your library assets so they all get this functionality.

    In the library panel, for each of your crop objects, right click (or ctrl+click on Mac) and go to properties. In the properties, click advanced, and give it a unique class name (for instance Strawberry). Then in the base class field, put Crop (the class we just made). Repeat for the others.

    enter image description here

    Now on your timeline, when you want a crop to start growing, you can do:

    field1.startGrowing();  //assuming your instance `field1` is one of the crops that you assigned the base class `Crop` to
    

    Hopefully this gives an entry point into the power of classes. You can add more functionality into this one and it automatically apply to all the crops you attached it to.