はじめまして。
現在RPGゲーム製作を行っているのですが、
MVCでの設計でわからない点があり、こちらをご利用させていただきます。
使用言語はJavaです。
たとえばRPGなどの場合、タイトル画面、ゲーム画面、ゲームオーバー画面などのシーンがあります。
これをどのように設計するのが正なのかがわからず、苦戦しています。
考えたのはGameControllerとTitleControllerなど、各シーンに応じて
抽象コントローラクラスを継承したコントローラを実装し、
メインループでは現在のシーンのコントローラを呼び出す、という方法です。
各コントローラはそれぞれ必要なmodelを内部でnewし、ユーザー操作に応じて呼び出し、
メインループから呼び出されているexecuteメソッドで対応するviewのupdateを呼ぶようにしています。
ただ、この方法だと共通で使用するmodelの問題が発生します。
(コントローラの引数に共通のmodelを渡してあげればいけますが・・・)
また、各viewの実装についてなのですが、
それぞれのコントローラ(ここではGameControllerとTitleController)に対応するviewを実装。
コントローラ同様に必要なmodelを持たせておき、それぞれのupdateメソッドで
modelのgetterを利用し、画面の描画を行っています。
問題となるのは、controllerとviewで共通のmodelを持つ必要がある。
(二つをnewするときに、全ての使用modelを作って渡す・・・?)
ゲーム用のダイアログなど、共通でし使用するviewの実装方法。
上記のように、この方法だといろいろと問題が発生し、美しくないソースになってしまいました・・・。
簡単で使いやすい方法や、参考になるサイトやサンプルソースなどご存知でしたら、
お手数ですがお教えいただけると助かります。
長くなってしまいましたが、以上よろしくお願いします。
MVCモデルでのRPG製作・設計
Re: MVCモデルでのRPG製作・設計
MVCよりはC無しのPMの方が好き (どっちかというとMVVM系の人) なので,偏りはあると思いますが……。
コントローラの役割は「入力をモデルに伝える」ただ一点です。
さらに,HTTPのように根本的に状態を持てない場合を除くと,根本的にモデルは常に存在する状態にあるはずです。
さらに,controllerがviewを触ることはないはずですが。
see) 【雑談】mixC++勉強会@Tokyo / 私のスライドの11ページ目の図
結局,MVCでの「PLを置く場所がない」という欠点がそのまま出ている感じです。
どうするにしても,「前の画面のModel」から「次の画面のModel」を得て,それをView/Controllerで利用する,ということになります。
Javaであるならば,あくまでフルステートのModelを作成できるはずです。
WebまわりのステートレスMVCを参考にしたりしていませんか。
先のスライドの末尾に参考となるリンクを載せていますので,参考になればと思います。
なんでコントローラがmodelをnewするのですか。はるさめ さんが書きました:各コントローラはそれぞれ必要なmodelを内部でnewし、ユーザー操作に応じて呼び出し、
メインループから呼び出されているexecuteメソッドで対応するviewのupdateを呼ぶようにしています。
ただ、この方法だと共通で使用するmodelの問題が発生します。
(コントローラの引数に共通のmodelを渡してあげればいけますが・・・)
コントローラの役割は「入力をモデルに伝える」ただ一点です。
さらに,HTTPのように根本的に状態を持てない場合を除くと,根本的にモデルは常に存在する状態にあるはずです。
さらに,controllerがviewを触ることはないはずですが。
see) 【雑談】mixC++勉強会@Tokyo / 私のスライドの11ページ目の図
遷移があった場合に,MVVM系だとWindowのDataContextに対応するVMを入れて終わりですが……。はるさめ さんが書きました:問題となるのは、controllerとviewで共通のmodelを持つ必要がある。
(二つをnewするときに、全ての使用modelを作って渡す・・・?)
ゲーム用のダイアログなど、共通でし使用するviewの実装方法。
結局,MVCでの「PLを置く場所がない」という欠点がそのまま出ている感じです。
どうするにしても,「前の画面のModel」から「次の画面のModel」を得て,それをView/Controllerで利用する,ということになります。
根本的なところで,Modelは状態を持っていますか。はるさめ さんが書きました:上記のように、この方法だといろいろと問題が発生し、美しくないソースになってしまいました・・・。
Javaであるならば,あくまでフルステートのModelを作成できるはずです。
WebまわりのステートレスMVCを参考にしたりしていませんか。
先のスライドの末尾に参考となるリンクを載せていますので,参考になればと思います。
Re: MVCモデルでのRPG製作・設計
ご返信ありがとうございます。
提示していただいた資料なども読んだのですが、不明な点がいくつかありましたので、
この機会に自分の勘違いと疑問を解決しようと、ご質問させていただきます。
>なんでコントローラがmodelをnewするのですか。
>コントローラの役割は「入力をモデルに伝える」ただ一点です。
>さらに,HTTPのように根本的に状態を持てない場合を除くと,根本的にモデルは常に存在する状態にあるはずです。
それぞれのControllerを作成するクラス(mainなど)で、必要なModelを作って保有しておき、
それぞれのControllerに渡してあげる、ということでしょうか。
簡易的にソースを書いてみました。
>さらに,controllerがviewを触ることはないはずですが。
毎フレーム画面を更新/表示するために、メインループとなるControllerに対応するViewを持たせておき、
呼んであげる、と考えていたのですが・・・。
そもそもゲームにおいて「Controllerがメインループ」という考えから違いますでしょうか。
以上、よろしくお願いします。
提示していただいた資料なども読んだのですが、不明な点がいくつかありましたので、
この機会に自分の勘違いと疑問を解決しようと、ご質問させていただきます。
>なんでコントローラがmodelをnewするのですか。
>コントローラの役割は「入力をモデルに伝える」ただ一点です。
>さらに,HTTPのように根本的に状態を持てない場合を除くと,根本的にモデルは常に存在する状態にあるはずです。
それぞれのControllerを作成するクラス(mainなど)で、必要なModelを作って保有しておき、
それぞれのControllerに渡してあげる、ということでしょうか。
簡易的にソースを書いてみました。
// メイン
int main() {
ModelA *modelA = new ModelA();
ModelB *modelB = new ModelB();
ControllerA contA = new ControllerA(modelA, modelB);
while (true) {
contA.execute();
}
return 0;
}
// コントローラクラス
class Controller {
private:
ModelA *modelA;
ModelB *modelB;
public:
void execute() {
// 操作に応じてModelの変更
// 歩くNPCなど処理するModelの呼び出し
modelA->moveNpc();
}
}
// ビュークラス(毎フレーム呼び出し、どこから・・・?)
class View {
private:
ModelA *modelA;
ModelB *modelB;
public:
void update() {
// NPCの座標などを取得し、画面更新
}
}
//
class ModelA {
public:
void moveNpc() {
// 確立に応じてNPCが移動する、など
}
}
毎フレーム画面を更新/表示するために、メインループとなるControllerに対応するViewを持たせておき、
呼んであげる、と考えていたのですが・・・。
そもそもゲームにおいて「Controllerがメインループ」という考えから違いますでしょうか。
以上、よろしくお願いします。
Re: MVCモデルでのRPG製作・設計
Modelはフルステートのものが一つあれば十分です。はるさめ さんが書きました:>なんでコントローラがmodelをnewするのですか。
>コントローラの役割は「入力をモデルに伝える」ただ一点です。
>さらに,HTTPのように根本的に状態を持てない場合を除くと,根本的にモデルは常に存在する状態にあるはずです。
それぞれのControllerを作成するクラス(mainなど)で、必要なModelを作って保有しておき、
それぞれのControllerに渡してあげる、ということでしょうか。
mainで作るなり,Singletonにしてしまっても良いでしょう。
Controllerは,必要とする一部分を受け取るなり,全体を受け取るなりすれば良いでしょう。
また,Controllerを複数必要としない,という作り方もありそうです。
シーン自体もModelの状態なので,Modelが抽象化された入力 (e.g. 「決定」など) を受け付けるようにすれば,Controllerを分割する必要性が薄れます。
フレームというのは,View側の都合です。はるさめ さんが書きました:>さらに,controllerがviewを触ることはないはずですが。
毎フレーム画面を更新/表示するために、メインループとなるControllerに対応するViewを持たせておき、
呼んであげる、と考えていたのですが・・・。
ということは,理想的な作りとしてはPLとして用意すべき物です。
現実的には,メインループはMVCの外側にあって,メインループ中で
- Controllerに対してユーザー入力の確認の要求 (必要に応じてControllerはModelをアップデート)
- Viewに対して表示の更新の要求
MVCを離れてPDSの実現ということだけであれば,ControllerがViewを触ってもよいと思います。
ただ,MVCというアーキテクチャを使うのであれば,ControllerがViewを触ってはいけません。
# MVPはControllerを兼ねるPresenterがViewを触るけれど,PLの置き場としてControllerがあるから。
違います。はるさめ さんが書きました:そもそもゲームにおいて「Controllerがメインループ」という考えから違いますでしょうか。
前回も書きましたが,Controllerの役割は「入力をModelに伝える」です。
フレームごとのアップデート信号も入力とみなすことはできますが,Controllerはそれを受け取ってModelに伝えることしかしません。
MVCは
- Model : ドメインの実装
- View : Modelを表示する
- Controller : 入力をModelに伝達する
Controllerは非常に薄い層になるはずです (入力を読み替えるだけだから)。
まずはGUIアプリケーションにおけるMVCについて調べてみてはどうでしょうか。
なんとなく,MVCフレームワークを使った「ダメな」Webアプリケーションの作り方を真似てしまっているように思えます。
# MVCフレームワークを使った「ダメな」Webアプリケーション : Controllerが肥大化したWebアプリケーション。ModelがDBのコピーだけだったりする