Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

ゲーム開発とデザインパターン

21 777 vues

Publié le

社内勉強会で使った資料を公開します。

Publié dans : Technologie
  • Login to see the comments

ゲーム開発とデザインパターン

  1. 1. ゲーム開発とデザインパター ン ~コスト削減とクオリティの両立を目指して~ もんぐり
  2. 2. この勉強会の目的 • デザインパターンに親近感をもってもら うこと • ゲーム開発における、よりよい設計につ いて一緒に考えてもらうこと • ゲームの品質と開発スピードの向上に寄 与すること ちなみに、僕はデザインパターンの専門家でもゲーム開発の専 門家でもなく、どっちも駆け出しなので、暖かくご意見ご指摘 ください!
  3. 3. デザインパターンとは • Wikipediaの定義 – 過去のソフトウェア設計者が発見し編み出した設計ノウハウを蓄積 し、名前をつけ、再利用しやすいように特定の規約に従ってカタロ グ化したものである。 • 代表的なのはGoFの23個のデザインパターン • 一言で表すと 「直に書かずにクラスを分けろ」 ってことかなと。(個人的解釈です)
  4. 4. デザインパターンを学ぶメリッ ト • 設計の世界共通言語 – 「ここはFactoryMethodで設計してるんだ」って説明すれば、 「ああFactoryMethodね」って、すぐ話が通じるよ! • 巨人の肩に乗る • 品質向上(バグを作りこみにくい設計) • メンテナンス性向上(読みやすい、修正 しやすい) • 品質向上≒開発スピード向上
  5. 5. デザインパターンを学ぶメリッ ト デザパタ駆使した とき クラスの独立性が 高くなるようにだ け気をつけた時 直にがんがん処理 を書いてる時 パフォーマンス ◯ ◯ ◯ 可読性 △ ◯ ☓ クラス独立性 ◯ △ ☓ ソースを書く速度 △ △ ◯ バグ発生率の低さ ◎ ◯ ☓ トータルな開発と メンテのコストの 低さ ◎ ◯ ☓ ※独断と偏見に基づく評価です
  6. 6. 23個も覚えきれないよ!
  7. 7. (独断と偏見で)厳選したパター ンを、 適用事例とともにご紹介します!
  8. 8. こんな経験ないですか? • このインスタンスはアプリ内で1個だけのはずな のに、勝手に別の場所でも作られちゃった! – アプリ全体のデータを保持したクラスとかの話 • → 利用者がそれと知らずに、複数インスタンス を扱っていると、バグに気づくのが遅れると大混 乱に イン スタ ンス1 イン スタ ンス2 利用者 更新 参照 インスタンス は 1個だけだよね
  9. 9. Singleton • 1個しか作っちゃいけないものは1個しか作れないようにして おこう • コンストラクタで例外投げたりAssertしたり、コンストラクタ をprivateにしたりして、newを禁止します。 • Cocos2d-xでは、CCTextureCacheなど、キャッシュ系でよく使 われてます。CCDirectorなどの単一機能クラスもSingletonに なってます。 class SingletonClass { public: static SingletonClass* getInstance(); private: static SingletonClass* m_instance; SingletonClass(); };
  10. 10. こんな経験ないですか? • Animalクラスを継承した子クラスを作って、子によって違う処理はそれぞ れに隠蔽するぞ! • → 開発してるうちに、子クラスの種類がどんどん増えてきたんだが。。。 • → 大量の子クラスのヘッダを#includeしちゃってるよ! Switch-caseの caseの数がめっちゃ多いよ! • ビルド時間増大、依存性増大、クラスの行数が増大し、扱いにくいソース に。。。 #include “Cat.h” #include “Dog.h” ・・・ 100個の#include #include ”Dragon.h” bool Game::init() { m_cat1 = new Cat(); m_dog1 = new Dog(); ・・・ m_doragon1 = new Dragon(); return true; };
  11. 11. FactoryMethod(&AbstractFactory) • 派生クラスのどれでもインスタンス生成できるクラス を別に作っておいて、それを使うようにしよう • 派生クラスへの依存性をなくし、ポリモーフィズムを 駆使できます class AnimalFactory { public: IFAnimal* createAnimal(ANIMAL_TYPE type); }; IFAnimal* AnimalFactory::createAnimal(ANIMAL_TYPE type) { switch(type) { case CAT: return new AnimalCat(); case DOG: return new AnimalDog(); ・・・ default: return NULL; } }
  12. 12. こんな経験ないですか? • 敵によって攻撃パターン(アルゴリズム)が違う。攻撃パ ターンはそれぞれの敵クラスに実装しよう • → 攻撃パターン変更依頼もらったけど、それぞれの敵クラ スに処理が散らばってて、少しずつ差分があるから修正量が 半端ないよ! • → 「敵Aの攻撃パターンを敵Bと同じやつに差し替えとい て」って依頼もらったけど、アルゴリズムに結びつけたソー スにしてるからほぼ全て書きなおしだ!
  13. 13. Strategy • →アルゴリズムごとにクラス作って、クラス内に詳細 な処理は隠蔽し、どれも同じI/Fで使用できるようにし ておこう • 僕は、複数パターンのAIを使い分けるときによく使っ ています。 class AttackAIFactory { public: IFAttackAI* createAttackAI(AI_TYPE type); }; IFAttackAI* AttackAIFactory::createAttackAI(AI_TYPE type) { switch(type) { case VERTICAL_LASER: return new AttackAIVerticalLaser(); ・・・ default: return NULL; } } class IFAttackAI { virtual vector<Cell> createAttackCollisionArea() = 0; ・・・ };
  14. 14. こんな経験ないですか? • 状態管理はenumだね。ゲームのループで呼ばれるメ ソッド内でSwitch文書いて、処理を分岐すればよし! • → case数の増大、case内処理の増大。。。クラスの 行数が増えて3000行を超えますた switch(m_state) { case STATE_MOVING: ・・・ break; case STATE_ATTACKING: ・・・ break; ・・・ case STATE_DEAD: break; default break; }
  15. 15. State • 状態ごとにクラス作って、どれも同じI/Fで処理を起動できる ようにしよう! • 実際は、主クラスから、状態依存する処理だけを独立して切 り出すのはなかなか難しい印象。使えるところに使っていこ う。 class PlayerStateFactory { public: IFPlayerState* createPlayerState(PLAYER_STATE state); }; IFPlayerState* PlayerStateFactory::createAttackAI(PLAYER_STATE state) { switch(state) { case PLAYER_STATE_POISON: return new PlayerStatePoison(); ・・・ default: return NULL; } } class IFPlayerState { virtual void moveTo(Point point) = 0; ・・・ };
  16. 16. こんな経験ないですか? • 弾幕シューティング、弾発射時にインスタン ス生成、画面外にいったらインスタンス解放 だ! • →弾が多くなるとめっちゃフレームレート落 ちるんですが。。。
  17. 17. Flyweight • →必要なくなったインスタンスを解放せずに 再利用すべし • オブジェクトをプーリングするってことです • Cocos2d-xの場合はCCTextureCacheとか CCSpriteBatchNodeとかの仕組みは揃ってるけ ど、まああんまり生成解放が頻繁だったら最 初からプーリング書いてもいいと思う • サンプルコードは書くのが面倒くさいので省 略
  18. 18. こんな経験ないですか? • PlayerとEnemyとStageクラスを作ったぞ! • 3者が密接に絡みすぎて、何か一つ修正する だけで影響範囲調査がしんどい。。。 Player Enemy 1 Stage Enemy 2
  19. 19. Mediator • →各オブジェクトを仲介するクラスを用意し、独立な オブジェクト同士は直接やりとりしないようにする • Mediatorは、次回に紹介するObserverパターンと組み 合わせて、非同期処理の命令を実装するといいです – 非同期処理の例: • 命令:メソッド • 結果通知:次で紹介するObserverパターンによる通知 PlayerEnemy Stage GameManager
  20. 20. (デザパタって) 本当にゲーム開発の現場で 役に立つんかいな?
  21. 21. 知り合いに聞いてみた ※このスライドは、個人情報が入ってくるので、 SlideShare版では記載を外しました。 • 個人的には、経験上、取捨選択すればおおい に使えると思っています。
  22. 22. まとめ • デザインパターンをいい感じに使えるように なって開発スピードと品質を向上させよう! – Singleton – FactoryMethod – State – Strategy – Flyweight – Mediator • 次回はObserverとMVCパターンを議論します。
  23. 23. 参考書籍 • 検索するとわかりやすい解説サイトが出てくるのでそ れで十分かもです。 • オブジェクト指向における再利用のためのデザインパ ターン – いわゆるGoF本 • リファクタリング Martin Fowler著 上の2冊は僕は読んでません! • Java言語で学ぶデザインパターン • Java言語で学ぶリファクタリング入門 – 結城浩さんの本です

×