こちらの講座を参考にしつつシューティングゲームを製作しているのですが、
円と矩形(四角)の当たり判定を製作する部分で行き詰ってしまいました。
矩形が傾いていない時の判定は出来るのですが、矩形が傾いていた場合の判定計算の方法がわからないのです。
そこで過去ログを探っていたところ、管理人様がこちら(http://www.play21.jp/board/formz.cgi?ac ... &rln=24727)で分かりやすい判定方法を提示なさっていました。
分からないながらも自分なりに考えたところ、円から伸ばした十字(それぞれ四角の縦横に平行なもの)と四角から伸ばした十字(X軸Y軸に対してθ分だけ傾いたもの)との交点二点の座標を求め、そのそれぞれ二つと四角の中心の距離を求め、その長さがともに「円の判定の長さ+縦(または横)の判定の長さ」より小さければ当たりである、という処理を行えば良いと思いました。
しかし実際にプログラムへと落とし込んでみたところ、問題の十字同士の交点の座標を算出する方法がわかりません。
どなたか考え方なりヒントだけでも教えていただけないでしょうか。よろしくおねがいします。
一応、当たり判定を考える上で使っているプログラムのソースも載せておきます。
キーボード入力で円(当たり判定)が動きます。読み込んでいる画像は50×15ピクセルの塗りつぶしの四角です。
環境:WindowsXP VC++ 2008EE DXライブラリ
#include "DxLib.h" #include "math.h" #define PI 3.1415926535898 char Key[256]; int KeyBuf; int image; int hit=0; double cx=200, cy=200; double ex_cx=0, ex_cy=0; double c_range=10; double ex=640/2, ey=480/2; double tate=25, yoko=15; double ANGLE=0*(PI/180);//傾けたい角度 double x[4],y[4];//四角形の頂点四つの座標 double kyori[4],kyori_x,kyori_y;//当たり判定と比べる距離 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){ if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //初期化処理 SetDrawScreen( DX_SCREEN_BACK ); //描画先を裏画面に設定 SetDrawBlendMode( DX_BLENDMODE_ADD , 256 ) ;//これは気にしなくていい。 while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){ //↑メッセージ処理 ↑画面をクリア ↑キーボード入力状態取得 ↑ESCが押されると終了 // キー入力取得 KeyBuf = GetJoypadInputState( DX_INPUT_KEY_PAD1 ) ; // 上を押していたら上に進む if( KeyBuf & PAD_INPUT_UP ) cy -= 1 ; // 下を押していたら下に進む if( KeyBuf & PAD_INPUT_DOWN ) cy += 1 ; // 右を押していたら右に進む if( KeyBuf & PAD_INPUT_RIGHT ) cx += 1 ; // 左を押していたら左に進む if( KeyBuf & PAD_INPUT_LEFT ) cx -= 1 ; image=LoadGraph("1.png");//30×50の画像 x[0]=(ex-yoko);//左上 y[0]=(ey-tate); x[1]=(ex+yoko);//右上 y[1]=(ey-tate); x[2]=(ex-yoko);//左下 y[2]=(ey+tate); x[3]=(ex+yoko);//右下 y[3]=(ey+tate); //円と四角の四点 int i; for(i=0; i<4; i++){ kyori=sqrt((cx-x)*(cx-x)+(cy-y)*(cy-y)); if(kyori<=c_range) hit=1; } //ここから double point_x[2], point_y[2]; point_x[0]=;//??? point_y[0]=;//??? point_x[1]=;//??? point_y[1]=;//??? kyori_y=sqrt((cx-point_x[0])*(cx-point_x[0])+(cy-point_y[0])*(cy-point_y[0])); kyori_x=sqrt((cx-point_x[1])*(cx-point_x[1])+(cy-point_y[1])*(cy-point_y[1])); //ここまで if(kyori_x=c_range+yoko && kyori_y<=c_range+tate) hit=1; DrawCircle(cx,cy,c_range,GetColor(255,255,255), TRUE);//円形当たり判定(自機) DrawRotaGraphF(ex,ey,1.0,ANGLE,image,true);//矩形当たり判定(敵機) if(hit==1){ DrawString( 0,0,"○接触しています!!○",GetColor(255,255,0)); hit=0; } else DrawString(300,0,"×接触していません。×",GetColor(255,255,0)); ScreenFlip(); } DxLib_End(); return 0; }