【问题标题】:AS3 || Using same function with different variablesAS3 ||使用具有不同变量的相同函数
【发布时间】:2018-10-06 05:56:12
【问题描述】:

我对 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 很陌生,哈哈。

【问题讨论】:

    标签: actionscript-3 flash


    【解决方案1】:

    虽然BFAT's tutorial 是绝对正确的,但它并不是唯一的做事方式,此外,如果你曾经从 Flash 和 AS3 迁移到其他东西,或者甚至尝试 Starling(一个框架允许在 Flash/AS3 中构建快速且无延迟的移动应用程序),您会发现该概念不适用。它非常Flash-y,但我对此表示赞赏。

    您可以让 Crop 类采用这 6 个字段中的 1 个,而不是使每个字段成为抽象的子类(意味着它永远不会被自己实例化)Crop 类作为创造(或以后)的论据。基本上,您会告诉“我想用小麦图形制作农田”。所以,让我重做一下那节课。

    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 类设置为可以访问它们,保持基类不变,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();
    

    【讨论】:

      【解决方案2】:

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

      这是一个简单的类的例子,可以做你想做的事。在 Flash/Animate 中,依次转到 filenew、“ActionScript 3.0 Class” - 将其命名为 Crop

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

      所以,首先,你应该有这个:

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

      让我们继续把你的代码放进去。详情见代码cmets:

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

      保存文件。现在您有了这个类,您需要将它附加到您的库资产中,以便它们都获得此功能。

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

      现在在您的时间线上,当您希望作物开始生长时,您可以:

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

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

      【讨论】:

      • 哇,没想到回答这么透彻。太感谢了!我会在明天早上继续努力的时候试试这个。
      • 很抱歉响应缓慢,直到今天我才有时间处理我的游戏,我一直在尝试这个。我把它作为解决方案,因为类显然是正确的答案,但我没有时间测试它。我无法理解类在属性中的作用,因为每当我单击复选框时,它都会给我一个“在类路径中找不到此类的定义”错误。一直在尝试谷歌一下,所以我不必问,但我似乎无法正确理解它。
      • 我终于找到了一个人解释的视频——并且展示得相当透彻,所以我现在理解得更多了,我也意识到这很明显,哈哈。无论如何,非常感谢您的回答!我见过有人说我不应该在时间轴上编码,而是使用类,但我一直不明白为什么,直到你回应,哈哈。谢谢!
      猜你喜欢
      • 1970-01-01
      • 2012-12-07
      • 2019-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多