AS3 ||使用具有不同变量的相同函数

AS3 || Using same function with different variables

我是 AS3 的新手,我正在尝试通过在 Flash 中进行实验、使用非常简单的代码制作一个简单的 2D 农场游戏来学习。

我从 6 个有效的农田中制作了一个,这是一个电影片段,每个水果生长都有不同的帧。例如,第 1-5 帧是正在生长的草莓,第 5 帧是可以采摘的,然后第 6-10 帧是胡萝卜,等等

有没有办法让我不必为下一个作物田编写完全相同的代码,而是根据您单击的作物田更改此代码中的变量?

这是代码示例

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);
        }

如前所述,请不要评判,我是 AS3 的新手,哈哈。

在这种情况下,有几种方法可以使您的代码变干(不要重复自己)。最好的方法是学习使用 classes。 Class这些是蓝图,专为这些场景而设计。

这是一个简单的示例 class 可以按照您的意愿进行操作。在 Flash/Animate 中,转到 file,然后 new,然后 'ActionScript 3.0 Class' - 将其命名为 Crop.

在出现的文档中,应该有一些基本的样板代码。一切都应该包裹在一个包裹里。该包告诉 flash 在哪里可以找到这个 class - 所以这个例子,保持原样(只是 package {)并将这个文件保存在与你的 .fla 相同的文件夹中。所有函数都需要包含在 class 声明中,这应该根据您输入的名称 (Crop) 为您生成。接下来您将看到一个与 class 同名的函数。这称为构造函数,只要您创建此 class 的新实例,此函数就会运行。由于 classes 是蓝图,您可以创建它们的实例,这些实例是对象 - 然后这些对象将获得您放入此 class 中的所有代码。

所以,首先,您应该拥有:

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

让我们继续把你的代码放进去,详情见代码注释:

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
        }
    }
}

保存文件。现在您已经有了这个 class,您需要将它附加到您的图书馆资产,以便它们都能获得此功能。

在库面板中,对于每个裁剪对象,右键单击(或 ctrl+单击 Mac)并转到 properties。在属性中,单击 advanced,并为其指定一个唯一的 class 名称(例如 Strawberry)。然后在基础 class 字段中,输入 Crop (我们刚刚创建的 class )。对其他人重复。

现在在你的时间表上,当你想让作物开始生长时,你可以这样做:

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

希望这能为 classes 提供一个切入点。您可以在此添加更多功能,它会自动应用于您附加的所有作物。

虽然是绝对正确的,但它并不是做事的唯一方法,而且,如果你曾经从Flash和AS3转向其他东西,甚至尝试Starling(一个允许在 Flash/AS3 中构建快速且无延迟的移动应用程序的框架),您会发现该概念不适用。它非常闪耀,但我还是为它鼓掌。

不是让每个字段子class抽象(意味着,它永远不会被自己实例化)Crop class,你可以让Crop class 将这 6 个字段中的 1 个作为创建(或以后)的参数。基本上,你告诉 "I want to make crop field with wheat graphics"。那么,让我重做一下 class。

package
{
    // Imports.
    import flash.display.Sprite;
    import flash.display.MovieClip;

    import flash.utils.Timer;

    import flash.events.Event;
    import flash.events.TimerEvent;

    public class Crop extends Sprite
    {
        // I agree with the use of Timer.
        private var timer:Timer;

        // Visuals go here.
        private var field:MovieClip;

        // Class constructor.
        public function Crop(FieldClass:Class)
        {
            // With "new" keyword you can omit ()
            // if there are no mandatory arguments.
            field = new FieldClass;
            field.stop();

            addChild(field);
        }

        // A function that starts the timer ticking.
        public function startGrowing():void
        {
            timer = new Timer(5000, 4);
            timer.addEventListener(TimerEvent.TIMER, grow);
            timer.start();
        }

        // This function is called every timer tick.
        private function grow(e:Event):void
        {
            // Command the graphics to go to the next frame.
            field.nextFrame();
        }
    }
}

然后,用法。当你创建字段时,你需要设置 AS3 classes 给他们访问,保留 base class 原样,Flash 会自动将其设置为非特定 MovieClip. Lessay,你有 crops.Wheat 字段和 crops.Barley 字段。

import Crop;
import crops.Wheat;
import crops.Barley;

var W:Crop = new Crop(Wheat);
var B:Crop = new Crop(Barley);

addChild(W);
addChild(B);
B.x = 100;

W.startGrowing();
B.startGrowing();