タイトルからメニュー画面→ゲームモードまでのフローを作っていきます。
メニュー画面周りのフロー一連はゲームの中でもおそらく最もフローが複雑かつ例外要素も多く入る可能性のある、
ある意味で最難関の一つなのではないでしょうか。
メニュー画面の実装はおそらくシューティング部分そのものよりも難しいです。
フローがあちこちいったりきたりするし何よりもドキュメント層を触るのがメインとなる部分だからです。
そしてメニュー画面はフローが多いです。東方ライクなゲームを作ると考えてもメニューには少なくとも
・ゲームモード
・リザルト
・オプション
・ミュージック
・終了
のようなフローになります。
また、ゲーム画面を選んだ場合は
難易度設定→装備選択→ゲームへ
というフローになるので非常にフローは長い。
リザルトは保存されたスコア、エントリーネームを難易度×最大レコード数
保存できるセーブ領域から持ってきて各レコードは自分の持ってくるべきレコードを見て
表示していく感じに作るのでこれはドキュメント層の参照になります。
オプションはキーコンフィグとサウンド設定なのでこれも当然ドキュメント扱い。
ミュージックルームはドキュメントではなくまぁ音楽を流す感じ。
ゲームモードからの難易度選択と装備選択はドキュメント層の参照になります。
非常に見るものは多いのですべてシーンにしたいところですが、できればメニュー画面は
入った段階でその画面で必要なリソースはすべて読み込み済みにしておきたいです。
必要なリソースは読み込み済みにしておく一方で、各画面は切り離したい!
なのでメニュー画面内で各フローを子タスクとして走らせることにしました。
メニュー項目選択画面のときはメニュー選択タスクを走らせ、
ゲームモードを選択したら難易度選択タスクが動きます。
各タスクは次にどのタスクを走らせるか、を持ちそれぞれのタイミングで次のタスクを動かすような感じにします。
というような部分の考案と実装をしておりました。
うん、だいぶ読みやすくなったような気がする。
あとはそろそろゲームドキュメントを作っていきます。
ゲームドキュメントとはゲーム中どこからでも触られる可能性のある領域といった感じ。
セーブデータにもなりうるしゲーム内の設定情報にもなりうる部分
シューティングの場合は選ばれた自機の種類IDとかゲーム内の獲得スコアとか
ショットパワーなどがそれに当たります。
ゲームオーバーからスコア登録画面へ遷移する場合は
ゲームタスク
ドキュメントに「ハイスコア更新かな?」と聞く
↓
ゲームドキュメント
スコアのハイスコア評価計算をする
ハイアスコアならtrue、
更新できないならfalse
↓
ゲームタスク
更新されてたらハイスコア登録ステートへ
更新されてないならそのままタイトルステートへ
というような感じで下の層にデータを管理させるとこの辺りは完全にアプリと分断できそうです。
というような仕組みを作っていきたい。
メニュー画面はまだまだ時間がかかりそう。
今の仕事が何時ぐらいに終わるかが勝負どころになりそうです。
ではでは...
【同人ゲーム日記】メニューとゲームドキュメント
【同人ゲーム日記】メニューとゲームドキュメント
最後に編集したユーザー せんちゃ on 2013年4月29日(月) 00:11 [ 編集 1 回目 ]
Re: 【同人ゲーム日記】メニューとゲームドキュメント
わたしは仕事がら、リソースの割り当てを優先して考えてしまいます。せんちゃ さんが書きました:非常に見るものは多いのですべてシーンにしたいところですが、できればメニュー画面は
入った段階でその画面で必要なリソースはすべて読み込み済みにしておきたいです。
必要なリソースは読み込み済みにしておく一方で、各画面は切り離したい!
256x256のテクスチャを同時に4枚までしか読み込んではいけない、みたいな縛りがよくあるので。
メモリの使用状況で割り当てはころころ変わるので、シーンとリソースを直結させません。
リソースマネージャーは独立していて、シーンとリソースの対応テーブルを作って、勝手に読み込んだり解放したりする仕組みです。
わたしにはそれがふつうなんですよね。
メニューのタスクはわたしは逆の考え方ですかね。
メニュー画面はふつうに作ります。
コードはGUIのコンポーネントと同じやり方で共通化します。
メニューはメニュー監視タスクの元で動いてメニュー監視タスクが状況に応じて遷移先を決定します。
オプションはタイトル画面で呼ばれることもポーズメニューで呼ばれることもありますけど、メニュー自身にはどこに遷移するか意識させません。
実装としてはシンプルに用意しておいたテーブルで切り替えるパターンが多いですけど。
最後に編集したユーザー ISLe on 2013年4月29日(月) 01:37 [ 編集 2 回目 ]
Re: 【同人ゲーム日記】メニューとゲームドキュメント
ISLeさん
私はどちらかというと「そのシーンで必要なワークはシーンの最初に全て取る」
という考え方が強いため、最初にそのシーンで利用するリソースを割り当ててしまいます。
リソースマネージャーは私も作るのですがどちらかというとリソースとアプリを切り離すため、
という意味合いが強く、
「ID何番を読み込んでくれといったらマネージャーでロードする、
ロードされたらスタックに積まれていってシーン終了時にまとめて開放する」
というような役割ですかね、
メニュー画面は各画面を全てタスクにしている感じです。
メニュー画面シーンというシーン内で遷移する子タスクみたいな感じで、
オプション、リザルト、難易度選択、ミュージックルーム、装備選択
などの画面毎に1つのタスクにして、シーン内のアップデートで現在指定されている
タスクだけを処理させる、といった感じです(UIなどのレイアウト系のものはシーンとは関係なく常にアップデートが呼ばれます)
各画面は「次に何処へ行くのか」と「前の画面はどこなのか」
で各UIの演出、挙動を変える必要があるためなのですが、この部分はいろいろと悩ましい部分ですね
私はどちらかというと「そのシーンで必要なワークはシーンの最初に全て取る」
という考え方が強いため、最初にそのシーンで利用するリソースを割り当ててしまいます。
リソースマネージャーは私も作るのですがどちらかというとリソースとアプリを切り離すため、
という意味合いが強く、
「ID何番を読み込んでくれといったらマネージャーでロードする、
ロードされたらスタックに積まれていってシーン終了時にまとめて開放する」
というような役割ですかね、
メニュー画面は各画面を全てタスクにしている感じです。
メニュー画面シーンというシーン内で遷移する子タスクみたいな感じで、
オプション、リザルト、難易度選択、ミュージックルーム、装備選択
などの画面毎に1つのタスクにして、シーン内のアップデートで現在指定されている
タスクだけを処理させる、といった感じです(UIなどのレイアウト系のものはシーンとは関係なく常にアップデートが呼ばれます)
各画面は「次に何処へ行くのか」と「前の画面はどこなのか」
で各UIの演出、挙動を変える必要があるためなのですが、この部分はいろいろと悩ましい部分ですね
Re: 【同人ゲーム日記】メニューとゲームドキュメント
以前の日記のコメントに書いたと思いますが、わたしもリソースは割り当て済みの考えのもとコードを書きますよ。
ただ、そのコードではリソースの『状態』をまったく意識しません。
遅延ロードは一時停止の考え方と同じと書きましたが、リソースの割り当てが済んでいなければメインを停止して割り当て済みなら再開します。
遅延が無ければ止まらないだけです。
止めるかどうかも更新メソッドを呼ばなければ止まるというだけのものです。
メインは止められたことを知らなくても良いし知る必要もないいうのが重要です。
(追記)
メインを止めるというのはフレームワークを止めるということではなく、マップの進行とか敵の発生とかゲームの進行に関するタスクを止めるということです。
例えばロードインジケータータスクは常に動いていて、ロードが長引けば画面に何か表示するといったふうにします。
わたしのメニューの実装は考えたらMVCでした。
各画面をどのように分割するかという問題です。
画面タスクがビュー(&コントローラー)で、監視タスクがモデルに当たります。
タイトル画面から呼ばれるオプションはフル項目だけど、ポーズメニューからのオプションでは変更できない項目があったり、変更したらリセットしてタイトル画面に戻る必要があったりといったとき、画面ごとに作ると制御構造が複雑になりませんか?
項目を変更した直後に「ゲームがリセットされますが変更しても良いですか?」といったダイアログを割りこませたりするのも簡単です。
それでも画面タスクはどの項目が特別なのかまったく意識する必要がありません。
設定が即座に反映されるか決定後に反映されるかとかも画面タスクが意識する必要ありませんし変えるのも簡単です。
ただ、そのコードではリソースの『状態』をまったく意識しません。
遅延ロードは一時停止の考え方と同じと書きましたが、リソースの割り当てが済んでいなければメインを停止して割り当て済みなら再開します。
遅延が無ければ止まらないだけです。
止めるかどうかも更新メソッドを呼ばなければ止まるというだけのものです。
メインは止められたことを知らなくても良いし知る必要もないいうのが重要です。
(追記)
メインを止めるというのはフレームワークを止めるということではなく、マップの進行とか敵の発生とかゲームの進行に関するタスクを止めるということです。
例えばロードインジケータータスクは常に動いていて、ロードが長引けば画面に何か表示するといったふうにします。
わたしのメニューの実装は考えたらMVCでした。
各画面をどのように分割するかという問題です。
画面タスクがビュー(&コントローラー)で、監視タスクがモデルに当たります。
タイトル画面から呼ばれるオプションはフル項目だけど、ポーズメニューからのオプションでは変更できない項目があったり、変更したらリセットしてタイトル画面に戻る必要があったりといったとき、画面ごとに作ると制御構造が複雑になりませんか?
項目を変更した直後に「ゲームがリセットされますが変更しても良いですか?」といったダイアログを割りこませたりするのも簡単です。
それでも画面タスクはどの項目が特別なのかまったく意識する必要がありません。
設定が即座に反映されるか決定後に反映されるかとかも画面タスクが意識する必要ありませんし変えるのも簡単です。
最後に編集したユーザー ISLe on 2013年4月29日(月) 18:53 [ 編集 8 回目 ]
Re: 【同人ゲーム日記】メニューとゲームドキュメント
なるほど、ロード中はゲーム処理を呼ばないように下を作るということですね。
シーン内で利用されているリソースは割り当て済みになっていることが前提、という感じに捉えています。
「ロードしているか否か」「ロード開始からどれくらい経過したか」はマネージャーのほうでカウントして
それらをトリガーにインジケーターを描画する、というようなロジックでしょうか。
例えばポップアップウィンドウなどの場合ですと
「どのボタンを有効化するか」や
「どのボタンを表示するか(利用するか)」
みたいなフラグを各項目に持たせ
有効フラグが落ちているのであればそこは動かせない(操作できない)、
表示フラグが立っていない項目は描画しない、
というような実装方法をするようにしています。
メニュー項目は共通して「何が押されたのか」というイベントだけを投げるように作ってしまえば
制御構造には悩まないと思っています。
オプションならばボリューム選択時に上が押されたら「ボリュームが上がった」というイベントのみを
親に投げてあげて、実際のボリュームのパラメータを上げるか下げるかは親側でやってしまう
難易度選択なら「選択された」という情報のみを投げてあげてあとは親がどこの難易度を選択されたかを持つ
というような感じです。
シーン内で利用されているリソースは割り当て済みになっていることが前提、という感じに捉えています。
「ロードしているか否か」「ロード開始からどれくらい経過したか」はマネージャーのほうでカウントして
それらをトリガーにインジケーターを描画する、というようなロジックでしょうか。
画面によって共通して使いまわす系のUIですと各項目の制御を行えるように作りますね。ISLe さんが書きました: タイトル画面から呼ばれるオプションはフル項目だけど、ポーズメニューからのオプションでは変更できない項目があったり、変更したらリセットしてタイトル画面に戻る必要があったりといったとき、画面ごとに作ると制御構造が複雑になりませんか?
例えばポップアップウィンドウなどの場合ですと
「どのボタンを有効化するか」や
「どのボタンを表示するか(利用するか)」
みたいなフラグを各項目に持たせ
有効フラグが落ちているのであればそこは動かせない(操作できない)、
表示フラグが立っていない項目は描画しない、
というような実装方法をするようにしています。
メニュー項目は共通して「何が押されたのか」というイベントだけを投げるように作ってしまえば
制御構造には悩まないと思っています。
オプションならばボリューム選択時に上が押されたら「ボリュームが上がった」というイベントのみを
親に投げてあげて、実際のボリュームのパラメータを上げるか下げるかは親側でやってしまう
難易度選択なら「選択された」という情報のみを投げてあげてあとは親がどこの難易度を選択されたかを持つ
というような感じです。
Re: 【同人ゲーム日記】メニューとゲームドキュメント
できるだけ関連性を持たせないように、表示タイミングはロードの開始タイミングだけ通知してあとは勝手に何秒後みたいにしますね。せんちゃ さんが書きました:「ロードしているか否か」「ロード開始からどれくらい経過したか」はマネージャーのほうでカウントして
それらをトリガーにインジケーターを描画する、というようなロジックでしょうか。
進捗メーターとかはアプリケーションのコンテキストを経由して通知するような仕組みにします。
割り当て済みが前提としても可能な限り並行かつ独立して動くようにします。
そのほうがデバッグしやすいですから。
それを判断するのがビューなのかモデルなのかが重要ですよ。せんちゃ さんが書きました:有効フラグが落ちているのであればそこは動かせない(操作できない)、
表示フラグが立っていない項目は描画しない、
というような実装方法をするようにしています。
描画ロジックの中で個別に表示フラグを見て判断するのではなくて、モデルが項目ごとの状態をビューに通知して、ビューは通知された状態に応じて項目を描画するというふうに分離することでコードの汎用性が増します。
実際のところビューのモジュールは一個あれば良くて、モデルはテーブルのデータ構造を工夫することでコードをシンプルにできます。
項目が完全に独立していればそれだけで良いのですが。せんちゃ さんが書きました:メニュー項目は共通して「何が押されたのか」というイベントだけを投げるように作ってしまえば
制御構造には悩まないと思っています。
ビューに判断のロジックを持たせると、連動する項目があると再描画のロジックが複雑になってコード量も増えます。
例えばサウンドのオン/オフ項目にはボリューム項目が連動する(その逆も)というフラグをテーブルに持たせます。
モデル内部では、項目の変更によって連動する項目にも変更されたというイベントが通知され、ビューには再描画が通知されます。
ビューは項目ごとに有効/無効や表示/非表示という属性だけを保持し、モデルからの通知によって属性が変化し、属性に応じて項目を描画します。
どうです?めちゃくちゃシンプルでしょう。
そうは見えないですか?
Re: 【同人ゲーム日記】メニューとゲームドキュメント
なんだか横からすいません…つい感動してしまって。
毎度ISLeさんとせんちゃさんの会話には勉強になっております。なんせ自分の取り組んでいることとのシンクロ率が高くて・・・
ここまでの内容を本にして売られたら、4ケタ円までなら飛びつきますよ。的な。
で、ビューとモデルの分離の話ですが。オプション画面のOKを押した後、タイトルに戻るか、ゲーム本編に戻るか、ボタンの見た目は同じだけども
やってることは違うから分離しよう、みたいな話ですよね? 確かにシンプルで、見た目と挙動をくっつけて考えている間は思いつかないやり方ですね・・・参考になりました。
毎度ISLeさんとせんちゃさんの会話には勉強になっております。なんせ自分の取り組んでいることとのシンクロ率が高くて・・・
ここまでの内容を本にして売られたら、4ケタ円までなら飛びつきますよ。的な。
で、ビューとモデルの分離の話ですが。オプション画面のOKを押した後、タイトルに戻るか、ゲーム本編に戻るか、ボタンの見た目は同じだけども
やってることは違うから分離しよう、みたいな話ですよね? 確かにシンプルで、見た目と挙動をくっつけて考えている間は思いつかないやり方ですね・・・参考になりました。
Re: 【同人ゲーム日記】メニューとゲームドキュメント
なるほどです。
ビューはあくまでも表示だけで表示の制御はモデル側ということですね。
モデルが描画しろ!とビューに頼んでビューはそれで描画する感じで。。。
よくよく考えるとGUIのツールとも通じるものがありますね、あれもフォームデザイナー(ビジュアル)と実装で分かれていますし。
シーンと考えるより純粋に一つのGUIと考えたほうがシンプルかつ汎用的な作りになりそうですね。
ビューはあくまでも表示だけで表示の制御はモデル側ということですね。
モデルが描画しろ!とビューに頼んでビューはそれで描画する感じで。。。
よくよく考えるとGUIのツールとも通じるものがありますね、あれもフォームデザイナー(ビジュアル)と実装で分かれていますし。
シーンと考えるより純粋に一つのGUIと考えたほうがシンプルかつ汎用的な作りになりそうですね。
Re: 【同人ゲーム日記】メニューとゲームドキュメント
SUEさん
どうもどうも、いつも見ていただいてありがとうございます。
私自身いろいろと悩んだり学んだりしているので、学習したことは日記に書くように心がけております。
自分が学習した知識が他の技術者から見てどのように感じるのか、というのがすごく気になるから、というのもありますが
いろんな方法論を知ることができるからです。
お互い勉強頑張りましょう~
どうもどうも、いつも見ていただいてありがとうございます。
私自身いろいろと悩んだり学んだりしているので、学習したことは日記に書くように心がけております。
自分が学習した知識が他の技術者から見てどのように感じるのか、というのがすごく気になるから、というのもありますが
いろんな方法論を知ることができるからです。
お互い勉強頑張りましょう~
Re: 【同人ゲーム日記】メニューとゲームドキュメント
メニューはレイアウトなどデザインのほうに圧倒的に手間がかかるし変更も多いですからね。
コード部分をほとんど変更しないで済むメリットは絶大です。
コード部分をほとんど変更しないで済むメリットは絶大です。