web-dev-qa-db-ja.com

ゲームの動作/コンポーネントベースのシステムを作成する

バックグラウンド

私は趣味でゲーム開発をしており、それらを設計するためのより良い方法を探しています。現在、私は標準のOOPアプローチを使用しています(私は8年間エンタープライズ開発を行っているので、それが自然に行われるようになっています)。

_public class Baddie:AnimatedSprite //(or StaticSprite if needed, which inherit Sprite)
{
    //Sprite base will have things like what texture to use, 
    //what the current position is, the base Update/Draw/GetInput methods, etc..
    //an AnimatedSprite contains helpers to animated the player while 
    //a StaticSprite is just one that will draw whatever texture is there
}
_

問題

私が2Dプラットフォーマーを作っているとしましょう。ジャンプするためにはバディが必要です。通常は、Update/GetInputメソッドに適切なコードを追加します。その後、プレイヤーにクロール、アヒル、登山などを行わせる必要がある場合、コードがそこに配置されます。

注意しないと、これらのメソッドが乱雑になるので、次のようなメソッドのペアを作成してしまいます。

CheckForJumpAction(Input input)およびDoJump()

CheckforDuckAction(Input input)およびDoDuck()

getInputは次のようになります

_public void DoInput(Input input)
{
    CheckForJumpAction(input);
    CheckForDuckAction(input);
}
_

更新は次のようになります

_public void Update()
{
    DoJump();
    DoDuck();
}
_

私が行ってanotherゲームを作成して、プレイヤーがジャンプしてアヒルする必要がある場合、私は通常、機能を持つゲームに行ってそれをコピーします。乱雑な、私は知っています。それが私がより良いものを探している理由です。

解決?

Blendが要素にアタッチできるビヘイビアをどのように持っているかが本当に好きです。ゲームで同じコンセプトを使用することを考えています。同じ例を見てみましょう。

基本のBehaviorオブジェクトを作成します

_public class Behavior
{
    public void Update()
    Public void GetInput()
}
_

そして、それを使用してビヘイビアを作成できます。 _JumpBehavior:Behavior_および_DuckBehavior:Behavior_

次に、ビヘイビアのコレクションをSpriteベースに追加し、必要なものを各エンティティに追加します。

_public class Baddie:AnimatedSprite
{
    public Baddie()
    {
        this.behaviors = new Behavior[2];
        this.behaviors[0] = new JumpBehavior();
        //etc...
    }

    public void Update()
    {
        //behaviors.update
    }

    public GetInput()
    {
        //behaviors.getinput
    }
}
_

だから今私が多くのゲームでジャンプとダックを使いたいのなら、私は振る舞いを持ち帰ることができます。一般的なライブラリを作成することもできました。

うまくいきますか?

私が理解できないことは、それらの間で状態を共有する方法です。 JumpとDuckを見ると、どちらも描画されているテクスチャの現在の部分だけでなく、プレーヤーの状態にも影響を与えます。 (ジャンプは時間の経過とともに減少する上向きの力を適用しますが、アヒルは動きを止めようとしていますが、テクスチャとバッディーの衝突サイズを変更します。

これをどのように結び付けて機能させることができますか?動作間の依存関係プロパティを作成する必要がありますか?親についてそれぞれの動作knowを設定し、直接変更する必要がありますか?トリガーされたときにデリゲートを各ビヘイビアーに渡して実行することができると思っていました。

まだまだ検討している問題があると思いますが、全体の目的は、ゲーム間、および同じゲーム内のエンティティ間でこれらの動作を簡単に再利用できるようにすることです。

だから私はあなたにそれを引き渡します。これがどのように/できるかを説明するために気をつけますかもっと良いアイデアはありますか?ぜひ聞きたいです。

11
user81

this プレゼンテーションを見てください。あなたが探しているパターンの種類にかなり近いように聞こえます。このパターンは、動作とアタッチ可能なプロパティをサポートしています。プレゼンテーションで言及されているとは思いませんが、アタッチ可能なイベントを作成することもできます。この考え方は、WPFで使用される依存関係プロパティに似ています。

1
Nieldy

私には、これは Strategy Pattern を使用するためのほとんど教科書のケースのように聞こえます。このパターンでは、一般的な動作をインターフェイスで定義して、実行時に動作のさまざまな実装を入れ替えることができます(パワーアップがキャラクターのジャンプまたは実行能力にどのように影響するかを考えてください)。

(不自然な)例の場合:

// The basic definition of the jump behavior
public interface IJumpBehavior {
    void Jump();
}

これで、特定の各ジャンプの詳細を必ずしも知らなくても、キャラクターが使用できるさまざまなタイプのジャンプを実装できます。

// This is the jump the character may have when first starting
public class NormalJump : IJumpBehavior {

     public void Jump() {
         Console.WriteLine("I am jumping, and being pretty boring about it!");
     }

}

// This is the jump of a character who has consumed a power-up
public class SuperJump : IJumpBehavior {
    public void Jump() { 
         Console.WriteLine("I am all hopped up on star power, now my jumps can do damage!");
     }
}

ジャンプできるようにしたいすべての文字にIJumpableへの参照を含めることができ、さまざまな実装の使用を開始できます

public class HeroCharacter {

    // By default this hero can perform normal jump.
    private IJumpBehavior _jumpBehavior = new NormalJump();

    public void Jump() {
        _jumpBehvaior.Jump();
    }

    // If you want to change the hero's IJumpable at runtime
    public void SetJump(IJumpBehavior jumpBehavior) {
      _jumpBehavior = jumpBehavior;
    }

}

その後、コードは次のようになります。

HeroCharacter myHero = new HeroCharacer();

// Outputs: "I am jumping, and being pretty boring about it!"
myHero.Jump()

// After consuming a power-up
myHero.SetJump(new SuperJump());

// Outputs: "I am all hopped up on star power, now my jumps can do damage!"
myHero.Jump();

これで、これらの動作を簡単に再利用したり、後でさらに種類のジャンプを追加したり、単一の横スクロールプラットフォームでビルドしたゲームを作成したりするために、それらを拡張することができます。

9
mclark1129

DCIアーキテクチャ を見てくださいOOプログラミングに役立つ可能性がある興味深いプログラミング.

DCIスタイルアーキテクチャをC#で実装するには、単純なドメインクラスを使用し、拡張メソッドとインターフェイスでContextオブジェクト(動作)を使用して、ドメインクラスがさまざまな役割で共同作業できるようにする必要があります。インターフェイスは、シナリオに必要なロールをマークするために使用されます。ドメインクラスは、意図した動作に適用されるインターフェース(ロール)を実装します。ロール間のコラボレーションは、コンテキスト(動作)オブジェクトで行われます。

個別のプロジェクトのドメインオブジェクト間で共有できる一般的な動作と役割のライブラリを作成できます。

C#のコード例については、「 C#のDCI 」を参照してください。

1
Ed James

コンテキストオブジェクトをビヘイビアーに渡して、ビヘイビアーの影響を受けるスプライト/オブジェクトの状態を変更するメソッドを提供するのはどうですか?オブジェクトに複数の動作がある場合、それらはそれぞれループで呼び出され、コンテキストを変更する機会を与えます。プロパティの特定の変更が他のプロパティの変更を除外/制約する場合、コンテキストオブジェクトは、この事実を示すためにある種のフラグを設定するメソッドを提供するか、不要な変更を単に拒否することができます。

0
Jonny Dee