ページ 11

ヒット判定について

Posted: 2011年2月02日(水) 13:18
by 卒業したい
またよろしくお願いします。
消す判定で今困っています

鉄人さん同様に近くにある弾を消す作業に入っているのですが
上キーしか反応せずほかの列の弾まで上キーで消してしまいます
また、上キーを長押しすると判定ラインにつくだけで消えてしまいます

いろいろ手直しをしたのですが
直したものは判定ラインに着くだけで弾が消えてしまいます・・・

なぜ上キーしか反応しないのでしょうか?
また力をお貸しください
お願いします。

コード:

#include "DxLib.h"
 
int Key[256];
 
int GetHitKeyStateAll_2(int GetHitKeyStateAll_InputKey[256]){
    char GetHitKeyStateAll_Key[256];
    GetHitKeyStateAll( GetHitKeyStateAll_Key );
    for(int i=0;i<256;i++){
        if(GetHitKeyStateAll_Key[i]==1) GetHitKeyStateAll_InputKey[i]++;
        else GetHitKeyStateAll_InputKey[i]=0;
    }
    return 0;
}
int CheckStateKey(unsigned char Handle){
    return Key[Handle];
}
 int GetJoypadInputState( int InputType ) ;


 
//----------------------------------------------------
int haikei[10];//色のハンドル------------------------------------------------
void gazou1(){//これは背景画像ーーーーーーーーーーーーーーーーーーーーーーーー
haikei[0]=LoadGraph("kop3.png");
haikei[1]=LoadGraph("ue1.png");
haikei[2]=LoadGraph("migi1.png");
haikei[3]=LoadGraph("hidari1.png");
haikei[4]=LoadGraph("sita1.png");
}
int tama[10];//たまの画像----------------------------------------------------
void gazou2(){
tama[0]=LoadGraph("dan.png");
tama[1]=LoadGraph("ber.png");
}
//--------------------------------------------------------------
int color[10];//これは色の設定-----------------------------------------------
void load(){
    color[0] = GetColor(255,255,255);//白
    color[1] = GetColor( 0, 0, 0);//黒
    color[2] = GetColor(255, 0, 0);//赤
    color[3] = GetColor( 0,255, 0);//緑
    color[4] = GetColor( 0, 0,255);//青
    color[5] = GetColor(255,255, 0);//黄色
    color[6] = GetColor( 0,255,255);//青緑
    color[7] = GetColor(255, 0,255);//紫
}//------------------------------------
int music[1];
void kyoku(){
	music[0] = LoadSoundMem("校歌.mp3");
}
//--------------------------------------------------------------
 
//ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
#define BER_UX 65
#define BER_Y 60
 
#define BER_MX 215
 
#define BER_HX 370

#define BER_SX 525


#define HIT_UX 80
#define HIT_UY 73
 
#define HIT_MX 230
 
#define HIT_HX 385

#define HIT_SX 540



//判定ライン-------------------------------------------------
#define VGOOD_Y 5
#define GOOD_Y 20
#define BAD_Y 30
//ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー//
typedef struct{
    int flag;
    int knd;
}humen_t;//譜面の構造体
#define HUMEN_MAX 1000
humen_t humen[HUMEN_MAX];
 
void load_humen(){
    int i=0,cnt=0;
    int c;
    FILE *fp;
    fp=fopen("ue.txt","r");
    if(fp==NULL)
        return;
        while((c=fgetc(fp))!=EOF){
        if(c==' '||c=='\n')continue;
        if(c!='0'){
            humen[i].flag=1;
            humen[i].knd=c-'0';
        }
            i++;
            if(i>=HUMEN_MAX)break;//オーバーフロー防止
    }
fclose(fp);
}
//テキストから譜面(0,1,2,3,4)を読み込む--------------------------------------------------------

typedef struct{
	int flag;
}KEY_H;
KEY_H KEY;

void KEY_O(){
	if(CheckStateKey(KEY_INPUT_UP)==1){
		//DrawString(  0,  0, "hello! DX Library!" , color[1]);    
			DrawGraph(BER_UX,BER_Y,tama[1],TRUE);
				KEY.flag=1;
	}
	if(CheckStateKey(KEY_INPUT_LEFT)==1){//ひだり
		//DrawString(  0,  0, "hello! DX Library!" , color[1]);    
			DrawGraph(BER_HX,BER_Y,tama[1],TRUE);
				KEY.flag=1;
	}
	if(CheckStateKey(KEY_INPUT_RIGHT)==1){
		 //DrawString(  0,  0, "hello! DX Library!" , color[1]);
			 DrawGraph(BER_MX,BER_Y,tama[1],TRUE);
				KEY.flag=1;
	}
	if(CheckStateKey(KEY_INPUT_DOWN)==1){
		//DrawString(  0,  0, "hello! DX Library!" , color[1]);
			DrawGraph(BER_SX,BER_Y,tama[1],TRUE);
				KEY.flag=1;
	}}
//キー入力関係--------------------------------------------------------------------------

#define FLAME 60


int fps_count,count0t;//fpsのカウンタ、60フレームに1回基準となる時刻を記録する変数

int f[FLAME];//平均を計算するため60回の1周時間を記録

double ave;//平均fps


void fps_wait(){						//FLAME fps になるようにfpsを計算・制御
    int term,i,gnt;
    static int t=0;
    if(fps_count==0){					//60フレームの1回目なら
        if(t==0)						//完全に最初ならまたない
            term=0;
        else							//前回記録した時間を元に計算
            term=count0t+1000-GetNowCount();
    }
    else								//待つべき時間=現在あるべき時刻-現在の時刻
        term = (int)(count0t+fps_count*(1000.0/FLAME))-GetNowCount();

    if(term>0)							//待つべき時間だけ待つ
        Sleep(term);

    gnt=GetNowCount();

    if(fps_count==0)					//60フレームに1度基準を作る
        count0t=gnt;
    f[fps_count]=gnt-t;					//1周した時間を記録
    t=gnt;
    //平均計算
    if(fps_count==FLAME-1){
        ave=0;
        for(i=0;i<FLAME;i++)
            ave+=f[i];
        ave/=FLAME;
    }
    fps_count = (++fps_count)%FLAME ;
}


void draw_fps(int x, int y){			//x,yの位置にfpsを表示
    if(ave!=0){
        DrawFormatString(x, y,color[0],"[%.1f]",1000/ave);
    }
    return;
}

void FPS_M(){
fps_wait();
draw_fps(0,0);
}
//FPSの管理------------------------------------------------------------------------------------

typedef struct{
    int flag;
    int x,y;
	int se_flag;
	int spd;
	int knd;
}bullet_t;//たまの構造体
#define BULLET_MAX 1000
bullet_t bullet[BULLET_MAX];
 
int flame;
void huru_bullet(){
    int i,j;
    const int list[]={0,HIT_UX,HIT_MX,HIT_HX,HIT_SX};
    i=flame++;
    if(i>=HUMEN_MAX)return;
    if(humen[i].flag==1){
        if(humen[i].knd>=1 && humen[i].knd<=4){
            for(j=0;j<BULLET_MAX;j++) {
                if(bullet[j].flag==0) {
                    bullet[j].flag=humen[i].knd;
                    bullet[j].x=list[humen[i].knd];
                    bullet[j].y=552;
                    break;
                }
            }
        }
    }
}
        
        
 
//譜面のフラグとkndが1の時・・・
int tama_bullet(){
    int i;
    for(i=0;i<BULLET_MAX;i++){
    if(bullet[i].flag!=0){
                bullet[i].y-=3;          //座標を8減らす
                DrawGraph( bullet[i].x , bullet[i].y , tama[0] ,TRUE);
                //ここに当たり判定
				//if(KEY.flag==1){
				if(bullet[i].y < -32){    //もし画面外まで来たら
                                    bullet[i].y=552;    //初期値に戻し、
                                    bullet[i].flag=0;   //発射フラグを戻す
                                }
                        }
               }
return 0;
}


//hit判定

void hit_bullet(){
	int i,j,k,knd;
	char key[256];
	double y,pre_y,y0,y1;
	double line_y[3]={VGOOD_Y,GOOD_Y,BAD_Y};
	GetHitKeyStateAll(key);
	
	for(i=0;i<BULLET_MAX;i++){//弾分ループ
		if(bullet[i].flag!=0){//弾が存在していて
			knd=-1;
			pre_y=bullet[i].y+bullet[i].spd;
			y=bullet[i].y;
			for(j=0;j<3;j++){
				y0=HIT_UY-line_y[j];
				y1=HIT_UY+line_y[j];
				// ↓148よりx0が下であるか↓148よりx0が上であるか↓x0がxを下回っているか、x1がxを上回っているか↓初期化
				if(y<y0 && y0<pre_y		|| y<y1 && y1<pre_y		|| y0<y && y<y1 ||				y0<pre_y && pre_y<y1){//距離ヒット以内なら
				  //押したときの現在位置が当たり判定の軸からline_x分離れた中にあるなら決められた範囲の処理を行う
					knd=j;//kndに数値を代入する
					break;
				}
			}
			//距離OKでその時たたいていたら (ここから)
			if(knd!=-1 && (key[KEY_INPUT_UP]==1 && bullet[i].knd==0 || key[KEY_INPUT_DOWN]==1 && bullet[i].knd==1 || key[KEY_INPUT_LEFT]==1 && bullet[i].knd==2 || key[KEY_INPUT_RIGHT]==1 && bullet[i].knd==3)){
			

			//if(||||||)
				bullet[i].flag=0;
			{break;}
				//enter_hit_dat(k,i,knd,bullet[i].x);
			}
				//bullet[i].flag=1;  (ここまで)
		}
	}
}
void bullet_main(){
    huru_bullet();
    tama_bullet();
	hit_bullet();
}
//弾関係の設定---------------------------------------------------------------------------------

void music_t(){
//WaitTime(60000);
//PlayMusic( "曲.mid" , DX_PLAYTYPE_BACK ) ;
	PlaySoundMem(music[0],DX_PLAYTYPE_BACK);
}

void ini(){
    memset(bullet,0,sizeof(bullet_t)*BULLET_MAX);//弾情報初期化
    memset(humen,0,sizeof(humen_t)*HUMEN_MAX);//結果表示情報初期化
}
//初期化設定------------------------------------------------------------------------------------
void matome(){
    gazou1();
    gazou2();
    DrawGraph(0,0,haikei[0],TRUE);
 kyoku();
    load();
    load_humen();
    flame=0;
    FPS_M();    
	DrawBox( 0, 70 , 645 , 75 , color[0] ,TRUE);
        DrawBox( 85 , 0 , 95 , 480 , color[2],TRUE );
        DrawBox( 235 , 0 , 245 , 480 , color[3],TRUE );
        DrawBox( 390 , 0 , 400 , 480 , color[4],TRUE );
        DrawBox( 545 , 0 , 555 , 480 , color[5],TRUE );
		KEY_O();
 }
//まとめ----------------------------------------------------------------------------------------
void graph(){
    ClearDrawScreen();
    DrawGraph(0,0,haikei[0],TRUE);
    DrawGraph(90,0,haikei[1],TRUE);
    DrawGraph(240,0,haikei[2],TRUE);
    DrawGraph(395,0,haikei[3],TRUE);
    DrawGraph(550,0,haikei[4],TRUE);
        DrawBox( 0, 70 , 645 , 75 , color[0] ,TRUE);
        DrawBox( 85 , 0 , 95 , 480 , color[2],TRUE );
        DrawBox( 235 , 0 , 245 , 480 , color[3],TRUE );
        DrawBox( 390 , 0 , 400 , 480 , color[4],TRUE );
        DrawBox( 545 , 0 , 555 , 480 , color[5],TRUE );
		KEY_O();
}
//画像に関するプログラム----------------------------------------------------------------------- 
//ループで必ず行う3大処理
 
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
    ChangeWindowMode(TRUE);//ウィンドウモード
    
    if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化
    ini();
	music_t();
    matome();
	kyoku();
	music_t();
while(ProcessMessage()==0&&GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
        //↑メッセージ処理   ↑画面をクリア     ↑入力状態を保存       ↑ESCが押されていない
       
		graph();
		FPS_M();
 
		
        bullet_main();

        ScreenFlip();
		if(CheckStateKey(KEY_INPUT_ESCAPE)==1)break;//エスケープが入力されたらブレイク
    }
    
    DxLib_End();
    return 0;
}
タグ囲みに失敗していたので修正しました。必ずプレビューで確認してから投稿してください。 by softya(ソフト屋)

Re: ヒット判定について

Posted: 2011年2月02日(水) 13:32
by softya(ソフト屋)
太鼓の鉄人を改良して音ゲーを作られているんですよね?
そのヒットの条件とかキー入力の関係、ラインとの関係などルールを明確にしてもらえないでしょうか?

Re: ヒット判定について

Posted: 2011年2月02日(水) 16:03
by 卒業したい
softya(ソフト屋)さんへ

ルールなどはこのようになっています

ヒットの条件
決められたY座標の前後合計76の範囲
キー入力の関係
キーボードの上下左右
ラインとの関係
デクリメントして動かしている画像が範囲内に入ったときに決められたキーのみで消える

つまり、下から画像を流して範囲内に入った画像を決められたキーで消すというルールです。

画像を流す場所を四つに分けてそれぞれに上下左右の入力待ちのルールを作り、
範囲に入った画像が上専用のX座標にある画像ならば上のみで消えるというものを目指しています。

掲示したプログラムの前に作ったものは上下左右のキー どれを入力しても範囲に最初に入った画像が消えてしまっていました。
流れてくる画像に合わせて上を押してもほかの下や右などにある画像が上を押す、または押しっぱなしで消えてしまいます。

原因としては恐らく、上下左右すべてが画像発射フラグを0にする条件であったからだと思います。
これを上専用に設定したX座標の位置から出てくる画像は上のみで消せるようなプログラムを作りたいのです。

説明不足で申し訳ありません。この説明も不快を招くこともあるかもしれませんが、こちらとしては考え付くことがありませんので
ぜひ力をお貸しください。お願いします。

あと、掲示したプログラムの266行目のプログラムを元に先ほどの条件をクリアできるプログラムも可能であればよろしくお願いします。
これは余力があれば、またはこちらのほうが適しているということであればで構いません。
基本的に↓のプログラムを266行目に差し替えた状態で話を進めていきます。
if(knd!=-1&&key[KEY_INPUT_UP]==1||key[KEY_INPUT_DOWN]==1||key[KEY_INPUT_LEFT]==1||key[KEY_INPUT_RIGHT]==1)
長文失礼しました。よろしくお願いします。

Re: ヒット判定について

Posted: 2011年2月02日(水) 17:15
by softya(ソフト屋)
GetHitKeyStateAllの戻り値をそのまま使っているからですね。
押されている間は1なので押している間は条件を満たしてしまいます。

int Key[256];の値を使ってください。
こちらは押された1フレーム目だけ1になり、離すと0に戻ります。

Re: ヒット判定について

Posted: 2011年2月02日(水) 17:52
by ISLe
softyaさんの補足になりますが。
hit_bullet関数の中で、GetHitKeyStateAllの呼び出しは要りません。ローカルkey配列も要りません。
グローバルな配列Keyを参照するためにCheckStateKeyという関数が用意されているのでそちらを使いましょう。

Re: ヒット判定について

Posted: 2011年2月02日(水) 19:06
by 卒業したい
softyaさんとISLeさんのアドバイスをもとに
14行目のcharをintに
245、248行目を削除したところ、押しっぱなしで消えることはなくなりました。(最初のやつを元に書いています)

その代わり、範囲外で上キーを押すと画像が消え、ランダムに画像が消えるようになってしまいました。
これは、267行目に259行目のプログラムをコピーしたところ、この問題は解消されました。

上キーを押せば上下左右すべてに適用される点は相変わらずです。↓に今までの結果を含め数箇所書き換えたプログラムを表示します。

コード:

#include "DxLib.h"
 
int Key[256];
 
int GetHitKeyStateAll_2(int GetHitKeyStateAll_InputKey[256]){
    char GetHitKeyStateAll_Key[256];
    GetHitKeyStateAll( GetHitKeyStateAll_Key );
    for(int i=0;i<256;i++){
        if(GetHitKeyStateAll_Key[i]==1) GetHitKeyStateAll_InputKey[i]++;
        else GetHitKeyStateAll_InputKey[i]=0;
    }
    return 0;
}
int CheckStateKey(unsigned int Handle){
    return Key[Handle];
}
 int GetJoypadInputState( int InputType ) ;


 
//----------------------------------------------------
int haikei[10];//色のハンドル------------------------------------------------
void gazou1(){//これは背景画像ーーーーーーーーーーーーーーーーーーーーーーーー
haikei[0]=LoadGraph("kop3.png");
haikei[1]=LoadGraph("ue1.png");
haikei[2]=LoadGraph("migi1.png");
haikei[3]=LoadGraph("hidari1.png");
haikei[4]=LoadGraph("sita1.png");
haikei[5]=LoadGraph("a.png");
}
int tama[10];//たまの画像----------------------------------------------------
void gazou2(){
tama[0]=LoadGraph("dan.png");
tama[1]=LoadGraph("ber.png");
}
//--------------------------------------------------------------
int color[10];//これは色の設定-----------------------------------------------
void load(){
    color[0] = GetColor(255,255,255);//白
    color[1] = GetColor( 0, 0, 0);//黒
    color[2] = GetColor(255, 0, 0);//赤
    color[3] = GetColor( 0,255, 0);//緑
    color[4] = GetColor( 0, 0,255);//青
    color[5] = GetColor(255,255, 0);//黄色
    color[6] = GetColor( 0,255,255);//青緑
    color[7] = GetColor(255, 0,255);//紫
}//------------------------------------
int music[1];
void kyoku(){
	music[0] = LoadSoundMem("校歌.mp3");
}
//--------------------------------------------------------------
 
//ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
#define BER_UX 65
#define BER_Y 60
 
#define BER_MX 215
 
#define BER_HX 370

#define BER_SX 525


#define HIT_UX 80
#define HIT_UY 60
 
#define HIT_MX 230
 
#define HIT_HX 385

#define HIT_SX 540



//判定ライン-------------------------------------------------
#define VGOOD_Y 20
#define GOOD_Y 25
#define BAD_Y 30
//ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー//
typedef struct{
    int flag;
    int knd;
}humen_t;//譜面の構造体
#define HUMEN_MAX 1000
humen_t humen[HUMEN_MAX];
 
void load_humen(){
    int i=0,cnt=0;
    int c;
    FILE *fp;
    fp=fopen("ue.txt","r");
    if(fp==NULL)
        return;
        while((c=fgetc(fp))!=EOF){
        if(c==' '||c=='\n')continue;
        if(c!='0'){
            humen[i].flag=1;
            humen[i].knd=c-'0';
        }
            i++;
            if(i>=HUMEN_MAX)break;//オーバーフロー防止
    }
fclose(fp);
}
//テキストから譜面(0,1,2,3,4)を読み込む--------------------------------------------------------

typedef struct{
	int flag;
}KEY_H;
KEY_H KEY;

void KEY_O(){
	if(CheckStateKey(KEY_INPUT_LEFT)==1){
		DrawString(  0,  0, "hello! DX Library!" , color[1]);    

//				KEY.flag=1;
	}
	if(CheckStateKey(KEY_INPUT_DOWN)==1){//ひだり
		DrawString(  100,  100, "hello! DX Library!" , color[1]);    

//				KEY.flag=1;
	}
	if(CheckStateKey(KEY_INPUT_UP)==1){
		 DrawString(  200,  200, "hello! DX Library!" , color[1]);

//				KEY.flag=1;
	}
	if(CheckStateKey(KEY_INPUT_RIGHT)==1){
		DrawString(  300,  300, "hello! DX Library!" , color[1]);

//				KEY.flag=1;
	}}
//キー入力関係--------------------------------------------------------------------------

#define FLAME 60


int fps_count,count0t;//fpsのカウンタ、60フレームに1回基準となる時刻を記録する変数

int f[FLAME];//平均を計算するため60回の1周時間を記録

double ave;//平均fps




void fps_wait(){						//FLAME fps になるようにfpsを計算・制御
    int term,i,gnt;
    static int t=0;
    if(fps_count==0){					//60フレームの1回目なら
        if(t==0)						//完全に最初ならまたない
            term=0;
        else							//前回記録した時間を元に計算
            term=count0t+1000-GetNowCount();
    }
    else								//待つべき時間=現在あるべき時刻-現在の時刻
        term = (int)(count0t+fps_count*(1000.0/FLAME))-GetNowCount();

    if(term>0)							//待つべき時間だけ待つ
        Sleep(term);

    gnt=GetNowCount();

    if(fps_count==0)					//60フレームに1度基準を作る
        count0t=gnt;
    f[fps_count]=gnt-t;					//1周した時間を記録
    t=gnt;
    //平均計算
    if(fps_count==FLAME-1){
        ave=0;
        for(i=0;i<FLAME;i++)
            ave+=f[i];
        ave/=FLAME;
    }
    fps_count = (++fps_count)%FLAME ;
}


void draw_fps(int x, int y){			//x,yの位置にfpsを表示
    if(ave!=0){
        DrawFormatString(x, y,color[0],"[%.1f]",1000/ave);
    }
    return;
}

void FPS_M(){
fps_wait();
draw_fps(0,0);
}
//FPSの管理------------------------------------------------------------------------------------

typedef struct{
    int flag;
    int x,y;
	int se_flag;
	int spd;
	int knd;
}bullet_t;//たまの構造体
#define BULLET_MAX 1000
bullet_t bullet[BULLET_MAX];
 
int flame;
void huru_bullet(){
    int i,j;
    const int list[]={0,HIT_UX,HIT_MX,HIT_HX,HIT_SX};
    i=flame++;
    if(i>=HUMEN_MAX)return;
    if(humen[i].flag==1){
        if(humen[i].knd>=1 && humen[i].knd<=4){
            for(j=0;j<BULLET_MAX;j++) {
                if(bullet[j].flag==0) {
                    bullet[j].flag=humen[i].knd;
                    bullet[j].x=list[humen[i].knd];
                    bullet[j].y=552;
                    break;
                }
            }
        }
    }
}
        
        
 
//譜面のフラグとkndが1の時・・・
int tama_bullet(){
    int i;
    for(i=0;i<BULLET_MAX;i++){
    if(bullet[i].flag!=0){
                bullet[i].y-=3;          //座標を8減らす
                DrawGraph( bullet[i].x , bullet[i].y , tama[0] ,TRUE);
                //ここに当たり判定
				//if(KEY.flag==1){
				if(bullet[i].y < -32){    //もし画面外まで来たら
                                    bullet[i].y=552;    //初期値に戻し、
                                    bullet[i].flag=0;   //発射フラグを戻す
                                }
                        }
               }
return 0;
}


//hit判定

void hit_bullet(){
	int i,j,k,knd;
	double y,pre_y,y0,y1;
	double line_y[3]={VGOOD_Y,GOOD_Y,BAD_Y};
	
	for(i=0;i<BULLET_MAX;i++){//弾分ループ
		if(bullet[i].flag!=0){//弾が存在していて
			knd=-1;
			pre_y=bullet[i].y+bullet[i].spd;
			y=bullet[i].y;
			for(j=0;j<3;j++){
				y0=HIT_UY-line_y[j];
				y1=HIT_UY+line_y[j];
				// ↓148よりx0が下であるか↓148よりx0が上であるか↓x0がxを下回っているか、x1がxを上回っているか↓初期化
				if(y<y0 && y0<pre_y		|| y<y1 && y1<pre_y		|| y0<y && y<y1 ||				y0<pre_y && pre_y<y1){//距離ヒット以内なら
				  //押したときの現在位置が当たり判定の軸からline_x分離れた中にあるなら決められた範囲の処理を行う
					knd=j;//kndに数値を代入する
					break;
				}
			}
			//距離OKでその時たたいていたら
			if(knd!=1&&Key[KEY_INPUT_UP]==1||Key[KEY_INPUT_DOWN]==1||Key[KEY_INPUT_LEFT]==1||Key[KEY_INPUT_RIGHT]==1){
				if(y<y0 && y0<pre_y		|| y<y1 && y1<pre_y		|| y0<y && y<y1 ||				y0<pre_y && pre_y<y1)					bullet[i].flag=0;

				//enter_hit_dat(k,i,knd,bullet[i].x);
			}
				//bullet[j].flag=1;
		}
	}
}
void bullet_main(){
    huru_bullet();
    tama_bullet();
	hit_bullet();
}
//弾関係の設定---------------------------------------------------------------------------------

void music_t(){
//WaitTime(60000);
//PlayMusic( "曲.mid" , DX_PLAYTYPE_BACK ) ;
	PlaySoundMem(music[0],DX_PLAYTYPE_BACK);
}

void ini(){
    memset(bullet,0,sizeof(bullet_t)*BULLET_MAX);//弾情報初期化
    memset(humen,0,sizeof(humen_t)*HUMEN_MAX);//結果表示情報初期化
}
//初期化設定------------------------------------------------------------------------------------
void matome(){
    gazou1();
    gazou2();
    DrawGraph(0,0,haikei[0],TRUE);
 kyoku();
    load();
    load_humen();
    flame=0;
    FPS_M();    
	DrawBox( 0, 70 , 645 , 75 , color[0] ,TRUE);
        DrawBox( 85 , 0 , 95 , 480 , color[2],TRUE );
        DrawBox( 235 , 0 , 245 , 480 , color[3],TRUE );
        DrawBox( 390 , 0 , 400 , 480 , color[4],TRUE );
        DrawBox( 545 , 0 , 555 , 480 , color[5],TRUE );
		KEY_O();
 }
//まとめ----------------------------------------------------------------------------------------
void graph(){
    ClearDrawScreen();
    DrawGraph(0,0,haikei[0],TRUE);
    DrawGraph(90,0,haikei[1],TRUE);
    DrawGraph(240,0,haikei[2],TRUE);
    DrawGraph(395,0,haikei[3],TRUE);
    DrawGraph(550,0,haikei[4],TRUE);
        DrawBox( 0, 70 , 645 , 75 , color[0] ,TRUE);
        DrawBox( 85 , 0 , 95 , 480 , color[2],TRUE );
        DrawBox( 235 , 0 , 245 , 480 , color[3],TRUE );
        DrawBox( 390 , 0 , 400 , 480 , color[4],TRUE );
        DrawBox( 545 , 0 , 555 , 480 , color[5],TRUE );
		KEY_O();
}
//画像に関するプログラム----------------------------------------------------------------------- 
//ループで必ず行う3大処理
 
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
    ChangeWindowMode(TRUE);//ウィンドウモード
    
    if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化
    ini();
	music_t();
    matome();
	kyoku();
	music_t();


while(ProcessMessage()==0&&GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
        //↑メッセージ処理   ↑画面をクリア     ↑入力状態を保存       ↑ESCが押されていない


		graph();
		FPS_M();
 
		
        bullet_main();

        ScreenFlip();
		if(CheckStateKey(KEY_INPUT_ESCAPE)==1)break;//エスケープが入力されたらブレイク
    }
    
    DxLib_End();
    return 0;
}
1、範囲内に入った画像のX座標を割り出し、(80、230、385、540)その画像が上キーで消えるかどうか(80)
2、上キーに画像のX座標(80)を定義させ、上キーが80のみに反応するようにする
という私が今現在思いついている解決策なのですが、これをプログラムであらわすとどうなりますか?
何度かトライしてはいますがうまくプログラムにできません。

Re: ヒット判定について

Posted: 2011年2月02日(水) 19:49
by h2so5
演算子には優先順位があります。
&&の方が||より順位が高いため、

if(knd!=1&&Key[KEY_INPUT_UP]==1||Key[KEY_INPUT_DOWN]==1||Key[KEY_INPUT_LEFT]==1||Key[KEY_INPUT_RIGHT]==1)

このようなコードは、

if((knd!=1&&Key[KEY_INPUT_UP]==1)||Key[KEY_INPUT_DOWN]==1||Key[KEY_INPUT_LEFT]==1||Key[KEY_INPUT_RIGHT]==1)

と同じ意味になります。

Re: ヒット判定について

Posted: 2011年2月03日(木) 12:50
by 卒業したい
h2so5さんやほかの皆さんのおかげで無事に解決しました!!
&&がつくと優先順位が決まってしまうということで
上下左右ばらばらに分けてみました。
そして、別に作ったテキストファイルを読み込ませるプログラムから、数字ごとに分かれている
発射フラグを一度だけ演算してフラグを0にする方法をとりました。

softyaさんとISLeさんのアドバイスで押しっぱなしが改善され、
h2so5さんのヒントで上キーを押せば上下左右すべてに適用される点も改善されました。
新たに変数kをひとつ用意し、for文(k=0;k<1;k++)のループの中に上下左右の判定とフラグを演算するプログラムを打ち込み、
それぞれにk+=1;を入れ一回入力でブレイク。
演算結果を確認し、合っていなかったらフラグを立てたままにするという方法です。

コード:

					for(k=0;k<1;k++){
					if(Key[KEY_INPUT_UP]==1)
						bullet[i].flag-=3;
					k+=1;
					if(Key[KEY_INPUT_RIGHT]==1)
						bullet[i].flag-=4;
					k+=1;
					if(Key[KEY_INPUT_LEFT]==1)
						bullet[i].flag-=1;
					k+=1;
					if(Key[KEY_INPUT_DOWN]==1)
						bullet[i].flag-=2;
					k+=1;
					break;}
					if(bullet[i].flag!=0&&k==1)
						bullet[i].flag=1;
このたびは長ったるいプログラムにお付き合いいただきありがとうございました。