【Dxlib使用】当たり判定プログラムの設計について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
オルゲ改

【Dxlib使用】当たり判定プログラムの設計について

#1

投稿記事 by オルゲ改 » 11年前

ユーザー登録しましたが画面が変わる度にログアウト状態になっているオルゲです。
そのせいで名前が重複してしまい改をつけています。
これからもよろしくお願いします。


現在、複数のモデルが存在するゲーム(FPS)を作っています。
モデルというのは椅子や机やドアや木などもう色々です。
さらに椅子という括りの中で複数の種類が存在します。

そこで、複数のモデルとプレイヤーとの当たり判定を効率的に行うには
どのようにプログラムを組むのがいいのでしょうか、と言うのが今回の質問になります。
当たり判定の処理は「Dxlib3Dアクション基本」で実装されている当たり判定コードを参考にさせて頂いています(と言うかほぼ丸パクリ)。

では現在開発中のゲームのファイルを説明します。

プレイヤーの処理↓(初期化、移動、描画、消去など・・)
Player_process.cpp,Player_process.h
椅子の処理↓(初期化、描画、消去、など・・)
Chair_process.cpp,Chair_process.h
机の処理↓(同上)
Desk_process.cpp,Desk_process.h

このように物ごとファイルが分けられています。

Chair_processの場合

#define CHAIR001 20 //(例)事務室の椅子の数
#define CHAIR002 35 //      ~
#define CHAIR003 7 // ~

int Model001[CHIAR001]; //(例)事務室の椅子
int Model002[CHIAR002]; //教室の椅子
int Model003[CHIAR003]; //ソファー
VECTOR Position001[CHAIR001];
VECTOR Position002[CHAIR002];
VECTOR Position003[CHAIR003];

上記のようにモデルを定義しています。椅子と言っても種類があるのです。数もまちまちで。
机も同じように定義されています。
「Dxlib3Dアクション基本」で実装されている当たり判定プログラムはまさに自分が考えている当たり判定の処理で
動作自体は完璧ですが、サンプルでわかりやすくするために一つのファイルにまとめられていて、当たり判定を行うモデルも一つだけを想定しているので
このように複数のモデルとの当たり判定をどう実装すればよいのか、よくわかりません。

Hitcheck関数のようなものを作ってそこに必要な値を放り込むのか・・しかしモデルによって数も違うし・・・
それと当たり判定を元にプレイヤーの位置を動かす必要もあります。(壁から押出や、床と判断された高さ(float y)をプレイヤーのPosition.yに入れるなど)

何か良い実装方法はないでしょうか。
よろしければご意見を頂けるとうれしいです。よろしくお願いします。


開発環境
Windows7 64bit
Visual Studio2010

zxc
記事: 79
登録日時: 11年前
住所: 日本の背骨(?)あたり

Re: 【Dxlib使用】当たり判定プログラムの設計について

#2

投稿記事 by zxc » 11年前

  C++をある程度しっている前提で話します。オーバーロードとクラスの継承で大部分が解決できる問題かと思います。

  椅子なら基底椅子モデルクラスを作り、それを継承したソファーなり背もたれ付き椅子なり(どうクラスわけするのが適切かは分かりませんが)様々な椅子を作ります。基底椅子クラスオブジェクトに対する処理だけでは足りないなら、派生椅子クラスごとに適切な処理を行う関数を作ることになると思います。

  たぶんこの掲示板でも特にSTGの敵の種類と自機弾との関係のような、似たような質問が幾つか見つかるかと思います。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 【Dxlib使用】当たり判定プログラムの設計について

#3

投稿記事 by softya(ソフト屋) » 11年前

>ユーザー登録しましたが画面が変わる度にログアウト状態になっているオルゲです。

IE10なら、IE8互換にするか別のブラウザを試してみてください。
他のブラウザでも、ブラウザを変えてみるのが方法です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

オルゲ
記事: 4
登録日時: 11年前

Re: 【Dxlib使用】当たり判定プログラムの設計について

#4

投稿記事 by オルゲ » 11年前

夜遅くなってしまいました
なんでかオルゲでログイン出来ているのでオルゲで書き込みます
「Dxlib3Dアクション基本」にある当たり判定を参考にしていると言いましたがそれが書かれているURLを貼っていなかったので今貼ります。
http://homepage2.nifty.com/natupaji/DxL ... ction.html

zxc さんが書きました:  C++をある程度しっている前提で話します。オーバーロードとクラスの継承で大部分が解決できる問題かと思います。

  椅子なら基底椅子モデルクラスを作り、それを継承したソファーなり背もたれ付き椅子なり(どうクラスわけするのが適切かは分かりませんが)様々な椅子を作ります。基底椅子クラスオブジェクトに対する処理だけでは足りないなら、派生椅子クラスごとに適切な処理を行う関数を作ることになると思います。

  たぶんこの掲示板でも特にSTGの敵の種類と自機弾との関係のような、似たような質問が幾つか見つかるかと思います。
zxcさん返答ありがとうございます
 私はC++に関してまだまだ未熟な部分が多いです。正直プログラム苦手です。

オーバーロードと継承を使うことで何となく各オブジェクトごとの当たり判定はできるような気がしました。なんとなく

例えば椅子のベースクラスを作り、当たり判定の関数をベースクラスで作成し
その関数を各椅子ごとオーバーロードすればいい。。と言うことでしょうか。


もう一つ問題がありまして、上の方に当たり判定のコードが書かれているURLを貼りましたが、当たり判定を考慮しプレイヤーを移動させ最終的な座標を決定しています。
つまりこれだと、プレイヤーの位置を決定する関数の中に当たり判定の関数を入れなくてはならない気がします。
この認識は合っているのでしょうか。
簡単に当たり判定を行う流れを説明していただけるとありがたいです。

椅子ベースクラス作る→当たり判定関数作る→各椅子クラス作る→ベースを継承→ごにょごにょごにょ→最終的にプレイヤーの座標決定!

こんな感じです。

STGのページも参考にさせて頂きます。

zxc
記事: 79
登録日時: 11年前
住所: 日本の背骨(?)あたり

Re: 【Dxlib使用】当たり判定プログラムの設計について

#5

投稿記事 by zxc » 11年前

  どのクラスに当たり判定のジャッジをさせるつもりかは分かりませんが、各オブジェクト同士の判定を行うのならば、その各オブジェクトに判定の機能をもたせるのではなく、判定専用のクラスを作るほうが良いかもしれません。その判定専用クラスは、(必要であれば)互いにぶつかりうるオブジェクトそれぞれに当たり判定の結果の情報を渡すような機能も持っているようなものになると思います。

  椅子のベースクラスと当たり判定のベースクラス(?)はまったくの別物だと思います。もちろん一緒にしてしまう設計も出来るでしょうし、それがより適切な状況もあるかもしれませんが・・・。あくまで椅子のベースもその派生も当たり判定処理の対象であって、当たり判定処理を行う権限を持つわけではないはずです。当たり判定関数が各椅子型ごとにオーバーロードするかどうかは、各椅子が当たり判定に関係した要素に差異を持つのならば必要でしょう(背もたれがある椅子とない椅子の両方で、背もたれについての当たり判定処理が必要だとは思えませんので)。 State/Strategyパターンなどを見ていろいろ検討してください。
  
  プレイヤーの位置を決定するのに当たり判定の情報が必要ということなら、関数内で情報を受け取っても良いのかもしれませんが、当たり判定の情報って、そこ以外では使わないのでしょうか?自分ならとりあえず当たり判定データをオブジェクトの当たり判定データメンバにコピーして、必要なときに使えるようにするかもしれません。どれが適切な設計なのかは、そのデータが必要になる頻度などを把握しているだろう製作者にしかわからないはずです。


  椅子とプレイヤーがあって、衝突・重なりの有無を知りたい->適切な判定関数が呼ばれるクラスに渡す->判定クラスからプレイヤーの位置を決定する何か(プレイヤー?)が情報を受け取る->プレイヤーがいろいろ情報を統合して位置決定
  こんな流れでしょうか。
  プレイヤーが自分で自身の位置を決めるのが適切かよく分かりませんが、外部のいろんな要素に左右されうるなら、それもそれ専用のクラスで決めてしまう方が良いかもしれません。

hide

Re: 【Dxlib使用】当たり判定プログラムの設計について

#6

投稿記事 by hide » 11年前

イスとソファとベンチなら継承だと思いますが
当たり判定を持つということを作るのであれば継承するよりも当たり判定を機能させるクラスをもたせるのがいいでしょうね。
イスの基底に当たり判定を持たせても机に実装できませんが、
当たり判定のクラスを作ってそれをメンバに持てば机にも応用出来ます。

逆に言えばプレイヤーの当たり判定も合わせてまとめられますね。

複数のモデルとプレイヤーとの当たり判定を効率的に行う ということについては
ゲームプログラマになる前に覚えておきたい技術 という本にいろいろ書いてあった気がします。
たくさんの物体との当たり判定とか書いてあったはずです。
数年前に某高専の図書室で見た記憶なので内容は若干うろおぼえではありますが 私にはためになりました。

オルゲ
記事: 4
登録日時: 11年前

Re: 【Dxlib使用】当たり判定プログラムの設計について

#7

投稿記事 by オルゲ » 11年前

zxcさん、hideさん
返答ありがとうございます。ひらめきました。
実は全てのオブジェクトに共通するObjectクラスを作ってありました。
そのクラスにはモデルの描画の関数を記述していたのですが(視界に入っていたら描画)
そこにHitcheck関数ってみようと思います。

zxcさんに言われて気づきましたが
確かに当たり判定の情報は他にも使う可能性があるのでそれも考慮したいと思います。言われなきゃ気づきませんでした

ゲームプログラマになる前に覚えておきたい技術
これ家にないけど図書館にあるので読んでみます。この本を読んでしまうとコードを全て直してしまいたくなるような気がして
ゲーム作成中に読むのを躊躇っていましたがさっそく読んでみます。

zxc
記事: 79
登録日時: 11年前
住所: 日本の背骨(?)あたり

Re: 【Dxlib使用】当たり判定プログラムの設計について

#8

投稿記事 by zxc » 11年前

オルゲ さんが書きました:zxcさん、hideさん
返答ありがとうございます。ひらめきました。
実は全てのオブジェクトに共通するObjectクラスを作ってありました。
そのクラスにはモデルの描画の関数を記述していたのですが(視界に入っていたら描画)
そこにHitcheck関数ってみようと思います。
  その設計が適切なら何も言いませんが、すべてのObjectが自身とその他との衝突を調べるというのはあまり適切ではないだろう、と書いたつもりです。何故なら1つの衝突について2回判定されうる(椅子から見た椅子とプレイヤー、プレイヤーから見たプレイヤーと椅子で2回)と考えられる、また、「Objectであること」と「当たり判定を持ち、更にそれについて知ることができる」この2つは別のことだと思うからです。
  あくまでobjectは(判定クラスが当たり判定を算出できるような)データを持ち、さらにそのデータを判定クラスに渡すことが出来る程度にして、そこから当たり判定を出すのは外部の判定クラスに任せてしまうような設計を自分なら考えます。
 
 もし解決なら解決にチェック入れえてくださいね。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 【Dxlib使用】当たり判定プログラムの設計について

#9

投稿記事 by softya(ソフト屋) » 11年前

こちらのISLeさんの回答とか参考になるんじゃないでしょうか。
「キャラ同士の重なりについて • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3&t=13231
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: 【Dxlib使用】当たり判定プログラムの設計について

#10

投稿記事 by ISLe » 11年前

当たり判定はモデルデータを使ってレイ(直線)と交差するポリゴンがあるかどうかで判定しますよね。
モデルハンドルで区別できるので、特に継承する必要はないと思いますし、椅子以外のモデルと区別する必要もないと思います。

当たり判定自体はすべての組み合わせを行う以外にないですから、とりあえずモデルが重なっているかどうかを画面に表示するだけのコードでも書いてみてはいかがでしょうか。
当たり判定の組み合わせ方のアルゴリズム自体は3Dも2Dも違いはありません。

レイを飛ばすのは重い処理なので、あらかじめモデルがすっぽり入る立方体を計算で求めておいて、まずX,Y,Z座標の大小比較だけでレイを飛ばすかどうかを決めるといった方法などでゲーム全体が重くならないようにしますが、そういったことは実際に重くなってから考えれば良いことです。

オルゲ
記事: 4
登録日時: 11年前

Re: 【Dxlib使用】当たり判定プログラムの設計について

#11

投稿記事 by オルゲ » 11年前

zxc さんが書きました:   その設計が適切なら何も言いませんが、すべてのObjectが自身とその他との衝突を調べるというのはあまり適切ではないだろう、と書いたつもりです。何故なら1つの衝突について2回判定されうる(椅子から見た椅子とプレイヤー、プレイヤーから見たプレイヤーと椅子で2回)と考えられる、また、「Objectであること」と「当たり判定を持ち、更にそれについて知ることができる」この2つは別のことだと思うからです。
  あくまでobjectは(判定クラスが当たり判定を算出できるような)データを持ち、さらにそのデータを判定クラスに渡すことが出来る程度にして、そこから当たり判定を出すのは外部の判定クラスに任せてしまうような設計を自分なら考えます。
 
 もし解決なら解決にチェック入れえてくださいね。
zxcさん
オブジェクトが自身と他の衝突と言うのは、例えば椅子と机、椅子とプレイヤーの衝突ということでよいのでしょうか。
椅子からみたプレイヤー、プレイヤーから見た椅子の意味がちょっとよくわかりませんすいません。
プレイヤーとオブジェクトの当たり判定は行いますが基本的にオブジェクトとオブジェクトの当たり判定は行いません。

外部の判定クラスと言うのものは、データを入れてやりプレイヤーの位置を算出する機能を持つクラスってことですか?


私がプログラムについて未熟ゆえに説明がヘタで曖昧で非常に申し訳ないと思っておりますがもう一度おさらいすると

椅子にはChair_process.cppというファイルがあり机にはDesk_process.cpp・・・と言うようにゲームに登場するオブジェクトごとにファイルが分割されています。
椅子は何種類も存在するためベースの椅子クラスを作ります。
プレイヤーの位置を決めるのはPlayer_process.cppの中のPlayer_moveという関数の中で行うとします。
Player_move関数の中では「Dxlib3D基本アクション」の当たり判定にちなんで
オブジェクトとの衝突を考慮しスライドさせたり、床ポリゴンをy座標を値をVECTOR Nowposに入れプレイヤーの位置を決定しています。当たり判定に必要となる主なデータはモデルのポリゴン情報(int Model)とプレイヤーのポジション、プレイヤーのステータスフラグです
さて、「Dxlib3D基本アクション」ではモデルがひとつで、更に同じファイルの中に存在したのですんなりPlayer_moveの中で当たり判定と位置決定ができましたが
モデルが複数ある場合
どのように沢山のオブジェクト達と当たり判定をしてプレイヤーを動かすか、

というおさらいです。。


おそらくこれではややこしいので少し質問を変えさせて頂きたいと思いました。
「Dxlib3D基本アクション」のページで当たり判定を行なっている部分があります。
もしファイルがStage.cpp,Player.cppと分けられていた場合どのように当たり判定を行いますか?

Stage.cppでは

コード:

class Stage{
private:
      int Model;
      VETOR Position;
public:
     void Initialize(){
        Model = MV1LoadModel("Stage.mqo");
        Positon = VGet(0.0f,0.0f,0.0f);
        MV1SetupCollInfo( Model, -1 );
}
     void Draw();
};
こんな感じに書かれてるとします。
これでステージとプレイヤーとの当たり判定が差し支えなく行えると
モデルが複数単体と言う違いはありますが殆ど問題解決出来ると思います!
解決まであと少しです。がんばります

この際モデルが沢山あればその分当たり判定の関数呼び出してやればいいんです。もちろんプレイヤーとの距離が一定以下のモデルのみ判定を行う 
などで処理を軽くすればいいのです。

zxc
記事: 79
登録日時: 11年前
住所: 日本の背骨(?)あたり

Re: 【Dxlib使用】当たり判定プログラムの設計について

#12

投稿記事 by zxc » 11年前

オルゲ さんが書きました:
プレイヤーとオブジェクトの当たり判定は行いますが基本的にオブジェクトとオブジェクトの当たり判定は行いません。

外部の判定クラスと言うのものは、データを入れてやりプレイヤーの位置を算出する機能を持つクラスってことですか?


おそらくこれではややこしいので少し質問を変えさせて頂きたいと思いました。
「Dxlib3D基本アクション」のページで当たり判定を行なっている部分があります。
もしファイルがStage.cpp,Player.cppと分けられていた場合どのように当たり判定を行いますか?
  それなら判定を行うクラスを外部に独立させる必要はなさそうなのでプレイヤーがもつ関数なりクラスなりで行ってください。外部の判定クラスというのはobject同士の衝突を判定するクラスで、前提としてプレイヤーも椅子も机もobjectであると勝手に考えてしまいましたが、そうでないならプレイヤーが持っても良いんじゃないでしょうか。

  あくまで判定クラスは衝突について教えてくれるだけです。当たり判定と移動は切り離せないくらい密接な関係のものだと思いますが、別のことだと思います。

  ファイルの分け方と当たり判定には何の関係もないと思いますが、どういうことでしょうか。もしファイルの分割で何かしら問題が生じるのなら、それはまた別の課題であるはずです。自分が言っていたのは型が違うものに対して似た処理を行う方法のつもりです。

オルゲ
記事: 4
登録日時: 11年前

Re: 【Dxlib使用】当たり判定プログラムの設計について

#13

投稿記事 by オルゲ » 11年前

遅くなりました
なんとか各オブジェクトと当たり判定ができましたので解決にさせて頂きます
返答くださった方々ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る