Re: マップデータとの当たり判定 ( No.1 ) |
- 名前:ろぜ 日時:2013/09/08 03:09
今現在どんな感じなのかいまいちわからないのですが・・
30*60のキャラと32*32のマップチップ判定を本当にドストレートな感じで考えてみました。
32*32の四角形を考え、配列が0なら判定なし、1なら判定あり。
あとは単純に
for(i=0; i<□; i++)
{
for(j=0; j<△; j++)
{
if(map[j][i]==1)
{
//自機とマップ(四角形対四角形)の判定
if( HitCheck(i, j) ==1 ) break;
//マップの判定はi、jを使いRECT構造体で(left=32*i, top=32*j, right=left+32, bottom=top+32)
//自機のあたり判定はあらかじめ拡大縮小等して自機用RECTに入れておく。
}
}
}
こんな感じだと、多分
map[0][0]のときは{0,0,32,32}
map[1][0]のときは{0,32,32,64}
の四角形になってると思いますし、こう四角形に置き換えてしまえば自機のサイズがどうであろうと四角形同士なら判定できます
いちおう自機の当たり判定ですが、グラフィックの表示座標を左上にしているなら
{position_x, position_y, position_x+30, position_y+60 }こんな感じかなぁ
ただこれを毎回全部の配列要素とやると効率悪いので、まず当たらないだろう要素(画面外とか)
を抜いたりすればいくらか計算量は減るんじゃないでしょうか。
ガクガクするとのことですが
未来の座標で壁とあたった→未来の座標を壁との距離0に持っていく→実際の座標にする
こうしてしまえば仮に壁に進み続けようとしてもぴったりの座標を保つのではないでしょうか。
実際にやるなら・・
xの移動量がプラス→壁に当たったら1px左に戻す→
→その座標で再度判定し、当たらなくなるまで繰り返す→マップにあたる寸前の座標に
こんな感じ・・ですかね?
ただしこうするには、当たった壁が自分に対して前後左右どちらにあるかも考慮する必要があります。
(前後の壁にあたったらyだけ押し返す、左右ならxだけ とか)
見当違いなこと言ってたらすみません><
|
Re: マップデータとの当たり判定 ( No.2 ) |
- 名前:Talvisota 日時:2013/09/08 13:03
ろぜさん、ご回答ありがとうございます。
今のところ、質問が一つあるのですが、
HitCheckという名のint型関数の中身は、
int HitCheck(int a,int b){
int left, top, right, bottom;
int retval = 0;
left = SIZE * b;
top = SIZE * a;
right = left + SIZE;
bottom = top + SIZE;
int ax1 = Me.X + (Me.G_width - Me.B_width)/2;
int ay1 = Me.Y + (Me.G_height - Me.B_height)/2;
int ax2 = Me.X + (Me.G_width + Me.B_width)/2;
int ay2 = Me.Y + (Me.G_height + Me.B_height)/2;
if((ax1 < right)&&(ax2 > left)&&(ay1 < bottom)&&(ay2 > top)){
retval = 1;
}
return retval;
というようなものなのでしょうか。(Meは自機のことで、構造体宣言をしています)
まだアドバイスを受けての制作途中なためうまくいってはいません。これからだんだんと反映させていきたいと思っています。
|
Re: マップデータとの当たり判定 ( No.3 ) |
- 名前:ジュンヤ 日時:2013/09/08 14:52
マップデータとの当たり判定のコツは、次の移動予定座標を用いて、X軸とY軸各々別に判定することです。
それとマップチップの判定を総当たりでやっていると、少ない場合は良いのですが、
規模の大きなマップだとかなり遅くなってしまうので、判定するポイントを絞った方がよいと思います。
テキストデータを読み込んで、マップデータとの当たり判定を行っているサンプルを作ってみました。
以下のサンプルの様にすれば、グラフィックサイズを簡単に変えることもできますし、
高速な当たり判定を実現することができますので、よろしければ参考にしてください。
h ttp://w w w1.axfc.net/uploader/so/3021711.zip pass dxlib
|
Re: マップデータとの当たり判定 ( No.4 ) |
- 名前:ろぜ 日時:2013/09/08 23:32
ジュンヤさんのサンプルがとても細かく書いてあって果たして自分が続くべきかと悩んだけど一応^^;
bool HitCheck(int x,int y)
{
RECT SquareA,SquareB;
SquareA.left = Me.X + (Me.G_width - Me.B_width)/2 ;
SquareA.top = Me.Y + (Me.G_height - Me.B_height)/2 ;
SquareA.right = Me.X + (Me.G_width - Me.B_width)/2 ;
SquareA.bottom = Me.Y + (Me.G_height - Me.B_height)/2 ;
SquareB.left = SIZE * x ;
SquareB.top = SIZE * y ;
SquareB.right = SquareB.left + SIZE ;
SquareB.bottom = SquareB.top + SIZE ;
if( SquareA.left <= SquareB.right &&
SquareA.top <= SquareB.bottom &&
SquareA.right >= SquareB.left &&
SquareA.bottom>= SquareB.top
) return true;
return false ;
}
一応こんな感じですが、RECT使うかの違い程度ですし、正直判定さえできれば問題はないかと思います。
Me.GとBは画像のサイズと実際の判定のサイズ、と勝手に解釈したのですが、これでよかったですかね?
あと、引数のaはy、bはx成分を表しているのでしょうか?もしaがxのつもりならleftとtopが逆な気がします(値の渡し方次第ですが)
判定の絞り込みですが、自分の判定用四角形の頂点2つ(左上と右下)が含まれる要素を取得してもいいかもしれません。
[100][100]のような大きいマップのとき、左上が[4][10]、右下が[14][20]に含まれていた場合、forの部分は
for(i=10; i<20; i++)
{
for(j=4; j<14; j++)
{
みたいにやるとか。
これなら自分の判定の中の要素だけチェックできる、気がします。
・・ジュンヤさんのを見て気付きましたが、壁の座標は配列から簡単に呼べましたね。押し出しとかそんな面倒なことを・・
|
Re: マップデータとの当たり判定 ( No.5 ) |
- 名前:Talvisota(解決?) 日時:2013/09/16 18:52
返信遅れてすみません。
取りあえずうまくいきました。様々な部分で改良は必要ですが、どうにか改良していきたいと思います。
|
Re: マップデータとの当たり判定 ( No.6 ) |
- 名前:Talvisota 日時:2013/09/23 01:22
・・・解決、というわけにはいきませんでした。再びお世話になります。
ジュンヤさんから頂いたサンプルデータを参考に当たり判定処理を作ってみました。
・・・が、ここで問題が発生。自機はまだいいのですが、敵キャラクタがいうことを聴いてくれません。
具体的には、敵がマップデータでの障害物にあたる場所にぶつかったとき、
猛スピードで左側に移動してしまうのです。
多分、めり込んでしまっているのでしょうが、その解決策がわかりません。
はっきりとした答えではなくとも、どうか、アドバイスをお願いします。
|
Re: マップデータとの当たり判定 ( No.7 ) |
- 名前:管理人 日時:2013/09/25 00:59
自機と同じ処理を敵にも施せば正常に動作するはずです
敵が猛スピードで左側に移動してしまう箇所をブレイクポイントを使用して確認して、
何故自機では同じようなことにならないのかを調べれば原因が分かると思います
|