0

私はActionScriptでゲームを書いています。そこでは、ショットで「ヒット可能」であるはずの複数のクラスがあります。

他のすべてのゲーム内エンティティが継承する最も一般的なクラスはCombatObjectです。CombatShip、CombatAsteroid、その他のさまざまなクラスがそれを継承しています。CombatAiクラスとCombatPlayerクラスはどちらもCombatShipから継承しています。

ここで、CombatAi、CombatPlayer、およびCombatAsteroidをショットでヒット可能にしたいのですが、それらに継承させたくありません(後で、ヒットできないはずのCombatShipがある可能性があります)。

私のアイデアは、これら3つにインターフェイスIHitableを実装して、ショットと衝突したときにif(hitObject is IHitable)、ショットを破壊してダメージを与えるように依頼できるようにすることでした。

さて、問題は、これらのクラスのそれぞれを持つことが最善でしょうか?

  1. ダメージを受けるために必要なすべてのコードを実装する(シールドのチェック、ダメージ率の計算など)
  2. それらすべてにクラスのインスタンスを所有させ、すべての損傷関連機能を処理するクラスを返すDamageManager関数を実装しますgetDamageManager():DamageManager
  3. (2.)の欠点の1つは、各CombatShip、CombatAsteroidなどがDamageManagerのインスタンスを所有している必要があることです。DamageManagerをシングルトンにして、船とそれに与えられたショットへの参照を持ち、残りを処理させる方がおそらくさらに良いでしょうか?
4

3 に答える 3

1

オプション1は、多くの反復コードを生成しますが、それは明らかな理由で悪いことです。

オプション3は、すべての衝突コードが1つのクラスに入ることを意味します。カプセル化の観点からすると、これは悪いことです。すべてを処理する巨大なクラスになってしまうからです。

そのため、オプション2が最良のオプションとして残ります。オプション2は、さまざまな種類の船や小惑星に対してDamageManagerクラスを拡張できるため、オプション3よりも優れています。

ただし、オプション4:ミックスインも提示したいと思います。

ミックスインは言語レベルの機能であり、継承せずに複数のクラスに共通の機能を追加できます。ActionScript 3言語はミックスインをサポートしていませんが、AS3はそれをシミュレートできるほど十分に柔軟性があります。AS3でのMixinまたはTraitの実装?

于 2010-10-29T22:53:27.380 に答える
1

Mixinは良いアイデアですが、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オブジェクト(オブジェクトのヘルスとシールドの情報を保持する)を「ヒッター」のプロパティを説明する別のオブジェクトと一緒に渡すことができ、DamageManagerは「ヒッティー」の統計を更新するために使用できる別のStatオブジェクトを返します。

それが理にかなっていることを願っています!

于 2010-10-30T13:29:43.750 に答える
0

IHitableインターフェイスでisHitableゲッターを実装すると、ゲームの後半で特定のクラスに変更を加えたい場合に柔軟性が高まります。これは、IHitableインスタンスでは「isIHitable」が常にtrueを返すためです。

計算のタイプと結果として生じる変更に応じて、DamageManagerは実際にはシングルトンである必要はありません。損傷評価を処理して変更されたオブジェクトを返す静的メソッドを呼び出すことができます。

于 2010-10-30T02:57:33.907 に答える