ソーシャルゲームにおけるデザインパターンの適用
新年あけまして、おめでとうございます。
システムグループに所属する、鰯(いわし)です。 最近ハマっているのは、AWSとSilexです。好きなフォントは、Monaco13ptです。
本日は、『ソーシャルゲームにおけるデザインパターンの適用』について、私なりの一つの事例を紹介したいと思います。
昨今、ソーシャルゲームの隆盛で、たくさんのプログラマの方がソーシャルゲームの開発を行っている事と思います。また、その中でも特に、カードゲームの人気が強く、どこもかしこもカードゲーム、カードゲーム、何を今更という感じですが。
今回は、そのカードゲームにおける一要素である、バトルシステムのお話です。
まずは、ソーシャルゲームのカードバトルシステムって何?という方のために、ごく一般的な仕組みについて説明しておきたいと思います。
ゲームのプレイヤーは、所持カードから任意のカードを選択し、デッキを組んでカードバトルに挑みます。バトルでは、このデッキに構成されたカードによりターンごとにカードを出して対戦します。
各カードには攻撃力と防御力の他にコストが決められており、強いカードほどコストも高くなります、デッキには合計のコストが決まっており、どのようにしてデッキにカードを組むかによって戦闘の勝敗を分けることになります。
と、ざっくり説明はここまでにして、さっそくですが、まずは、バトルシステムの枠組みとなるクラスを Template Method パターンを用いて定義します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[sourcecode lang="php"] abstract class Battle { protected $playerDeck = null; protected $enemyDeck = null; function __construct($playerDeck, $enemyDeck) { $this->playerDeck = $playerDeck; $this->enemyDeck = $enemyDeck; } public function getPlayerDeck() { return $this->playerDeck; } public function getEnemyDeck() { return $this->enemyDeck; } } [/sourcecode] |
Template Method パターンを用いる事で、バトルシステムの枠組みを作り、対ユーザバトルまた、対ボスバトルなどのそれぞれの差分だけをサブクラスへ任せます。
そして、このBattleクラスへさらに実際の戦闘ロジックを付け加えます、具体的に戦闘ロジックとは、先ほどカードバトルの説明に出てきた、『ターンごとにカードを出して対戦』という部分になります。
しかし、このロジックをそのまま実装してしまうと、ターン制のバトルしか行えなくなってしまうので、ここでは Strategy パターンを適用したいと思います。 (実際、某ゲームにおいてターン制以外の戦闘ロジックも必要だったので…)
Strategyを翻訳すると『戦略』、まさに戦闘における戦略を実装するためのパターン。
まずは、バトル用のStrategyクラスの枠組みを定義し、さらにそれを継承した、実体であるターン制の戦闘ロジッククラスを定義します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[sourcecode lang="php"] abstract class BattleStrategy { function __construct($playerDeck, $enemyDeck) { $this->playerDeck = $playerDeck; $this->enemyDeck = $enemyDeck; } abstract public function execute(); } class TurnBasedBattleStrategy extends BattleStrategy { public function execute() { // プレイヤーと敵の戦闘ロジックを実装 } } [/sourcecode] |
上記の戦闘ロジック扱えるように、Battleクラスへ実装を追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
[sourcecode lang="php"] abstract class Battle { // 〜〜〜〜 中略 〜〜〜〜 abstract protected function createStrategy($playerDeck, $enemyDeck); final public function doFight() { $battleStrategy = $this->createStrategy( $playerDeck, $enemyDeck ); $playerWin = null; while ($playerWin === null) { $playerWin = $battleStrategy->execute(); } $this->setPlayerWin($playerWin); } } [/sourcecode] |
while による判定は、プレイヤーの勝敗が決定するまで戦闘ロジックの実行を繰り返します。 また、 createStrategy() のメソッドを abstract としたのは、サブクラス側で戦闘ロジックを柔軟に変更する事を意図しています。
このようにして、Template Method パターンによる枠組みにより実装の抽象化を図り、Strategy パターンを適用する事で、より柔軟なバトルシステムの基礎が出来上がりました。
それぞれのパターンの説明については、Wikipediaを参照されたし…
– Strategy パターン
– Template Method パターン
昨今、MVCパターンのModelについて云々騒がれておりますが、こんな形でモデルを実装するんじゃね?という一つの解になるかは、わからないですが、いかがでしょう?
ソニックムーブではエンジニアを募集しております、今回は、話しのネタとして面白いかなと思ったので、ソーシャルゲームの話しをしましたが、弊社では、ソーシャルゲーム以外にも多種多様なサービスを展開しております、ソーシャルゲームは嫌だという、あなたでも大歓迎ですので、ぜひご応募ください。
熱いパッションを私はお待ちしております。