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);
}
A 回答 (1件)
- 最新から表示
- 回答順に表示
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が見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- FX・外国為替取引 mql4のコンパイルエラー箇所の修正お願いします。 1 2023/03/15 16:14
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# C言語 3 2022/11/09 13:27
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# C言語でif文が予想と違う動きをする件について7 4 2023/03/20 00:26
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
2の補数を計算するプログラム
-
intとlongは同じ?
-
再起呼び出しの回数をカウント...
-
C言語で%を使わない余りの出し方
-
迷路を脱出する経路探索プログ...
-
画像の拡大・縮小
-
分数の足し算をさせるプログラ...
-
C言語で簡単なパックマンゲーム...
-
C++で表を作成したいのです ...
-
条件が多い場合
-
複数の共有メモリの作成
-
ヒストグラム均等化処理プログラム
-
3のつく数と3の倍数を表示 C言語
-
argvのNULLチェック
-
乱数で交互に偶数、奇数が、、、。
-
プログラミングに関して
-
OpenCVによる4値化について
-
再帰処理をループ処理に変換
-
16bitで乱数を生成する方法
-
C++ Debug Errorについて教えて
おすすめ情報