如何使用动作脚本覆盖动态类中的函数?

发布于 2024-10-21 05:59:36 字数 418 浏览 7 评论 0原文

这是一个剧本应用程序。

我有两节课:

public dynamic class Bullet extends Sprite {
   public function update():void {
      x += 5;
      y += 5;
   }
}

public class BulletFactory {
   public function createFastBullet:Bullet {
      var result:Bullet = new Bullet();

      result.update = function() {
         x += 10;
         y += 10;
      }
   }
}

这基本上就是我想要做的。在动作脚本中实现这一目标的最佳方法是什么?

This is for a playbook app.

I have two classes:

public dynamic class Bullet extends Sprite {
   public function update():void {
      x += 5;
      y += 5;
   }
}

public class BulletFactory {
   public function createFastBullet:Bullet {
      var result:Bullet = new Bullet();

      result.update = function() {
         x += 10;
         y += 10;
      }
   }
}

This is essentially what I'm trying to do. What's the best way to achieve this in actionscript?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦冥 2024-10-28 05:59:36

你不这样做。动态是允许您添加任何尚未声明的临时属性,而不是覆盖已经声明的函数。动态不要与抽象混淆。

请尝试类似的操作 根据

public class Bullet extends Sprite{
    public var speedX = 5;
    public var speedY = 5;

    public function update():void{
       x += speedX;
       y += speedY;
    }
}

public class BulletFactory{

    public static function getFastBullet():Bullet{
        var result:Bullet = new Bullet();
        result.speedX = result.speedY = 10;
        return result;
    }

}

您的喜好调整 speedX/speedY 的公共/私人可见性。

另一方面,如果您想尽可能从字面意义上“动态覆盖函数”,那么总是有这个(虽然很hacky但有效)。

public class AbstractBullet extends Sprite{

    public var update:Function; // <- Notice that function is just a variable here.

}

然后,在您的子弹工厂中,您可以临时分配更新功能。请注意,这不太“安全”,因为更新不再具有设置的签名,因此您会失去所有类型安全的概念。在调用它之前,您还必须确保它存在。如果要避免编译器警告,则必须显式进行 null 检查。

var f:Function;

// this is fine.
// it's particularly safe if 
// f is a declared variable of type
// Function.
if(f != null) f();

// this is also fine,
// and is preffered if f is NOT
// a defined variable but instead
// a dynamically created (and therefore
// untyped) variable of a dynamic object.
// You would not want to "call" something
// that is not a function, after all.
if(f is Function) f();




// but this gives a warning
// even though the code works
// correctly at runtime.
if(f) f();

You don't do it that way. Dynamic is to allow you to add any ad-hoc property that isn't already declared, not to override already declared functions. Dynamic is not to be confused with abstract.

Try something like this instead

public class Bullet extends Sprite{
    public var speedX = 5;
    public var speedY = 5;

    public function update():void{
       x += speedX;
       y += speedY;
    }
}

public class BulletFactory{

    public static function getFastBullet():Bullet{
        var result:Bullet = new Bullet();
        result.speedX = result.speedY = 10;
        return result;
    }

}

Adjust the public/private visibility of speedX/speedY to your liking.

If on the other hand you want to "dynamically override a function" in as literal a sense as possible, there's always this (which is hacky but valid).

public class AbstractBullet extends Sprite{

    public var update:Function; // <- Notice that function is just a variable here.

}

Then in your bullet factory you can assign the update function on an ad-hoc basis. Note that this is less "secure" as you lose all notion of type safety as update no longer has a set signature. You also have to make sure it exists before you call it. You must make the null check explicit if you want to avoid a compiler warning.

var f:Function;

// this is fine.
// it's particularly safe if 
// f is a declared variable of type
// Function.
if(f != null) f();

// this is also fine,
// and is preffered if f is NOT
// a defined variable but instead
// a dynamically created (and therefore
// untyped) variable of a dynamic object.
// You would not want to "call" something
// that is not a function, after all.
if(f is Function) f();




// but this gives a warning
// even though the code works
// correctly at runtime.
if(f) f();
雪化雨蝶 2024-10-28 05:59:36

您可以使用接口、扩展和覆盖的组合来解决您的问题。
下面的内容不会编译,但应该为您提供一个起点。

public interface IBullet {
    function update():void
}

public class DefaultBullet extends Sprite implements IBullet{
   public function update():void {
      x += 5;
      y += 5;
   }
}

public class FastBullet extends DefaultBullet implements IBullet{
   override public function update():void {
      x += 10;
      y += 10;
   }
}

public class BulletFactory {
   public function createBullet(bulletType:String):IBullet {
      var bullet:IBullet;
      if(bulletType=="fast"){
        bullet = new FastBullet();
      }else{
        bullet = new DefaultBullet();
      }
      return bullet;
   }
}

You could solve your issue using a combination of Interfaces, extensions and overrides.
The below won't compile, but should give you a starting point.

public interface IBullet {
    function update():void
}

public class DefaultBullet extends Sprite implements IBullet{
   public function update():void {
      x += 5;
      y += 5;
   }
}

public class FastBullet extends DefaultBullet implements IBullet{
   override public function update():void {
      x += 10;
      y += 10;
   }
}

public class BulletFactory {
   public function createBullet(bulletType:String):IBullet {
      var bullet:IBullet;
      if(bulletType=="fast"){
        bullet = new FastBullet();
      }else{
        bullet = new DefaultBullet();
      }
      return bullet;
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文