書き物

技術とか作った物の話とか愚痴文句感想など

まだちゃんと分かってない。例のゲームシステム。

『花火』でゲームシステムを考える - 書き物

ここで試したゲームシステムですが、まだちゃんと理解していませんでした。


分からないところというのが、マネージャーを多段に噛ました場合のメッセージ転送方法です。

例えば次のような構成で作る場合、

GameManager implements IStageManagerCtx
┗ StageManager implements IPlayerCtx, IEnemyCtx・・・
  ┣ Player
  ┣ Enemy
  ・
  ・
  ・

PlayerがGameManagerのデータを参照したい場合、どうすれば良いか。

この場合、StageManagerがGameManagerの情報をPlayerへ橋渡しする必要があると思うのですが、

それをしようとすると路頭に迷ってしまいました。


まずはStageManagerがGameManagerからデータを取得する場合、

IStageManagerCtxにGameManagerからデータを取得する処理を定義、GameManagerで実装します。

これは前回書いた通り。


で、IPlayerCtxにStageManagerがGameManagerからデータを取得する処理を定義、StageManagerで実装・・・

とやってみたら、GameManagerからデータを取得できませんでした。

GameManagerはStageManager::execメソッドを呼ぶ際、自身を引数に指定します。

StageManager::execメソッドの引数は、context:IStageManagerCtxなわけで、

IStageManagerCtxで定義された処理を呼び出し、GameManagerからデータを取得できると。

このcontextからデータを取得する処理をIPlayerCtxに定義して、

IPlayerCtx::execメソッドを実行すれば、GameManagerのデータを取得できるはず・・・と思っていたのですが。

contextはexecの引数なので、exec以外のメソッドからはアクセスできません・・・。

なので、GameManagerのデータの取得ができないです。


対策としてほんとにパッと思いつく方法としては、

StageManagerにcontext:IStageManagerCtxをメンバとして持たせます。

これならIPlayerCtxでcontextからデータを取得する処理を定義すれば良いだけです。

確かに「メッセージを転送する」という意味では転送になるんだろうと思いますが、

StageManagerがメンバにcontextを持つという設計は、あまり美しくないんじゃないかと。


もうひとつは、

class StageManager
{
private var _player:Player;
public function exec(context:IStageManagerCtx):void
{
_player.exec(this, context);
}
}

というように、Player::execメソッドをStageManagerのthisと、context:IStageManagerCtxを2つとも指定する方法です。

これも転送・・・ですかね?

ただし、PlayerがGameManagerから取得するデータをStageManagerが制限できません。

いわばPlayerのGameManagerに対するアクセス権がStageManagerと同等になってしまい、

システムの意義がなくなるんじゃないかと思います。


このゲームシステムの各クラスがどういう役割で、何をすべきなのかをちゃんと分かっていないのかもしれません。

ここを決着をつけてから先に進みたいところです。