トップページ > 記事閲覧
当たり判定
名前:はちみつ 日時: 2018/07/10 09:50

試行錯誤して敵を複数体表示させることに成功したのですが当たり判定がうまくいきません 何が原因でしょうか? #include "DxLib.h" int count = 0; //カウント int Key[256]; // キーが押されているフレーム数を格納する // キーの入力状態を更新する int gpUpdateKey() { char tmpKey[256]; // 現在のキーの入力状態を格納する GetHitKeyStateAll(tmpKey); // 全てのキーの入力状態を得る for (int i = 0; i<256; i++) { if (tmpKey[i] != 0) { // i番のキーコードに対応するキーが押されていたら Key[i]++; // 加算 } else { // 押されていなければ Key[i] = 0; // 0にする } } return 0; } struct enemy { //敵の構造体 int gh; int x; int y; int life; int flag; int patarn; }Enemy[100]; struct character { //キャラクターデータの構造体 int gh; int x ; int y ; int Life; }Player; struct shot { //弾の構造体 int flag; int x; int y; int shotgh; }Playershot[25]; int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK); //ウィンドウモード変更と初期化と裏画面設定 Player = { LoadGraph("画像/自機.png") ,50,300,3 };//自機情報の初期化 for (int i = 0; i < 100; i++) { Enemy[i] = { LoadGraph("画像/敵.png"),0,0,1,0,0 };//敵情報の初期化 } for (int i = 0; i < 25; i++) { Playershot[i]={ 0,Player.x,Player.y,LoadGraph("画像/自機弾.png") };//自機の弾の情報の初期化 } while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 && gpUpdateKey() == 0) //メインループ開始 { if (Key[KEY_INPUT_UP] >= 1 && Player.y >= 0) { //自機操作上 Player.y -= 3; } if (Key[KEY_INPUT_DOWN] >= 1 && Player.y <= 430) { //自機操作下 Player.y += 3; } if (Key[KEY_INPUT_RIGHT] >= 1 && Player.x <= 560) { // 自機操作右 Player.x += 3; } if (Key[KEY_INPUT_LEFT] >= 1 && Player.x >= 0) { //自機操作左 Player.x -= 3; } if (Key[KEY_INPUT_A] == 1) { //自機が弾を発射した時のフラグと座標の代入 for (int i = 0; i <= 25; i++) { if (Playershot[i].flag == 0) { Playershot[i].flag = 1; Playershot[i].x = Player.x + 20; Playershot[i].y = Player.y + 20; break; } } } for (int i = 0; i <= 25; i++) { if (Playershot[i].flag == 1) { //自機の弾の進み方の計算 Playershot[i].x += 6; } if (Playershot[i].flag == 1 && Playershot[i].x > 600) { //弾が画面からはみ出したらフラグを戻す Playershot[i].flag = 0; } } //敵の出現パターンの代入 if (count == 150 && Enemy[1].flag == 0) { Enemy[1].flag = 1; Enemy[1].x = 570; Enemy[1].y = 200; Enemy[1].patarn = 1; Enemy[1].life = 1; } if (count == 250 && Enemy[2].flag == 0) { Enemy[2].flag = 1; Enemy[2].x = 570; Enemy[2].y = 400; Enemy[2].patarn = 1; } for (int i = 0; i < 100; i++) {//当たり判定 for (int k = 0; k < 25; k++) { if (Enemy[i].x == Playershot[k].x&&Enemy[i].y == Playershot[k].y) { Enemy[i].life -= 1; } } } DrawFormatString(50, 30, GetColor(225, 225, 225), "%d", count);//カウント表示 DrawFormatString(50, 50, GetColor(225, 225, 225), "%d,%d", Player.x, Player.y);//自機の座標表示 DrawGraph(Player.x, Player.y, Player.gh, true);//自機描画 for (int i = 0; i <= 25; i++) { //自機の弾の描写 if (Playershot[i].flag == 1) { DrawGraph(Playershot[i].x, Playershot[i].y, Playershot[i].shotgh, true); } } for (int i = 0; i < 100; i++) {//敵の描写 if (Enemy[i].flag == 1 && Enemy[i].patarn == 1 && Enemy[i].life > 0) { DrawGraph(Enemy[i].x, Enemy[i].y, Enemy[i].gh, true); Enemy[i].x -= 5; } if (Enemy[i].y <= -10 || Enemy[i].y >= 450 || Enemy[i].x >= 580 || Enemy[i].x <= -10 || Enemy[i].life == 0) {//敵の画面外処理 Enemy[i].flag = 0; } } count++; } WaitKey(); // キー入力待ち DxLib_End(); // DXライブラリ終了処理 return 0; }
メンテ

Page: 1 |

Re: 当たり判定 ( No.1 )
名前:GASHI 日時:2018/07/10 17:09

こんにちは。 if (Enemy[i].x == Playershot[k].x&&Enemy[i].y == Playershot[k].y) { Enemy[i].life -= 1; } この当たり判定だけでは、「ショットと敵の【位置】が完全に一致」した時だけ「当たり」になります。 (多分現状ではめったに当たらないと思います。) 実際はショットの「大きさ」と敵の「大きさ」も考慮する必要があります。 表示される大きさと実際の当たり判定の大きさはゲームバランスに関わるので、そこは自分の好みに 合うように工夫する必要があると思います。
メンテ
Re: 当たり判定 ( No.2 )
名前:はちみつ 日時:2018/07/13 00:12

ご指摘をいただいたことを考慮して当たりの範囲を広げるためにこのように変えてみたのですが敵が出てこなくなってしまいました。 すみませんがアドバイスをください。 for (int i = 0; i < 100; i++) {//当たり判定 for (int k = 0; k < 25; k++) { if (Enemy[i].x <= Enemy[i].x + 10 == Playershot[k].x <= Playershot[k].x + 10 &&Enemy[i].y <= Enemy[i].y + 10 == Playershot[k].y <= Playershot[k].y + 10) { Enemy[i].life -= 1; } } }
メンテ
Re: 当たり判定 ( No.3 )
名前:GASHI 日時:2018/07/13 01:24

こんばんわ。 答えではなく、アドバイスということでしたら… このように改行をとかっこを入れると、なにかが間違っていることに 気が付きやすくなるはずです。 さらにヒントとしては、この場合は「==」は登場しません。 頑張ってみて下さい。 for( int i = 0; i < 100; i++ ){//当たり判定 for( int k = 0; k < 25; k++ ){ if( (Enemy[ i ].x <= Enemy[ i ].x + 10 )== (Playershot[ k ].x <= Playershot[ k ].x + 10 )&& (Enemy[ i ].y <= Enemy[ i ].y + 10 )== (Playershot[ k ].y <= Playershot[ k ].y + 10 )) { Enemy[ i ].life -= 1; } } }
メンテ
Re: 当たり判定 ( No.4 )
名前:ひいちゃ 日時:2018/07/13 13:47

VB.NET用ではありますが、僕が使っている、自作の当たり判定関数をば。 これを参考にすると解決するかもです。 Function IsHit(pObj1 As Sprite, pObj2 As Sprite, Optional pPlayerFlag As Integer = DFALSE) As Integer Dim sInfo1 As HitCheckInfo Dim sInfo2 As HitCheckInfo Dim sInfoC As HitCheckInfo If pPlayerFlag = DTRUE Then With sInfo1 .X = pObj1.X + pObj1.Width / 2 - 2 .Y = pObj1.Y + pObj1.Height / 2 - 2 .W = 4 .H = 4 End With Else With sInfo1 .X = pObj1.X .Y = pObj1.Y .W = pObj1.Width .H = pObj1.Height End With End If With sInfo2 .X = pObj2.X .Y = pObj2.Y .W = pObj2.Width .H = pObj2.Height End With With sInfoC .X = Math.Abs(sInfo1.X - sInfo2.X) .Y = Math.Abs(sInfo1.Y - sInfo2.Y) .W = (sInfo1.W + sInfo2.W) / 2 .H = (sInfo1.H + sInfo2.H) / 2 End With If (sInfoC.X <= sInfoC.W) And (sInfoC.Y <= sInfoC.H) Then Return DTRUE Else Return DFALSE End If End Function
メンテ
Re: 当たり判定 ( No.5 )
名前:どん 日時:2018/07/13 20:22

弾も敵も円で考えるなら距離を使って判定したほうが簡単だと思います その場合だと三平方の定理をつかって if((Enemy[i].x - Playershot[k].x)*(Enemy[i].x - Playershot[k].x) + (Enemy[i].y - Playershot[k].y)*(Enemy[i].y - Playershot[k].y) < 10*10) これだと弾と敵の中心間の距離が10より小さいくなれば真になります
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存