トップページ > 過去ログ > 記事閲覧
障害物との判定
名前:C言語経験一年目 日時: 2008/04/04 22:28

はじめまして。 アクションRPGを作っているのですが、バックバッファを利用して、自機とマップ上の障害物との辺り判定を、色の当たり判定でしようと思っているのですが、GetPixelの処理が遅いので、自機が移動するたびに色の当たり判定をしていては、起動できるPCのスペックが限られてしまうかも。というのが心配です。 まだゲーム作りには慣れておらず、色の当たり判定くらいしか障害物との接触判定が思いつきません。なにかほかに良い方法はないでしょうか?また、GetPixelを使わずに色の当たり判定を行うことはできるでしょうか?

Page: 1 |

Re: 障害物との判定 ( No.1 )
名前:初心者A 日時:2008/04/05 02:24

画像を認識させるのは恐らく効率的ではありません 通れるか通れないか判別専用の平面(これは画像ではなくただの配列変数)を作ってみては? たとえば・・・(このプログラム自体はこぴぺで動きませんのであしからず) int map[W][H]; //判定用の平面フィールドと同じサイズ #define WALL 0 //壁 #define GROUND 1 //地面 /* としてmapの中身にはWALLかGROUNDのいずれかが入っているようにする。 */ int charX,charY;//キャラクターの座標 loop{ if(→押された){ if(map[charX+1][charY] == GROUND ){//移動先は壁なのか道なのか? charX++;//道なのでキャラの座標を移動 } } } とか(〜ω〜`) ゲームの種類によって何が効率的かは変わってきますが・・・ 壁の少ないゲームでしたら、地面全てに通れるか通れないかではなく、壁がどこにあるのか?だけを変数に用意すればメモリの節約になりますし。 このサイトのテクニック集みたいなところにゲームの初歩的なことかかれてますので探せば何かみつかるかもしれません。
Re: 障害物との判定 ( No.2 )
名前:C言語経験一年目 日時:2008/04/05 12:21

初心者Aさん、回答ありがとうございます。 自分は簡単なRPGやシューティングなら作った経験があるので、配列も考えてはいたのですが、これだと動きがカクカクになってアクションには向かないと思うんです。色の当たり判定にしたのは、複雑な動きをしても、確実に障害物に当たると停止するからです。 SFCでいうと聖剣伝説(2か3)のような感じを目指しているのですが……何か手はないでしょうか。 答えをいただいたのに、また質問をしてしまってすみません。
Re: 障害物との判定 ( No.3 )
名前:初心者A 日時:2008/04/05 15:15

そうですね、1マスのサイズが大きく、かつ壁か通路かしか無いといった構造の場合、上記方法ではカクカクしますね。 てけとーな解決方法でしたら ・1マスのサイズを小さくする(1マス2ドット程度に分割とか・・(まぁこの場合壁データつくりが異常に面倒になりますが;;) また上記方法の場合主人公の大きさはcharX,charYの1ドットではなくcharSize(主人公座標から上下左右に何マス大きさを持つか),なんて変数でも追加して if(→押された){ bool wallFlag = false;//壁にぶつかるかフラグ for(int i=-charSize;i<=charSize;++i){ if(map[charX+charSize+1][charY+i] == WALL ){//移動先は壁なのか道なのか? 動 wallFlag = true; break; } } if(!wallFlag) charX++;//壁は無ので移動 } って、とか思いましたけど、これ移動力が2マスだと2回for回るし;charSize*2*移動力の判定ががが;; これはまずいかも;;まぁマスの多きさと物の数しだいですね;; さてじゃぁ他の方法ですが、 キャラの移動を1マス単位にせず1ドット単位にすればどーでせぅ int map[W][H]; //判定用の平面フィールド#define GRIDSIZE 16 //1マスのドット数 #define WALL 1 //壁 #define GROUND 0 //地面 さて、そして次にキャラクターの情報ですが、 double charX,charX,//今のいるマス int charSize,//キャラの大きさ double charSpd,//キャラの移動量 ここではcharX,Yは1マス単位ではなく1ドット単位とします。(別にドットである必要はないけど;; つまりmap[charX/GRIDSIZE][charY/GRIDSIZE]が今キャラの居るマスです ついでにdoubleにしてるのは、正直1フレームに1ドットずつ移動でも早すぎる場合が多いので小数を取っただけです。(固定小数点のが賢いですが;; とりあえず制約は、キャラのサイズは1マスと同じ大きさ、1フレームの最大移動量も1マス以下とします(そうしないと判定で見るマスが多くややこしいので・・・ if(→が押された){ int mapX = (charX+charSpd-GURIDSIZE/2)/GURIDSIZE; int mapY = (charY-GURIDSIZE/2)/GURIDSIZE; //-GURIDSIZE/2って何だって思うかもしれませんが //これによって必ずキャラは[mapX][mapY]〜[mapX+1][mapY+1]に居ることになります(キャラの大きさ=1マスの制限上ですが;; bool wallFlag = false; for(int addY = 0; addY < 2;++addY){ if(map[mapX+1][mapY+addY] == WALL){ wallFlag = true; break; } } if(!wallFlag) charX += charSpd; } ぅぁ、なげーそしてきめぇ、そして今思ったら、1マスの通路は通れないですねこれ; 必ず2マス以上の太さが必要;; 正直かなり汎用性をそいでます;; しかも、これを縦横に分けてかくのは正直お勧めしませんが;; ちょっと形を変えると入力から先に移動ベクトルだけだしてしまって、 そのご、移動先に壁があるならばそのまま、壁がなければ移動ベクトルのぶんだけ進む、とか・・・ とりあえず超カオスでしたぺこり、 あとこのサンプルは動作確認もコンパイル確認も何(手元のプログラム貼るとそれこそ長すぎになるので;; もしてませんので正直誰か良い解説サイトでも。。。
Re: 障害物との判定 ( No.4 )
名前: 日時:2008/04/05 18:09

2DのRPGのような場合のMAPであれば、初心者Aさんが 書いているようなチップを管理する配列内のデータ で当たりを取るのが楽ですね。 #ドラクエ風なMAPのイメージですね。 アクション性の高いものは、背景と、障害物を別々 に表示することで当たりを実装します。 こうすると障害物にも描画する位置情報が 必要になるのですが、それを元にキャラクタなどと 当たり判定を行うことが出来ます。 また、MAP背景からの相対的な位置を持たせることで スクロールなどが発生しても、障害物の位置を 把握できるので当たりは取れますし、敵キャラなどの配置や当たりも同じ方法で取ることが 可能に成ります。 #どこまで細かい判定を取りたいかという部分にも #繋がってくると思いますが方法はたくさんあるので #一例の過ぎませんが。 >>手元のプログラム貼るとそれこそ長すぎ MSNなどのアカウントをお持ちならSkyDriveとか 5GBくらい無料でスペースが使えるので、 固めたファイルなどをUPする方法もありますよ。 他のアップローダなどでパスワード付きで配布する とか出来ます。
Re: 障害物との判定 ( No.5 )
名前:C言語経験一年目 日時:2008/04/05 18:53

初心者Aさん、通さん。解答ありがとうございます。 なるほど。移動量をいじれば、確かに動きそのもの見栄えは良くなりますね。プログラムとしてどうかって言われると、確かにできれば書きたくないやりかたなのかもしれません……ですが、すごく納得しました。ありがとうございます。 通さんの言うように、障害物を敵などと同じように、「描く」のではなく「置く」というやりかたは、思いつきませんでした。なるほど。確かに当たり判定はすごく楽になるかもしれませんね。その分、把握しなければいけない情報量は倍増しますが。 マップの時点で制作が停滞していたのですが、皆さんのお陰でどうにか先に進めそうです。まだまだ学ぶべきことは多いということですね。貴重なご意見、ありがとうございました。

Page: 1 |