こんにちは。Kettyです(^^)
前回、アルゴリズムの質問をさせていただき、みけCATさんやusaoさんに大変お世話になりました。
その節はありがとうございました。
今回の質問は、件名のとおりで、
ゲーム開発でのスクリプトクラスとその他のクラスの扱いや構成についてです。
以下のような場合、どういう設計にするのが望ましいのか、あるいはどうするのが一般的なのか教えてください。
現在、RPGのようなマップ見下ろし型のアドベンチャーゲームを作っており、
次のようなクラス構成にしています。
■プレイヤークラス
プレイヤーキャラクターの座標や状態、画像などを管理します。
■スクリプトクラス
スクリプトファイルのスキャンや条件達成の監視、イベントの実行をします。
スクリプトファイルには、
分岐の条件と、キャラクターの台詞表示や座標移動などイベントを記述しています。
■メインシーンクラス
スクリプトクラス、プレイヤークラス、マップやBGMといった諸々のオブジェクトを管理します。
ここで例えば、
「プレイヤーが座標Aにきたらコレコレという台詞を表示して、座標Bに強制的に移動させる」
という処理を実現したいとします。
私の考えでは、
まず、スクリプトクラスが、プレイヤーの座標を知る必要があり、
座標Bへの移動もスクリプトクラスが指示しないといけないことから、
(メインシーンクラスが、)スクリプトクラスの各メソッドに対して、
プレイヤークラスのポインタを引数として渡せばいいのかなと考えたのですが、
このやり方はよくなさそうだと思いました。
なぜかと言うと、
例えば、今後、フィールド上に「町人」を追加したい思ったら、
スクリプトクラスに町人クラスのポインタを渡さないといけなくなるし、
フィールドマップの状況に応じて条件分岐したいと思ったら、マップクラスのポインタを渡さないといけなくなる。
BGMが止まったらこれこれする、といった条件を判定するためにはBGMクラスのポインタを・・・
というように、条件や実現したいイベントの要素が増えれば増えるほど、
スクリプトクラスに渡す引数が増やさなければならなくなることと、
突き詰めるとメインシーンクラスの役割をスクリプトクラスが丸ごと請け負ってしまうことになりそうで、
各オブジェクトをクラス化している意味がなくなってしまうように思えるのです。
質問に戻りますが、こういった場合、どのようにするのがよいのでしょうか?
このフォーラム(C言語何でも質問掲示板)含め、Web検索で調べられる範囲では調べたのですが、
行き詰まってしまいましたのでご教示ください。
ちなみに、実装は、DXライブラリとC++です。
プログラミングは初心者ではありませんが、スクリプトを使うゲーム開発は初心者です。
また、参考にしたのを挙げますと以下になります。
http://2dgames.jp/2012/05/23/rpg%E3%81% ... %E6%96%B9/
http://karetta.jp/book-node/game-programming/235295
これで全部ではないですが、主に上記です。
ゲームのスクリプトクラスとその他のクラスの扱いや構成について
Re: ゲームのスクリプトクラスとその他のクラスの扱いや構成について
スクリプトクラスは個々のオブジェクトに直接アクセスするのではなくメインシーンクラスを経由したほうがよいですね。
メインシーンクラスがすべてのオブジェクトを管理しているわけですから。
メインシーンクラスがすべてのオブジェクトを管理しているわけですから。
Re: ゲームのスクリプトクラスとその他のクラスの扱いや構成について
>h2so5 さん
ご回答くださり、ありがとうございます。
なるほど、メインシーンクラスを経由させるというのは、
各オブジェクトをスクリプトクラスから隠ぺいするためですよね。
では、引数が増えてゆくという問題はどのように解決すべきなのでしょうか?
つまり、経由のさせ方です。
いま、思いついたのは、構造体を使うことです。
疑似コードで表現するとこんな感じで考えました。
当初の構想よりもけっこうすっきりしそうです。
おおよそ一般的なやりかたに近づいていると考えて差支えないでしょうか?
ご回答くださり、ありがとうございます。
なるほど、メインシーンクラスを経由させるというのは、
各オブジェクトをスクリプトクラスから隠ぺいするためですよね。
では、引数が増えてゆくという問題はどのように解決すべきなのでしょうか?
つまり、経由のさせ方です。
いま、思いついたのは、構造体を使うことです。
疑似コードで表現するとこんな感じで考えました。
struct 構造体 {
int プレイヤーの座標 ;
int 町人の座標 ;
・・・
} ;
class メインシーン {
public:
void Update() {
// 経由用に構造体にセット
各オブジェクトの状態 values ;
values.プレイヤーの座標 = player->GetPos() ;
values.町人の座標 = macihbito->GetPos() ;
// スクリプトクラスに渡して条件分岐や加工してもらう
script->処理メソッド( values ) ;
// 各オブジェクトにSet
player->SetPos( values.プレイヤーの座標 ) ;
macihbito->SetPos( values.町人の座標 ) ;
}
void Draw() {
・・・
}
} ;
class スクリプト {
public:
void 処理メソッド( 構造体 & values ) { // 参照渡しで引数をもらう
// 条件判定
if( values.プレイヤーの座標 == 座標A ) {
values.台詞 = "あいうえお" ; // 台詞決定
value.プレイヤーの座標 = 座標B ; // 座標移動
}
・・・
}
} ;
おおよそ一般的なやりかたに近づいていると考えて差支えないでしょうか?
Re: ゲームのスクリプトクラスとその他のクラスの扱いや構成について
一般的なやりかたかどうかは分からないですが、シンプルなスクリプト言語であればこの方法でも問題ないでしょう。
スクリプトが本格的な場合には別の設計を考えたほうがよいと思いますが、いずれにせよスクリプト言語の機能が明確ではないので細かいことは言えません。
スクリプトが本格的な場合には別の設計を考えたほうがよいと思いますが、いずれにせよスクリプト言語の機能が明確ではないので細かいことは言えません。
Re: ゲームのスクリプトクラスとその他のクラスの扱いや構成について
>h2so5 さん
ご回答くださり、ありがとうございました。
このやり方でやってみます。
恐れ入りますが、私は、スクリプトの"シンプル"とか"本格的"という基準が分かっておりません。
いまのところ、スクリプト言語の機能としては、
先にあげさせていただいた例題くらいのものを実現できればよいと考えており、
他に実現したい事柄を自分自身が想像できませんので、たぶん、私がやろうとしていることはシンプルなのだろうだと思います。
これこれこうしたい場合、こんなんじゃダメだ・・・、みたいな壁にぶち当たった場合に
また質問させていただくかもしれませんが、いったんこのトピックは解決とさせていただきます。
この度はありがとうございました。
ご回答くださり、ありがとうございました。
このやり方でやってみます。
恐れ入りますが、私は、スクリプトの"シンプル"とか"本格的"という基準が分かっておりません。
いまのところ、スクリプト言語の機能としては、
先にあげさせていただいた例題くらいのものを実現できればよいと考えており、
他に実現したい事柄を自分自身が想像できませんので、たぶん、私がやろうとしていることはシンプルなのだろうだと思います。
これこれこうしたい場合、こんなんじゃダメだ・・・、みたいな壁にぶち当たった場合に
また質問させていただくかもしれませんが、いったんこのトピックは解決とさせていただきます。
この度はありがとうございました。