おはようございます。横スクロールアクションRPGを製作しているネカというものです。
今回は、具体的なバグや不具合に対するを質問するというよりは、どちらかというと皆様のさまざまな意見をご教授
いただきたく投稿させていただきました。
まず、私がC++を用いて制作している横スクロールアクションRPGは
・実際にプレイヤのドット絵キャラクタを動かす「アクションパート」と
・立ち絵を使ってプレイヤ同士が会話をしたり(ADVのようなイメージ)、会話の合間にキャラクタのドット絵をイベントに合わせて動かす
「イベントパート」
の二つからなります。
イベントは、プレイヤが特定の位置に到達したら実行されます。
以前の私は、アクションパートからイベントパートに入る際、「アクションパート」に「イベントパート」をかぶせるイメージをしていました。具体的には、マップチップやプレイヤはアクションパートですでに存在するので(具体的にはマップチップクラス、プレイヤクラス等が)、そのオブジェクトをそのまま利用していき、アクションパートにはない動作をイベントパートで補間をしていくといった形です。
しかし、この場合には、いくつもの欠点があります。
例えば、『ゲームの序盤でプレイヤがラストボスに挑むのだけれど、ラストボスに攻撃がはじかれてしまい(キィンというSEなどを発しながら)まったく歯が立たず、逆にラストボスの攻撃にプレイヤが吹き飛ばされてしまう。』
といったイベントがあるとします。
挙げられる欠点としては、
・「アクションパート」ならばプレイヤは攻撃を受けるとHPが減り、「イベントパート」ならばダメージを受けてもHPが減らない、というIF分岐
が必要
・イベントは、イベント中に必要な全てのオブジェクトに対して、アクセスができる必要があるため、オブジェクト指向のカプセル化を崩してしまう
前置きが長くなって申し訳ないですが、つまりは、「アクションパート」と「イベントパート」は完全に分離をしたほうがいいのではないかということです。
少なくとも、今回作成するゲームでは「イベントパート」で必要なことはドット絵の画像がアクションパートと同じように動いて見えることだけですから(イベント中にプレイヤがレベルアップするといったようなシステムが係る処理は必要ない)、そもそもプレイヤやラストボスといった区別をつける必要すらないように感じます。
そのため、イベントパートでは、「キャラクタを動かすというよりは、もっと単純に画像を動かしているだけ」を意識した処理を
させようかと考えています。
挙げられる欠点としては、アクションパートで読み込んだ画像を再び読み込まなければならないという点がありますが、プログラム中で
もしイベントパートなら、のIF分岐でソースコードが汚れてしまうことを考えると些細なことかなと思います。
まとまりに欠けた内容ではありましたが、私の「アクションパート」と「イベントパート」に関する考えは以上となります。
繰り返しになりますが、皆様なら、どういった処理で実装されるのかをご教授していただければと思います。
また、私の今回の記事に関してゲームプログラマとして根本的にアイデア(実装方法)の考え方が下手である等のご指摘
もいただけるととてもうれしく思います。
それでは、皆様の意見をお待ちしております。
アクションパートとイベントパートの機能の分離についての考え方
Re: アクションパートとイベントパートの機能の分離についての考え方
手動で動くか自動で動くかの違いだけでオブジェクト自体は変わらないわけですから、分離する必要はないと思います。
自分だったら特別にフラグを作るのではなく、イベント開始時にプレイヤーのステータスを無敵状態にして、終了時に解除します。
アクセスする必要のあるオブジェクトには、アクセスできるのが自然だと思います。
ネカ さんが書きました: 例えば、『ゲームの序盤でプレイヤがラストボスに挑むのだけれど、ラストボスに攻撃がはじかれてしまい(キィンというSEなどを発しながら)まったく歯が立たず、逆にラストボスの攻撃にプレイヤが吹き飛ばされてしまう。』
といったイベントがあるとします。
挙げられる欠点としては、
状態が違うのだから分岐するのは当たり前ではないでしょうか。ネカ さんが書きました: ・「アクションパート」ならばプレイヤは攻撃を受けるとHPが減り、「イベントパート」ならばダメージを受けてもHPが減らない、というIF分岐
が必要
自分だったら特別にフラグを作るのではなく、イベント開始時にプレイヤーのステータスを無敵状態にして、終了時に解除します。
意味がよく分かりません。ネカ さんが書きました: ・イベントは、イベント中に必要な全てのオブジェクトに対して、アクセスができる必要があるため、オブジェクト指向のカプセル化を崩してしまう
アクセスする必要のあるオブジェクトには、アクセスできるのが自然だと思います。
それは分離しすぎです。別のゲームになってしまいます。ネカ さんが書きました: 前置きが長くなって申し訳ないですが、つまりは、「アクションパート」と「イベントパート」は完全に分離をしたほうがいいのではないかということです。
少なくとも、今回作成するゲームでは「イベントパート」で必要なことはドット絵の画像がアクションパートと同じように動いて見えることだけですから(イベント中にプレイヤがレベルアップするといったようなシステムが係る処理は必要ない)、そもそもプレイヤやラストボスといった区別をつける必要すらないように感じます。
そのため、イベントパートでは、「キャラクタを動かすというよりは、もっと単純に画像を動かしているだけ」を意識した処理を
させようかと考えています。
挙げられる欠点としては、アクションパートで読み込んだ画像を再び読み込まなければならないという点がありますが、プログラム中で
もしイベントパートなら、のIF分岐でソースコードが汚れてしまうことを考えると些細なことかなと思います。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: アクションパートとイベントパートの機能の分離についての考え方
もし分離するとしてイベントパートで、アクションパートと同じようなコードが沢山出るとしたら、それこそ無駄と言うかコードが大きな意味で汚れています。
ネカさんが気持ち悪いって事が問題なので、設計を根本から見直すかネカさんの気に入るように組むしか無いわけですが、私などから見るとメンテナンス性の低下に見えるわけです。
>オブジェクト指向のカプセル化を崩してしまう
オブジェクトの設計に問題が有るのかもしれません。
ネカさんが気持ち悪いって事が問題なので、設計を根本から見直すかネカさんの気に入るように組むしか無いわけですが、私などから見るとメンテナンス性の低下に見えるわけです。
>オブジェクト指向のカプセル化を崩してしまう
オブジェクトの設計に問題が有るのかもしれません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: アクションパートとイベントパートの機能の分離についての考え方
わたしは、ネカさんが「アクションパート」とおっしゃる部分でもキャラの移動やエンカウント、ダメージなどすべてイベントとして実装します。
そうすれば「イベントパート」はシナリオデータを元に自動操縦するモジュールを動的に挟むだけです。
プレイヤはHPを憶えておくだけでHPを減らすかどうかは外部から制御するといったふうにするのが理想ですね。
そういった設計の話はこの掲示板で過去に何度か話題になってます。
そうすれば「イベントパート」はシナリオデータを元に自動操縦するモジュールを動的に挟むだけです。
プレイヤはHPを憶えておくだけでHPを減らすかどうかは外部から制御するといったふうにするのが理想ですね。
そういった設計の話はこの掲示板で過去に何度か話題になってます。
Re: アクションパートとイベントパートの機能の分離についての考え方
すみません。返信が大変遅くなりました。
>>h2so5さん
-状態が違うのだから分岐するのは当たり前ではないでしょうか。
-自分だったら特別にフラグを作るのではなく、イベント開始時にプレイヤーのステータスを無敵状態にして、終了時に解除します。
-意味がよく分かりません。
-アクセスする必要のあるオブジェクトには、アクセスできるのが自然だと思います。
まさしく、その通りですね。私はオブジェクト指向のカプセル化に関して行き過ぎた
解釈をしてしまい、「可能な限りアクセスできる窓口を少なくしなければならない」と
とらえてしまっていたようです。
また、状態が異なることによって分岐をすることも、当たり前ですね。
これも、私の分岐の多いソースコードはあまりきれいに見えないという偏見のせいですね。
単純な分岐の多さではなく、重要なのは無駄な処理があるかどうかで判断をしなければい
けませんよね。
-それは分離しすぎです。別のゲームになってしまいます。
上の2点のご指摘を受けて、今回の分離するという考えはおよそメリットのないということが
理解できました!
>>softyaさん
-もし分離するとしてイベントパートで、アクションパートと同じようなコードが沢山出るとしたら、
-それこそ無駄と言うかコードが大きな意味で汚れています。
確かにその通りです。プログラミングを始める際には、「同じ処理を2か所以上で書くことになったら関数化しろ」
と言われたものですが、私は、そのことを理解できていなかったようです。
-ネカさんが気持ち悪いって事が問題なので、設計を根本から見直すかネカさんの
-気に入るように組むしか無いわけですが、
-私などから見るとメンテナンス性の低下に見えるわけです。
確かに、私の感覚的なものが大きく影響していた気がします。
一番の理由は、「複雑な条件分岐になってしまい、バグが出るようなら、いっそのこと分けてしまおう」
というものです。でも、これは言い訳というか逃げでしかありませんね。
状態遷移の設計をきちんと行えれば全く問題がないわけですから(笑)
softyaさんがおっしゃる通り、メンテナンス低下というのもありますし、
やはり、関数呼び出しにはそれなりの負荷がかかるので、がっつりとした3Dゲームを
作ることになるとしたら、やはりこのままではいけませんね。
-オブジェクトの設計に問題が有るのかもしれません。
本当にこれにつきます・・・
設計に関してはまだまだ未熟ですし、設計より先に勢いで書いてしまいがちな時もあるので、
もっと訓練が必要ですね。
>>ISLeさん
-わたしは、ネカさんが「アクションパート」とおっしゃる部分でも
-キャラの移動やエンカウント、ダメージなどすべてイベントとして実装します。
-そうすれば「イベントパート」はシナリオデータを元に
-自動操縦するモジュールを動的に挟むだけです。
そうですね。それぞれの動作をイベント化しようという考えはあったのですが、
だからといって今回のようにパートの分離を行わなければならないといったことは
全くなかったですね。
-プレイヤはHPを憶えておくだけでHPを減らすかどうかは外部から
-制御するといったふうにするのが理想ですね。
当たり前のことなのかもしれませんが、私にとっては目から鱗です。
アイテムによってオブジェクトが回復をする場合、オブジェクトクラスがアイテムクラス
を受け取り、さらにアイテムクラスの回復量を取得するget関数を呼び出し、
オブジェクトクラス内で変更を加えるといったような考えを持っていました。
しかし、普通に考えれば、アイテムクラスがオブジェクトクラスのhpを直接
操作するほうが、実際の処理とマッチしていてごく自然かもしれません。
-そういった設計の話はこの掲示板で過去に何度か話題になってます。
よくチェックもせずに、すみませんでした。
これからは、過去に同じような内容の投稿がないかきちんと確認したいと思います。
みなさんのおかげで、今一度自分のコードの書き方を見直すことができました。
ありがとうございました。
>>h2so5さん
-状態が違うのだから分岐するのは当たり前ではないでしょうか。
-自分だったら特別にフラグを作るのではなく、イベント開始時にプレイヤーのステータスを無敵状態にして、終了時に解除します。
-意味がよく分かりません。
-アクセスする必要のあるオブジェクトには、アクセスできるのが自然だと思います。
まさしく、その通りですね。私はオブジェクト指向のカプセル化に関して行き過ぎた
解釈をしてしまい、「可能な限りアクセスできる窓口を少なくしなければならない」と
とらえてしまっていたようです。
また、状態が異なることによって分岐をすることも、当たり前ですね。
これも、私の分岐の多いソースコードはあまりきれいに見えないという偏見のせいですね。
単純な分岐の多さではなく、重要なのは無駄な処理があるかどうかで判断をしなければい
けませんよね。
-それは分離しすぎです。別のゲームになってしまいます。
上の2点のご指摘を受けて、今回の分離するという考えはおよそメリットのないということが
理解できました!
>>softyaさん
-もし分離するとしてイベントパートで、アクションパートと同じようなコードが沢山出るとしたら、
-それこそ無駄と言うかコードが大きな意味で汚れています。
確かにその通りです。プログラミングを始める際には、「同じ処理を2か所以上で書くことになったら関数化しろ」
と言われたものですが、私は、そのことを理解できていなかったようです。
-ネカさんが気持ち悪いって事が問題なので、設計を根本から見直すかネカさんの
-気に入るように組むしか無いわけですが、
-私などから見るとメンテナンス性の低下に見えるわけです。
確かに、私の感覚的なものが大きく影響していた気がします。
一番の理由は、「複雑な条件分岐になってしまい、バグが出るようなら、いっそのこと分けてしまおう」
というものです。でも、これは言い訳というか逃げでしかありませんね。
状態遷移の設計をきちんと行えれば全く問題がないわけですから(笑)
softyaさんがおっしゃる通り、メンテナンス低下というのもありますし、
やはり、関数呼び出しにはそれなりの負荷がかかるので、がっつりとした3Dゲームを
作ることになるとしたら、やはりこのままではいけませんね。
-オブジェクトの設計に問題が有るのかもしれません。
本当にこれにつきます・・・
設計に関してはまだまだ未熟ですし、設計より先に勢いで書いてしまいがちな時もあるので、
もっと訓練が必要ですね。
>>ISLeさん
-わたしは、ネカさんが「アクションパート」とおっしゃる部分でも
-キャラの移動やエンカウント、ダメージなどすべてイベントとして実装します。
-そうすれば「イベントパート」はシナリオデータを元に
-自動操縦するモジュールを動的に挟むだけです。
そうですね。それぞれの動作をイベント化しようという考えはあったのですが、
だからといって今回のようにパートの分離を行わなければならないといったことは
全くなかったですね。
-プレイヤはHPを憶えておくだけでHPを減らすかどうかは外部から
-制御するといったふうにするのが理想ですね。
当たり前のことなのかもしれませんが、私にとっては目から鱗です。
アイテムによってオブジェクトが回復をする場合、オブジェクトクラスがアイテムクラス
を受け取り、さらにアイテムクラスの回復量を取得するget関数を呼び出し、
オブジェクトクラス内で変更を加えるといったような考えを持っていました。
しかし、普通に考えれば、アイテムクラスがオブジェクトクラスのhpを直接
操作するほうが、実際の処理とマッチしていてごく自然かもしれません。
-そういった設計の話はこの掲示板で過去に何度か話題になってます。
よくチェックもせずに、すみませんでした。
これからは、過去に同じような内容の投稿がないかきちんと確認したいと思います。
みなさんのおかげで、今一度自分のコードの書き方を見直すことができました。
ありがとうございました。
Re: アクションパートとイベントパートの機能の分離についての考え方
プレイヤにとっては、魔法で回復するのもアイテムで回復するのも同じ回復だということですね。
例えば属性付き魔法攻撃とか属性の相性とか耐性とか調べて…なんて処理をプレイヤが抱え込むとあっという間に複雑怪奇なコードになります。
属性、状態、ダメージ/回復、等を分解して並列に置くことで構造をシンプルに保てます。
アルゴリズムを外部に出すことによる拡張性向上もメリットです。
例えば属性付き魔法攻撃とか属性の相性とか耐性とか調べて…なんて処理をプレイヤが抱え込むとあっという間に複雑怪奇なコードになります。
属性、状態、ダメージ/回復、等を分解して並列に置くことで構造をシンプルに保てます。
アルゴリズムを外部に出すことによる拡張性向上もメリットです。