• 締切済み

当たり判定の処理がわかりません。

CとDXライブラリでSTGを作っているのですが、あたり判定がわかりません。前、斜め右上、斜め右下の3方向に飛ぶ弾の処理を行いたいのですが、どうすればいいのでしょうか? 画面に出力することはできたのですが、ななめに飛ぶ弾だけ判定できずに困っています。 ―――――――――ソースの一部――――――――――― //拡散する弾 void JitamaMove2(){ //弾の発射 int key = GetJoypadInputState(DX_INPUT_KEY_PAD1); if( (key & PAD_INPUT_A) && (trigger == 0) ) { for( int i = 0; i < 3; i++ ){ if (jitama[i].life == 0){ jitama[i].life = 1; jitama[i].x = jikidata.x+24; jitama[i].y = jikidata.y+8; jitama[i].y1 = jikidata.y+8; jitama[i].y2 = jikidata.y+8; float dy = jikidata.y; float d = sqrt(dy*dy); jitama[i].yobi = dy/d*idouryou[4]*10; break; } } trigger = 20; } if(trigger>0) trigger = trigger - 1; //弾の移動 for(int i=0; i<3; i=i+1){ if(jitama[i].life > 0){ jitama[i].x = jitama[i].x + idouryou[10]; DrawGraph(jitama[i].x, jitama[i].y,*(jitama[i].ghandle), TRUE); float idouy = (float)jitama[i].yobi / 10; jitama[i].y2 = jitama[i].y2 - idouy; DrawGraph(jitama[i].x, jitama[i].y2 - 10, *(jitama[i].ghandle), TRUE); //斜め下に対する弾の描写 jitama[i].y1 = jitama[i].y1 + idouy; DrawGraph(jitama[i].x, jitama[i].y1 + 10, *(jitama[i].ghandle), TRUE); //斜め上に対する弾の描写 //画面外に出たときの処理 if(jitama[i].x>640) jitama[i].life = 0; } } } /*当たり判定を計算する関数*/ int IsAtari(CharaData *a, CharaData *b){ int retval = 0; int ax1 = a->x + (a->image_w - a->bounds_w)/2; int ay1 = a->y + (a->image_h - a->bounds_h)/2; int ax2 = a->x + (a->image_w + a->bounds_w)/2; int ay2 = a->y + (a->image_h + a->bounds_h)/2; int bx1 = b->x + (b->image_w - b->bounds_w)/2; int by1 = b->y + (b->image_h - b->bounds_h)/2; int bx2 = b->x + (b->image_w + b->bounds_w)/2; int by2 = b->y + (b->image_h + b->bounds_h)/2; if( (ax1<bx2) && (bx1<ax2) && (ay1<by2) && (by1<ay2) ){ switch (a->amode){ case A_NORMAL: //キャラ消滅 a->life = 0; break; case A_HARD: //耐久力-1 a->life = a->life -1; break; } switch (b->amode){ case A_NORMAL: //キャラ消滅 b->life = 0; break; case A_HARD: //耐久力-1 b->life = b->life -1; if(b->life > 0) SetHanten(b->x, b->y, b->image_w, b->image_h); break; } if(b->life == 0) SetBakuen(b->x, b->y); retval = 1; } return(retval); } //当たり判定の処理 int AtariHantei(){ for(int i=0; i<50; i=i+1){ if(tekidata[i].life > 0 && tekidata[i].amode != A_GHOST){//A_GHOS・・・判定なし //自機と敵の判定 if(IsAtari(&jikidata, &tekidata[i])==1) return(1); //弾と敵の判定 for(int j=0; j<3; j=j+1){ if(jitama[j].life > 0 && jitama[j].amode != A_GHOST){ IsAtari(&jitama[j], &tekidata[i]); } } } } for( int i = 0; i < 50; i++ ){ if(tekitama[i].life > 0){ if(IsAtari(&jikidata, &tekitama[i]) == 1) return(1); } } return(0); }

みんなの回答

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.1

★弾をどう管理しているのでしょうか? >画面に出力することはできたのですが、ななめに飛ぶ弾だけ判定できずに困っています。  ↑  弾の座標が判定したい座標と違うから上手く判定できていないように思います。  弾の当たり判定は何時呼び出しますか?  普通は弾が移動した後で判定しますが…。  ※自機、自機弾、敵機、敵機弾の移動タイミングは同じですか? ・ソースを見ましたが良く分かりません。  当たり判定は次の4パターンあります。  (1)『自機の移動』と『敵機/敵機弾』の当たり判定  (2)『敵機の移動』と『自機/自機弾』の当たり判定  (3)『自機弾の移動』と『敵機』の当たり判定  (4)『敵機弾の移動』と『自機』の当たり判定  これを上手に判定するには自機、自機弾、敵機、敵機弾を1つのオブジェクトとして  管理します。そうすれば当たり判定を1つの共通な関数に出来て便利なのですが。  ソースを見た感じ違う構造のようですね。  斜めだけ判定できないということはY座標がずれているのかも。  当たり判定の関数を整理した方が良いでしょう。  まず次の関数を用意します。  (1)自機本体との衝突チェック⇒int JikiCheck(x,y,w,h)  (2)自機弾丸との衝突チェック⇒int JikiShotCheck(x,y,w,h)  (3)敵機本体との衝突チェック⇒int EnemyCheck(x,y,w,h)  (4)敵機弾丸との衝突チェック⇒int EnemyShotCheck(x,y,w,h)  これらの関数は与えられた引数(x,y,w,h)より衝突すれば 1 を返す仕様です。  この4つの関数を用意したら自機などが移動した時の当たり判定を作ります。  (1)『自機の移動』と『敵機/敵機弾』の当たり判定⇒void JikiCrash()  (2)『敵機の移動』と『自機/自機弾』の当たり判定⇒void JikiShotCrash()  (3)『自機弾の移動』と『敵機』の当たり判定⇒void EnemyCrash()  (4)『敵機弾の移動』と『自機』の当たり判定⇒void EnemyShotCrash()  この4つは上記の Check 関数を呼び出して当たり判定します。  例えば(1)なら次のようになります。 サンプル: // 『自機の移動』と『敵機/敵機弾』の当たり判定 void JikiCrash( void ) {  // 自機と敵機の判定  for ( int i = 0 ; i < 50 ; i++ ){   if ( TekiData[i].life > 0 ){    int x = TekiData[i].x;    int y = TekiData[i].y;    int w = TekiData[i].image_w;    int h = TekiData[i].image_h;        if ( EnemyCheck(x,y,w,h) ){     // 衝突処理    }   }  }  // 自機と敵機弾の判定  for ( int i = 0 ; i < 50 ; i++ ){   if ( TekiTama[i].life > 0 ){    int x = TekiTama[i].x;    int y = TekiTama[i].y;    int w = TekiTama[i].image_w;    int h = TekiTama[i].image_h;        if ( EnemyShotCheck(x,y,w,h) ){     // 衝突処理    }   }  } } このように関数を整理して作り上げればバグも入りにくくなります。 本当なら自機、自機弾、敵機、敵機弾の座標だけを共通に管理する方法を考え 作り直せば当たり判定もスッキリ出来ます。時間があれば全ソースを見直して シューティング・ゲームの設計をやり直すべきです。本当はね。 もう随分と作りこんでいるのでバグを見つけるのが大変です。 IsAtari関数が多分原因ではないかと推測します。 頑張って下さい。

関連するQ&A

  • Java ブロック崩し 当たり判定

    こんにちは、Java初心者の者です。 今週の末に、文化祭があるので、その際の出し物で「ブロック崩し」を出すことにしたのですが、 ブロックの当たり判定がおかしいのです。 おかしいというか、正確にはブロックとの当たり判定自体はあるのですが、ブロックと当たったらブロックが消えるようにしているはずが、消えないのです。 一応、消えてはくれるのですがボールとブロックが離れたらまた元の色に戻ってしまいます。 フラグ管理を使っての処理で、ボールとブロックが触れたらフラグを「偽」。そしたらそれに該当するブロックを描画しないようにする仕組みなのですが、どうも上手くいきません。 以下コードです。 ~~~~中略~~~~ //ブロックの座標の設定 int k=0; for(int j=0;j<block_r;j++) { for(int i=0;i<block_g;i++) { block_x[k] = i*block_w; block_y[k] = j*block_h; block[k] = 1; flag[k] = true; k++; } } //ブロックに当たった時の処理 for(int i=0;i<30;i++) { if(flag[i] == true) { if(y + ball_y >= block_y[i] && y <= block_y[i]+block_h && x + ball_x >= block_x[i] && x <= block_x[i] + block_w) { vy = -vy; flag[i] = false; } } } //ブロックの描画 for(int i=0;i<30;i++) { if(flag[i] == true ) { //ブロックの描画 offg.setColor(Color.yellow); offg.fillRect(block_x[i],block_y[i],block_w,block_h); //ブロックの枠線 offg.setColor(Color.black); offg.drawRect(block_x[i],block_y[i],block_w,block_h); } } ~~~~中略~~~~~ paintメソッドの部分だけ載せてます。 どこかおかしいところがあれば、アドバイスを頂ければ幸いです。 宜しくお願い致します。

    • ベストアンサー
    • Java
  • シューティングゲームの当たり判定

    現在directxを用いた(DXライブラリは使わない)インベーダーゲームを作っているのですが、当たり判定の部分がなぜかうまくいきません。自機と敵の弾の当たり判定部分のコードを載せるのでどなたかご享受ください。 //============敵の攻撃======================== if(enemy[rand_atk].tamaflag == 0 && shot_save % 100 == 0 ){ __enemy[rand_atk].tamaflag = 1; __enemy_atk[rand_atk].x = enemy[rand_atk].x+17; __enemy_atk[rand_atk].y = enemy[rand_atk].y+17; } for(i = 0; i < 11; i++){ __if(enemy[i].tamaflag == 1){ ____enemy_atk[i].y+=1; ____if(enemy_atk[i].y >= 480){ ______enemy[i].tamaflag = 0; ______enemy_atk[i].y = -20; //画面外へ ____} ____if( ( move.x - 7 < enemy_atk[i].x && move.x + 32 > enemy_atk[i].x ) && ________( move.y - 13 < enemy_atk[i].y && move.y + 24 > enemy_atk[i].y ) ){ ______move.zanki--; ______enemy[i].tamaflag = 0; ______enemy_atk[i].y = -20; //画面外へ ____} __} } move.x,move.yは自機のx,y座標で横32縦24 敵の弾の大きさは横7縦13 rand_atkはrand_atk = timeGetTime() % 11;でランダムに攻撃させようとしています。

  • 直線と点の距離を使って当たり判定を作りたいのですが

    こんばんは、C++のゲームプログラミングで、当たり判定を作成しているのですが、どうしても上手くいかず、困っています。 エラー等ではなく、単純にどこが間違っているのか解らない、といった類の質問をするのはあまり良く無いのかもしれませんが、自分ではどうすればいいのか解らないので、ここで質問させて頂きます、よろしくお願いします。 作りたいのは、あるオブジェクトCの頂点の座標から直線の方程式、ax+by+cの、a,b,cを求め、接触しているからを確認したいオブジェクトTの頂点座標との距離を |ax0+by0+c|/√a*a+b*b の式を使って求めるプログラムです。 ソースコードは以下になります。 bool Object::Check_Collision2(Object Collision) { Sub_bShow(false);//自分自身には処理をしない。 point C[5]={0};//対象の頂点4つ、計算しやすいように配列は5つまで作ってある。 point T[4]={0};///呼び出し側のオブジェクトの頂点4つ double C_Distance = sqrtf((Collision.Ref_x_size()/2*Collision.Ref_x_size()/2)+(Collision.Ref_y_size()/2*Collision.Ref_y_size()/2));//中心から頂点までの距離を計算 double T_Distance = sqrtf((Ref_x_size()/2*Ref_x_size()/2)+(Ref_y_size()/2*Ref_y_size()/2)); for(int i=0;i<=3;i++) { //頂点の値を配列に代入 C[i].x = Collision.Ref_x() + cos((Ref_Angle()+45+(90*i)) * PI / 180.0f) *C_Distance; C[i].y = Collision.Ref_y() + sin((Ref_Angle()+45+(90*i)) * PI / 180.0f) *C_Distance; T[i].x = Ref_x() + cos((Ref_Angle()+45+(90*i)) * PI / 180.0f) *T_Distance; T[i].y = Ref_y() + sin((Ref_Angle()+45+(90*i)) * PI / 180.0f) *T_Distance; } C[4].x=C[0].x; C[4].y=C[0].y;//forで計算しやすいようにするための処理 //あとは二点間の直線の方程式 ax+by+cを求めて、点と直線の距離の公式で出来る・・・はず。 if(Collision.Ref_bShow()==true)//確認する対象は参照するべき相手かを確認 { if(Collision.Ref_Collision()==true)//当たり判定を有するか { for(int i=0;i<=3;i++) { for(int j=0;j<=3;j++) { double a =(C[i].y-C[i+1].y); double b =-(C[i].x-C[i+1].x); double c =( ((C[i].x-C[i+1].x)*C[i+1].y) - ((C[i].y-C[i+1].y)*C[i+1].x)); //呼び出したオブジェクトと引数のオブジェクトの接触を判定する if ( (fabs((a*T[j].x)+(b*T[j].y)+c) /hypot(a,b))<=10.0 ) { return(true); } } } return(false); } else { return(false); } } else { return(false); } } このソースコードで試してみたのですが、上手くいかず、数値を確認してみると、(fabs((a*T[j].x)+(b*T[j].y)+c) /hypot(a,b))の値がTの座標が違うところでこの関数を呼び出しても値が同じだったりと、おかしな結果になってしまいます(どうおかしい結果なのかも書くべきなのだとは思うのですが、法則性をまだ見つけられていないので・・・) もしどの部分が間違っているのかが解りそうでしたら、教えて頂けると助かります、数学的知識の勘違いや、単純なくだらないミスなのかもしれませんが、宜しくお願いします。

  • direct3dで当たり判定

    現在direct3dでフライトゲームを作っており、当たり判定部分を考えているのですがうまくいきません。メタセコイアでxファイルを作成し、ビルボードで表示している(敵も自弾も)のですが、そもそも基準点はどこに来るのか、プログラム上で指定する縦横高さがわからないなど当たり判定以前の問題のような気もするのですが・・・。とりあえず、該当部分のコードを載せるのでご享受お願いします。 ↓ゲームメインの攻撃部分↓ if(GetKeyboardTrigger(DIK_Z)){ _for(int i = 0; i < ATTACKNUM; i++){ __if( man_bullet[i].flag.bullet == 0){ ___man_bullet[i].flag.bullet = 1; ___//自機の座標セット ___mat_world[15+i]._41 = mat_world[0]._41; ___mat_world[15+i]._42 = mat_world[0]._42+2; ___mat_world[15+i]._43 = mat_world[0]._43; ___break; __} _} } for(int i = 0; i < ATTACKNUM; i++){ _if(man_bullet[i].flag.bullet == 1){ __mat_world[15+i]._43 ++; __man_bullet[i].cnt.bullet++; __if(man_bullet[i].cnt.bullet >= 100){ ___man_bullet[i].flag.bullet = 0; ___man_bullet[i].cnt.bullet = 0; ___mat_world[15+i]._42 = -100; __} __for(int j = 0; j < ENEMYNUM; j++){ ___man_bullet[i].flag.atk_result = ___Hit_Judging(&mat_world[5+j]._41, &mat_world[5+j]._42, &mat_world[5+j]._43, ________enemy[j].x, enemy[j].y, enemy[j].z, ________&mat_world[15+i]._41 , &mat_world[15+i]._42, &mat_world[15+i]._43, ________man_bullet[i].x, man_bullet[i].y, man_bullet[i].z ); ___if(man_bullet[i].flag.atk_result == 1){ ____man_bullet[i].flag.atk_result = 0; ____man_bullet[i].flag.bullet = 0; ____man_bullet[i].cnt.bullet = 0; ____mat_world[5+j]._43 = 150; ____mat_world[15+i]._42 = -100; ____break; ___} __} _} } ↓当たり判定部分↓ int Hit_Judging( float *xpos1 , float *ypos1 , float *zpos1 , ________float x1, float y1, float z1, ________float *xpos2 , float *ypos2 , float *zpos2 , ________float x2, float y2, float z2 ) { _for(int i = 0; i < ATTACKNUM; i++){ __if(man_bullet[i].flag.bullet == 1){ ___for(int j = 0; j < ENEMYNUM; j++){ ____if( ((xpos1[j] - (x1/2) ) < (xpos2[i] + (x2/2) ) && ______(xpos1[j] + (x1/2) ) > (xpos2[i] - (x2/2) )) && ______((ypos1[j] + y1 ) < ypos2[i] && ypos1[j] > (ypos2[i] + y2 )) && _______(zpos1[j] == zpos2[i]) ){ _____return 1; ____}else _____return 0; ___} __} _} }

  • クリックされた地点が2点の線分上かの判定

    bool CheckOnline(int x1,int y1,int x2,int y2,int MouseX,int MouseY){ int range = 10; //許容範囲 double a; double b; if(x2 == x1){ if( abs( MouseX -x1)<range ){ if( abs(MouseY -abs(y2-y1)) <range) return true; } }else{ a=(y2-y1)/(x2-x1); b= y1 - a*x1; if( abs(MouseY - (a * MouseX +b)) <range ){ if( abs(MouseX - ((MouseY-b)/a)) <range ) return true; } } return false; } ぴったりでなく少し誤差があっても線上と判定したいです。 上記の方法ではうまく行きませんでした。 一応、y=ax+bのaとbを求めて、マウスのxとマウスのyを代入 その結果がrange以内かどうかでやってみようとした結果です。

  • 敵との当たり判定

    現在VisualC++2008でゲームを製作してるんですが 自分と敵との当たり判定がわかりません。 どのようにすればいいか教えてもらえないでしょうかm(_ _)m #define SCREEN_WIDTH (640) // 画面の横幅 #define SCREEN_HEIGHT (480) // 画面の縦幅 #define CHIP_SIZE (32) // 一つのチップのサイズ #define MAP_WIDTH (SCREEN_WIDTH / CHIP_SIZE) // マップの横幅 #define MAP_HEIGHT (SCREEN_HEIGHT / CHIP_SIZE) // マップの縦幅 #define CHAR_SIZE (30) // プレイヤーのサイズ float PlX, PlY ; // プレイヤーの座標(中心座標) int ActMain( void ) { // プレイヤーの座標を初期化 PlX = 100.0F ; PlY = 1.0F ; // マップ { int i, j ; for( i = 0 ; i < MAP_HEIGHT ; i ++ ) { for( j = 0 ; j < MAP_WIDTH ; j ++ ) { // 1のところだけ描画 if( MapData[i][j] == 1 ) { DrawBox( j * CHIP_SIZE, i * CHIP_SIZE, j * CHIP_SIZE + CHIP_SIZE, i * CHIP_SIZE + CHIP_SIZE, GetColor( 0, 0, 0 ), TRUE ) ; } } } } //プレイヤーの描写 DrawBox( ( int )( PlX - CHAR_SIZE * 0.5F ), ( int )( PlY - CHAR_SIZE * 0.5F ), ( int )( PlX + CHAR_SIZE * 0.5F ) + 1, ( int )( PlY + CHAR_SIZE * 0.5F ) + 1, GetColor( 255, 0, 0 ), TRUE ) ; Cr = GetColor( 255 , 255, 255 ) ; //敵の描写 DrawGraph(teki[0].x,teki[0].y,teki[0].img,TRUE); //初期化 void SYOKIKA(void){ teki[0].x=500; teki[0].y=200; teki[0].img=LoadGraph("red_player.bmp"); //当たり判定をつくったつもりですが反応せず・・・。一応あたったらPlXを0に移動させようとしています。 if(PlX==teki[0].x) PlX=0; if(PlX==teki[0].y) PlX=0; if(PlY==teki[0].x) PlX=0; if(PlY==teki[0].y) PlX=0; がソースです(文字数が足りないのであたり判定に関係ありそうな(敵と自分の座標関連)ところだけ抜きました)今のところ敵、自分、マップ表示や自分の移動などはできているのですが、敵に触れても反応せず、ときおり敵のいないまったく関係のない場所でPlXが0に移動したりしてしまいます ソースみづらくて申し訳ありません。

  • セグメンテーション違反

    穴掘り方というやり方で迷路を作っています。 とりあえずすこしだけ作ってみて実行したらセグメンテーション違反が起こってしまいました。 解説お願いします。 次のサイトを参考にしています。ttp://www.ced.is.utsunomiya-u.ac.jp/lecture/2009/prog/p3/kadai4/5.html #include<stdio.h> #include<stdlib.h> #include<time.h> #define A 51 #define B 51 /*51ラ51マスの迷路*/ void initialize(int *x,int *y,int map[A][B]);  /*最初のステージ作成と座標決定*/ int dig(int *x,int *y,int map[A][B]);   /*道を作る*/ int main(void) { int x,y;   /*現在の座標*/ int map[A][B];    initialize(&x,&y,map); dig(&x,&y,map); map[1][0] = 2; map[A-2][B-1] = 2; for(y=0;y<B;y++){ for(x=0;x<A;x++){ if( map[x][y] == 0){ printf(" "); }else if( map[x][y] == 1){ printf("■"); }else if( map[x][y] == 2){ printf("..") ; } } printf("\n"); } } void initialize(int *x,int *y,int map[A][B]) { int i,h; for(i=0;i<A;i++){ for(h=0;h<B;i++){ map[i][h]=1; } } do{ *x=rand()%A; *y=rand()%B; }while(*x!=0 && *x!=A-1 && *y!=0 && *y!=B-1); } int dig(int *x,int *y,int map[A][B]) { int r,c,dx,dy,count=0; do{ r = rand()%4; switch(r){     /*道を進める方向を決める*/ case 0: dx = 0; dy = -1; break; case 1: dx = -1; dy = 0; break; case 2: dx = 0; dy = 1; break; case 3: dx = 1; dy = 0; break;    } if(*x+dx*2 <= 0 || *y+dy*2 <= 0 || *x+dx*2 >= A-1 || *y+dy*2 >= B-1 || map[*x+dx*2][*y+dy*2] == 0){ c = 0; count++; if(count ==4){     /*4方向とも進めなかったらループを抜ける*/ break; } }else if(map[*x+dx*2][*y+dy*2] == 1){ map[*x+dx][*y+dy] = 0; *x = *x + dx*2; *y = *y + dy*2; c =1; } }while(c==0); }

  • C言語の素数判定について質問です。

    C言語の素数判定について質問です。 「与えられた数値以下で、最大の素数を返す関数を作成しなさい。 素数が存在しない場合、0を返すこと。 int max_prime (int x);を使用する。」 という問題なのですが。まったくの初心者なので何をすればよいか分かりません。 例として以下のようなプログラムを見せられたのですが、他の例などないでしょうか。 もし分かるかたがいらっしゃれば教えていただけないでしょうか。よろしくお願いします。 #include<stdio.h> int is_prime (int i){ int a; for(a=2;a<=i-1;a++){ if(i%a == 0){ return i; } } return 0; } int max_prime(int x){ int i; for(i=x;i>1;i--){ if(is_prime(i)!=i){ return i; } } return 0; } int main(void){ int x,z; scanf("%d",&x); z=max_prime(x); printf("%d数値以下で最大の素数は[%d]である!\n",x,z); return 0; }

  • 解けません!

    http://www.pref.fukushima.jp/pc-concours/2008/03/pdf/2007honsen.pdf この問題03の宅配料金の問題が解けません!! 書かれている入力例と出力例はあっているのですが、 学校のジャッジシステムが受けつけてくれません。 どなたか僕のプログラムの不備を見つけて下さい。 お願いします。 #include <stdio.h> int ryoukin(int x, int y, int h, int w) { int i,t,c; i = x + y + h; if (i <= 60) t = 600; else if (i <= 80) t = 800; else if (i <= 100) t = 1000; else if (i <= 120) t = 1200; else if (i <= 140) t = 1400; else if (i <= 160) t = 1600; else t = 0; if (w <= 2) c = 600; else if (w <= 5) c = 800; else if (w <= 10) c = 1000; else if (w <= 15) c = 1200; else if (w <= 20) c = 1400; else if (w <= 25) c = 1600; else c = 0; if (t == 0) return 0; else if (c == 0) return 0; else if (t < c) return c; else return t; } int main(void) { int x,y,h,w,n,i,sum; sum = 0; while(n != 0){ scanf("%d",&n); if(n != 0){ for(i = 0; i < n; i++){ scanf("%d %d %d %d", &x, &y, &h, &w); sum = sum + ryoukin(x,y,h,w); } printf("%d\n",sum); sum = 0; } } return (0); }

  • 四角形の当たり判定についての質問です。

    四角い2つブロックの当たり判定をとりたいです。1つのブロックは十字キーによって移動することができ、もうひとつのブロックは画面中央に固定されたまま動くことはありません。2つの四角形が当たった時に擦りぬけないようにしたいのですが、ぶつかったときに十字キーで上下左右に動かしてもすりぬけないようにしたのですが、斜めに移動させるとおかしくなってしまいます。次のプログラムをどう修正すればいいでしょうか? 変数の説明 Player.x:動く四角形のX座標 Player.y:動く四角形のY座標 Player.width:動く四角形の幅 Player.height:動く四角形の高さ Wall.x:動く四角形のX座標 Wall.y:動く四角形のY座標 Wall.width:動く四角形の幅 Wall.height:動く四角形の高さ //2つの四角形がぶつかっていなかったら if(!(((Player.x > Wall.x && Player.x < Wall.x + Wall.width) || (Wall.x > Player.x && Wall.x < Player.x + Player.width)) && ((Player.y > Wall.y && Player.y < Wall.y + Wall.height) || (Wall.y > Player.y && Wall.y < Player.y + Player.height)))) { //右キーを押していたら if(g_keyState[DIK_RIGHT] & 0x80 ) { Player.x += 3; if((((Player.x > Wall.x && Player.x < Wall.x + Wall.width) || (Wall.x > Player.x && Wall.x < Player.x + Player.width)) && ((Player.y > Wall.y && Player.y < Wall.y + Wall.height) || (Wall.y > Player.y && Wall.y < Player.y + Player.height)))) Player.x = Wall.x - Player.width - 1; } //左キーを押していたら if(g_keyState[DIK_LEFT] & 0x80) { Player.x -= 3; if((((Player.x > Wall.x && Player.x < Wall.x + Wall.width) || (Wall.x > Player.x && Wall.x < Player.x + Player.width)) && ((Player.y > Wall.y && Player.y < Wall.y + Wall.height) || (Wall.y > Player.y && Wall.y < Player.y + Player.height)))) Player.x = Wall.x + Wall.width + 1; } //上キーを押していたら if(g_keyState[DIK_UP] & 0x80) { Player.y -= 3; if((((Player.x > Wall.x && Player.x < Wall.x + Wall.width) || (Wall.x > Player.x && Wall.x < Player.x + Player.width)) && ((Player.y > Wall.y && Player.y < Wall.y + Wall.height) || (Wall.y > Player.y && Wall.y < Player.y + Player.height)))) Player.y = Wall.y + Wall.height + 1; } //下キーを押していたら if(g_keyState[DIK_DOWN] & 0x80) { Player.y += 3; if((((Player.x > Wall.x && Player.x < Wall.x + Wall.width) || (Wall.x > Player.x && Wall.x < Player.x + Player.width)) && ((Player.y > Wall.y && Player.y < Wall.y + Wall.height) || (Wall.y > Player.y && Wall.y < Player.y + Player.height)))) Player.y = Wall.y - Player.height - 1; } }

専門家に質問してみよう