Cocos2d-xのデザインパターン

こんにちは、Habr! Aleksei Pinchukによる記事「 Cocos2d-xのデザインパターン 」の翻訳を紹介します。



この記事は、Cocos2d-x開発者およびパターンを研究する人々にとって興味深いものになります。 これは、特定のパターンがCocos2d-xで使用されている場所をすばやく確認できる簡単な要約の形式で作成されます。 この記事の目的は、各パターンを完全に説明することではありません。



生成パターン



試作機



プロトタイプは、オブジェクトをコピーするためのインターフェースを定義します。 新しいオブジェクトを作成するには、オブジェクトの状態をコピーします。 たとえば、Animationオブジェクトでclone()を呼び出す場合、まったく同じパラメーターでAnimationオブジェクトを作成します。



画像



シングルトン



はい。



構造パターン



フライ級



Flyweightは、同じリソースの多数のインスタンスを作成せずに、同じリソースを個別に使用するために使用する必要があります。 これにより、メモリを効率的に使用できます。 このパターンは、テキストの表示に適しています。



テキストを表示するには、Labelクラスが使用されます。 テキストを表示するには、フォントが必要です。 TTFフォントを取得するには、FontAtlasCacheクラスのgetFontAtlasTTFメソッドを使用する必要があります。 FontAtlasCacheは、アプリケーションで使用されるすべてのフォントのプールです。 フォントは、少なくとも1つのオブジェクトが使用するまで保存されます。 同じフォントを持つ10個のLabelオブジェクトがある場合、それらはすべてFontAtlasクラスの同じインスタンスを使用します。



画像



FontAtlasには、シンボルを表示するためのデータ(テクスチャと座標)が含まれています。 テクスチャのサイズは512x512であり、すべての文字が1つに収まらない場合、そのようなテクスチャをいくつか作成できます。 このフォントを参照するオブジェクトが使用する文字のみが作成されます。 Labelは、FontAtlasから各文字のFontLetterDefinition構造を取得します。 この構造からのデータに基づいて、Labelはスプライトを作成し、BatchNodeに配置します。 一般的に、Labelがどれだけ慎重に最適化されているかがわかります。



画像



リソースを共有するもう1つの良い例は、テクスチャスプライトの使用です。 ダウンロードした各ファイルのテクスチャは、単一のコピーに保存されます。 同じファイルから作成された複数のスプライト、同じテクスチャインスタンスを参照します。



画像



規則性を見つけることができます-クラス名がCacheで終わる場合、個別に使用するオブジェクトを生成します。





ブリッジは、抽象化と実装を分離します。 このパターンは、クロスプラットフォームオブジェクトを実装するために最もよく使用されます。 クラシックブリッジは、EditBoxおよびDownloaderにあります。



画像



画像



また、このパターンはGLView、AudioEngine、Controller、およびWebViewに適しています。 ただし、同じタスクを実装するさまざまな方法、つまり抽象化と実装の分離を見ることができます。



コンポジット



Compositeの目標は、ツリーを構築し、ツリーコンポーネントへのアクセスを統合することです。 通常、複合回路は次のようになります。



画像



Compositeは、Componentから継承された複数のオブジェクトで構成される複合オブジェクトです。 したがって、複数のオブジェクトを1つとして認識することができます。 Cocos2d-xでは、ノードはコンポジットとコンポーネントの両方です。



画像



Nodeのおかげで、Nodeが属するノードごとにグラフシーンが作成されます。



行動パターン



コマンド



コマンドはリクエストをオブジェクトとしてカプセル化し、リクエストのキューイングを可能にします。 他のユースケースは考慮されません。 Cocos2d-xでは、このパターンを使用してRendererのキューを作成します。 このパターンのおかげで、オブジェクト内でのOpenGL APIの使用は削除されました。 OpenGLの同じコードが1つのコマンドで出力され、何度もコピーされません。 他のグラフィカルAPIへの移行も容易になりますが、簡単にはなりません。



画像



オブザーバー



オブジェクト間の1対多の関係を定義します。 Cocos2d-xでは、サブジェクトはEventDispatcherであり、オブザーバーはEventListenerです。 EventDispatcherはシングルトンではなく、EventDispatcherを継承できます。 Directorは、EventDispatcherを介して、加速度計、マウス、キーボードなどの状態の変化についてオブザーバーに通知します。 カスタムEventCustomメッセージを作成することもできます。 これらのメッセージには、オブザーバーに送信する必要がある名前とデータがあります。 これは、すでに非推奨としてマークされているNotificationCenterの代替です。 また、Directorは、EVENT_BEFORE_UPDATE、EVENT_AFTER_UPDATEなど、いくつかの便利なEventCustomを定義します。 EVENT_BEFORE_UPDATEは、Box2Dで作業するときに便利です。 たとえば、物理世界を更新する前に、linearVelocityを何らかのオブジェクトに変更します。



画像



パターンの分離



成分



すべてのゲーム開発者はコンポーネントベースのアーキテクチャを知っていると思います。 Unity3dプログラマーは確実に知っておくべきです。 このようなシステムでは、コンポーネントの接続性が低下し、エンティティがエンティティについても知らない方法でコンポーネントをエンティティに追加できます。 このシステムはCocos2d-xにあります。 各ノードにはコンポーネントのコンテナがあります。 Componentクラスからコンポーネントを継承する必要があります。 各コンポーネントには、所有するノード(所有者)、updateメソッド、およびコンポーネントと他のオブジェクト間のメッセージを処理するためのserializeメソッドへのリンクがあります。



画像



最適化パターン



データの局所性



このパターンの目的は、プロセッサーによるキャッシュのためにより便利なデータの配置を使用することにより、メモリーへのアクセスを高速化することです。 このパターンは、パーティクルの作成によく使用されます。 また、Cocos2d-xでは、パーティクルの作成にも使用されます。 ParticleSystemでは、すべての粒子データはParticleDataに保存されます。 ParticleDataには、すべてのパーティクルのデータが含まれています。 ParticleDataのほとんどすべてのメンバーは配列です。 たとえば、posx配列には、x軸に沿った粒子の座標が格納されます。



class ParticleData { public: float* posx; float* posy; //... };
      
      





データを処理順にメモリに順次配置することで、データを迅速に処理し、キャッシュミスを可能な限り回避できます。



汚れた旗



Sosos2d-xでは非常に一般的です。 このパターンは、結果が必要になるまで、遅い作業の実行を遅らせます。 Scene、Camera、Node、Label、ParticleSystem、Spriteなどのクラスにあります。



All Articles