在AS3中如何在没有继承的情况下为多个类提供额外的功能?

时间:2010-10-29 21:56:26

标签: actionscript-3 game-engine

我正在用ActionScript编写一个游戏,我有多个类应该通过镜头“匹配”。

所有其他游戏内实体继承的最通用的类​​是CombatObject; CombatShip,CombatAsteroid和其他各种类继承自它。 CombatAi和CombatPlayer类都继承自CombatShip。

现在我想通过镜头使CombatAi,CombatPlayer和CombatAsteroid成为可能,但我不希望它们继承它(后来可能会有不应该被击中的CombatShips。)

我现在的想法是让这三个实现一个界面,IHitable,这样当他们碰到一个镜头时,我可以问if(hitObject is IHitable)如果是真的,那就把镜头摧毁并造成伤害。

现在问题是,最好是拥有这些类

  1. 实施所有必要的代码以自行修复(例如检查防护罩,计算损坏百分比等)
  2. 让他们拥有类DamageManager的实例并实现一个函数getDamageManager():DamageManager,它返回一个处理所有与损害相关的功能的类
  3. (2.)的一个缺点是每个CombatShip,CombatAsteroid等都必须拥有一个DamageManager实例。让DamageManager成为一个单身人士可能会更好,只需要参考船只和给它的射击并让它处理其余部分吗?

3 个答案:

答案 0 :(得分:1)

选项1会导致大量重复的代码,而且由于显而易见的原因这很糟糕。

选项3意味着您的所有碰撞代码都会进入一个类。从封装的角度来看,这很糟糕,因为你最终会得到一个处理所有事情的庞然大物。

这使得选项2成为最佳选择。选项2优于选项3,因为您可以为不同类型的船舶和小行星扩展DamageManager类。

但是,我还想提出一个选项4:mixins

Mixins是一种语言级功能,允许您向多个类添加常用功能而无需继承。尽管ActionScript 3语言不支持mixins,但AS3足够灵活,您可以对其进行模拟。 Mixin or Trait implementation in AS3?

答案 1 :(得分:1)

Mixins是一个好主意,但它在AS3中的支持是模拟的。

选项2将起作用,但暴露DamageManager实例会破坏封装。您可以通过在IHitable界面中添加命中方法来解决此问题。当某些东西击中此对象时,您的游戏将调用此方法。此方法的实现取决于对象。您可以为每个对象实现不同的选项(选项1),但您也可以创建一个通用的DamageManager类并使用它来计算损坏。

class DamageManager {
    public function calculateDamage(...){
        // implement your damage logic...
    } 
}

interface IHitable {
    function hit(by:GameObject);
}

例如在CombatPlayer中

class CombatPlayer implements IHitable
{
    private var _damage:DamageManager;

    public function CombatPlayer(){
         _damage = new DamageManager();
    }

    public function hit(by:GameObject):void {
        _damage.calculateDamage(...);
    }
}

我已经在DamageManager上打开了实现,因为我不知道你的对象是如何实现的,也不知道你想要如何计算损坏。

我认为理想情况下,DamageManager不应直接修改您的对象。您可以传递一个Stat对象(其中包含对象的运行状况和屏蔽信息)以及另一个描述“hitter”属性的对象,DamageManager将返回另一个Stat对象,您可以使用该对象更新“hittee”的统计信息。

希望它有所了解!

答案 2 :(得分:0)

如果要在IHitable界面中实现isHitable getter,如果你想在游戏中稍后对某些类进行更改,这可以提供更大的灵活性,因为使用IHitable实例“is IHitable”将始终返回true。

取决于计算类型&由此产生的修改,DamageManager实际上不必是一个Singleton,你可以调用一个静态方法来处理损坏评估并返回你修改过的对象。