0

我正在用 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 成为 Singleton 并且只引用船和给它的镜头并让它处理其余部分可能会更好吗?
4

3 回答 3

1

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

选项 2 会起作用,但暴露 DamageManager 的实例会破坏封装。您可以通过在 IHitable 界面中添加 hit 方法来解决此问题。当有东西击中这个对象时,你的游戏会调用这个方法。此方法的实现取决于对象。您可以为每个对象以不同的方式实现它(选项 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”的统计信息。

希望它有一些意义!

于 2010-10-30T13:29:43.750 回答
1

选项 1 会导致大量重复代码,这很糟糕,原因很明显。

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

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

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

Mixins 是一种语言级别的功能,它允许您向多个类添加通用功能而无需继承。尽管 ActionScript 3 语言不支持 mixin,但 AS3 足够灵活,您可以模拟它。AS3 中的 Mixin 或 Trait 实现?

于 2010-10-29T22:53:27.380 回答
0

在 IHitable 接口中实现 isHitable getter 怎么样,如果您想在游戏后期对某些类进行更改,这可以提供更大的灵活性,因为使用 IHitable 实例“is IHitable”将始终返回 true。

根据计算类型和产生的修改,DamageManager 不一定是 Singleton,您可以调用静态方法来处理损坏评估并返回修改后的对象。

于 2010-10-30T02:57:33.907 回答