キャラクタと壁のあたり判定について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ついうくん

キャラクタと壁のあたり判定について

#1

投稿記事 by ついうくん » 11年前

コード:

 


#include "DxLib.h"

int muki=3,a_flag=0,i,j;
int px=300,py=418;
int y_tmp=0,y_prev=0;
bool p_flag=false;
char Key[256];
float speed=1.0f;
int mode=0;
int h_color=(255,0,0);
int color=GetColor(255,255,255);
int haikei,player[16],Handle;
int xcount=0,ycount=0;
int ix=0,iy=0,result=0;

int hantei[15][20]={

		{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
        { 1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 },
        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
        { 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0 },
        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
        { 0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0 },
        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1 },
        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
        { 0,1,0,0,1,0,0,1,0,0,0,1,0,0,0,1,0,0,1,0 },
        { 1,1,1,1,1,0,1,1,1,0,1,1,1,0,1,1,0,1,1,1 },

};


int IsAbleToGo(int x,int y,int muki){     //進めるかどうかの判定

	if(muki==0)
		if(hantei[y/32-1][x/32]==1)                             //ブロックの1つ上、その場所
			return 1;
	if(muki==1)                        //エラー値を返す
		if(hantei[y/32][x/32-1]==1)                             //その場所、ブロックの一つ左
			return 1;
	if(muki==2)
		if(hantei[y/32+1][x/32]==1)                             //ブロックの一つ下、その場所
			return 1;
	if(muki==3)
		if(hantei[y/32][x/32+1]==1)                             //その場所、ブロックの一つ下
			return 1;
	return 0;

}



void title(){

	DrawGraph(0,0,haikei,FALSE);
	DrawString(240,270,"ゲーム:G",color);
	DrawString(240,290,"コンフィグ:c",color);
	DrawString(240,310,"終了:esc",color);
	
	if(Key[KEY_INPUT_G]==1) mode = 1;		
	if(Key[KEY_INPUT_C]==1) mode = 2;

}


void kabe(){

	for(i=0;i<15;i++)                                                    //縦
		for(j=0;j<20;j++)                                                //横
			if(hantei[i][j]==1)                                          //i,jで1がたっているところは
				DrawBox(j*32,i*32,(j+1)*32,(i+1)*32,color,TRUE);         //jが1なら32、iが1なら32かける(ブロック1つを表示させる)、右のブロックにも32かける、したのブロックにも32かける
}


void pmove(){	

	if(Key[KEY_INPUT_LEFT]==1 || Key[KEY_INPUT_RIGHT]==1){
		if(Key[KEY_INPUT_UP]==1 || Key[KEY_INPUT_DOWN]==1){
			speed=0.71f;
		}else{
			speed=1.0f;
		}
	}else if(Key[KEY_INPUT_UP]==1||Key[KEY_INPUT_DOWN]==1){
				speed=0.7f;
	}	  	  

	if(Key[KEY_INPUT_LEFT]==1){
		px-=(int)4*speed;
	}

	if(Key[KEY_INPUT_RIGHT]==1){
		px+=(int)4*speed;
	}

	if(Key[KEY_INPUT_DOWN]==1){
	}
			
	if(p_flag==true){																	//ジャンプしてるとき
		y_tmp=py;										//pyを保存し
		py+=(py-y_prev)+1;																//ジャンプする前の値をpyから引いて、1足したのをpyに足す
		y_prev=y_tmp;                    
		if(py==418){																	//pyが418まで増えたら            
			p_flag=false;                                                           //ジャンプフラグを折る
		}
	}

	if(Key[KEY_INPUT_UP]==1&&p_flag==false){                                        //ジャンプしていないときにスペースを押すと
		p_flag=true;                                     //ジャンプフラグを立ててから
		y_prev=py;                                      //現在のpを保存させて
		py=py-20;                                      //今の場所から20引いたのを、pyに代入
	}

	if(px>=640-32) px=640-32;															//移動制御
	else if(px<=0) px=0;

	if(py>=480+32) py=480+32;																	//同上
	else if(py<0-18) py=0;
		
	if(Key[KEY_INPUT_M]==1) mode=0;

	if(px%32==0&&py%32==0){																 //自分の座標が32で割り切れたら、入力できる
		a_flag=1;                                       //歩くフラグを立てる

		if(Key[KEY_INPUT_UP]==1)
			muki=0;
		else if(Key[KEY_INPUT_LEFT]==1)
			muki=1;
		else if(Key[KEY_INPUT_DOWN]==1)
			muki=2;
		else if(Key[KEY_INPUT_RIGHT]==1)
			muki=3;
		else a_flag=0;                                   //どれも押されてないなら、歩かない

		if(a_flag==1)
			if(IsAbleToGo(px,py,muki)==1)												//行き先が歩けないなら
				a_flag=0;                                //歩くフラグを倒す
	}

	Handle=player[(px%32+py%32)/8+muki*4];                        
	DrawGraph(px,py,Handle,TRUE);
	DrawString(0,0,"M:メニュー画面",GetColor(255,0,0));

}


int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){ 
	ChangeWindowMode(TRUE);

	if( DxLib_Init() == -1 ) return -1;

	LoadDivGraph("キャラクタ10.png",16,4,4,32,32,player);
	haikei=LoadGraph("メニュー背景.png");

	SetDrawScreen( DX_SCREEN_BACK );

		while(1){	
			ClearDrawScreen();
			GetHitKeyStateAll(Key);

			switch(mode){
			case 0:
				title();
				break;
			case 1:
				kabe();
				pmove();
				break;
			default:
				DxLib_End();
				return 0;
				break;
			}

			if(Key[KEY_INPUT_ESCAPE]==1) break;

			if(ProcessMessage()==-1) break;

			ScreenFlip();

		}

		DxLib_End();
		return 0;

		}






			











printfDx関数で調べてみると、どうやら

コード:



 if(px%32==0&&py%32==0){                                                              //自分の座標が32で割り切れたら、入力できる
        a_flag=1;                                       //歩くフラグを立てる
 
        if(Key[KEY_INPUT_UP]==1)
            muki=0;
        else if(Key[KEY_INPUT_LEFT]==1)
            muki=1;
        else if(Key[KEY_INPUT_DOWN]==1)
            muki=2;
        else if(Key[KEY_INPUT_RIGHT]==1)
            muki=3;
        else a_flag=0;                                   //どれも押されてないなら、歩かない
 
        if(a_flag==1)
            if(IsAbleToGo(px,py,muki)==1)                                               //行き先が歩けないなら
                a_flag=0;                                //歩くフラグを倒す
    }


の部分が動作していないみたいで

そもそも、a_flagがたっていないみたいで、動かないです

もし、ほかに訂正ポイントなどがあれば教えていただいてもよろしいでしょうか

rascal
記事: 27
登録日時: 11年前

Re: キャラクタと壁のあたり判定について

#2

投稿記事 by rascal » 11年前

こんばんは

えっとprintfDxでpxとpyの確認をしましょう

このプログラムでは pxとpyが同時に32にでわりきれないと入力をうけつけない としてあります
px とpy がきちんと32でわりきれる数字になっていますでしょうか?

なっていない場合は その部分はプログラムとしては動作していないので if文を変更するか
32で割り切れるようにプログラムを改変する必要があります

ついうくん

Re: キャラクタと壁のあたり判定について

#3

投稿記事 by ついうくん » 11年前

コード:



#include "DxLib.h"

int muki=3,a_flag=0,i,j;
int px=300,py=418;
int y_tmp=0,y_prev=0;
bool p_flag=false;
char Key[256];
float speed=1.0f;
int mode=0;
int h_color=(255,0,0);
int color=GetColor(255,255,255);
int haikei,player[16],Handle;
int xcount=0,ycount=0;
int ix=0,iy=0,result=0;

int hantei[15][20]={

		{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
        { 1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 },
        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
        { 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0 },
        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
        { 0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0 },
        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1 },
        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
        { 0,1,0,0,1,0,0,1,0,0,0,1,0,0,0,1,0,0,1,0 },
        { 1,1,1,1,1,0,1,1,1,0,1,1,1,0,1,1,0,1,1,1 },

};


int IsAbleToGo(int x,int y,int muki){     //進めるかどうかの判定

	if(p_flag==true)
		if(hantei[y/32-1][x/32]==1)                             
			return 1;
	if(muki==1)                        //エラー値を返す
		if(hantei[y/32][x/32-1]==1)                            
			return 1;
	if(p_flag==false)
		if(hantei[y/32+1][x/32]==1)                             
			return 1;
	if(muki==3)
		if(hantei[y/32][x/32+1]==1)                            
			return 1;
	return 0;

}


void gameover(){
	ClearDrawScreen();
	DrawString(132,123,"gameover",GetColor(255,54,32),TRUE);
}


void title(){

	DrawGraph(0,0,haikei,FALSE);
	DrawString(240,270,"ゲーム:G",color);
	DrawString(240,290,"コンフィグ:c",color);
	DrawString(240,310,"終了:esc",color);
	
	if(Key[KEY_INPUT_G]==1) mode = 1;		
	if(Key[KEY_INPUT_C]==1) mode = 2;

}


void kabe(){

	for(i=0;i<15;i++)                                                    
		for(j=0;j<20;j++)                                               
			if(hantei[i][j]==1)                                          //i,jで1がたっているところは
				DrawBox(j*32,i*32,(j+1)*32,(i+1)*32,color,TRUE);         //jが1なら32、iが1なら32かける(ブロック1つを表示させる)、右のブロックにも32かける、したのブロックにも32かける
}


void pmove(){	

	if(Key[KEY_INPUT_LEFT]==1||Key[KEY_INPUT_RIGHT]==1){
		if(Key[KEY_INPUT_UP]==1|| Key[KEY_INPUT_DOWN]==1){
			speed=0.71f;
		}else{
			speed=1.0f;
		}
	}else if(Key[KEY_INPUT_UP]==1||Key[KEY_INPUT_DOWN]==1){
				speed=0.7f;
	}	  	  

	if(Key[KEY_INPUT_LEFT]==1){
		a_flag=1;
		//muki=1;
		px-=(int)4*speed;
	}

	if(Key[KEY_INPUT_RIGHT]==1){
		a_flag=1;
		//muki=3;
		px+=(int)4*speed;
	}

	
			
	if(p_flag==true){																	
		y_tmp=py;										
		py+=(py-y_prev)+1;																
		y_prev=y_tmp;                    
		if(py==418){																	        
			p_flag=false;                                                           
		}
	}

	if(Key[KEY_INPUT_UP]==1&&p_flag==false){                                        //ジャンプしていないときにスペースを押すと
		p_flag=true;                                     //ジャンプフラグを立ててから
		y_prev=py;                                      //現在のpを保存させて
		py=py-20;                                      //今の場所から20引いたのを、pyに代入
	}


	if(px>=640-32) px=640-32;															
	else if(px<=0) px=0;

	if(py>=480+32) py=480+32;

	if(py>480) gameover();
																	
		

	if(a_flag==1){
		if(Key[KEY_INPUT_LEFT]==1)
			muki==1;

		if(Key[KEY_INPUT_RIGHT]==1)
			muki==3;
		}else a_flag=0;


	if(a_flag==1){

		if(muki==1)
			if(IsAbleToGo(px,py,muki)==1)
				px+=(int)4*speed;
			
		if(muki==3)
			if(IsAbleToGo(px,py,muki)==1)
				px-=(int)4+speed;

		//if(IsAbleToGo(px,py,muki)==1)
			//a_flag=0;

		if(p_flag==false)
			if(IsAbleToGo(px,py,muki)==1)
				py+=(int)4*speed;

			if(p_flag==true)
				if(IsAbleToGo(px,py,muki)==1)
					p_flag=false;

	}

				
	DrawString(0,0,"M:メニュー画面",GetColor(255,0,0));
	Handle=player[(px%32+py%32)/8+muki*4];                        
	DrawGraph(px,py,Handle,TRUE);
	
	if(Key[KEY_INPUT_M]==1) mode=0;

}


int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){ 
	ChangeWindowMode(TRUE);

	if( DxLib_Init() == -1 ) return -1;

	LoadDivGraph("キャラクタ10.png",16,4,4,32,32,player);
	haikei=LoadGraph("メニュー背景.png");

	SetDrawScreen( DX_SCREEN_BACK );

		while(1){	
			ClearDrawScreen();
			GetHitKeyStateAll(Key);

			switch(mode){
			case 0:
				title();
				break;
			case 1:
				kabe();
				pmove();
				break;
			default:
				DxLib_End();
				return 0;
				break;
			}

			if(Key[KEY_INPUT_ESCAPE]==1) break;

			if(ProcessMessage()==-1) break;

			ScreenFlip();

		}

		DxLib_End();
		return 0;

		}





一度アルゴリズムを組みなおし

1.壁かどうかの判定

2.もし、上、左右のキーが入力されていたら、a_flagを立てて、キャラを進める

3、どのフラグがたっているのかをみて、壁かどうかの関数で調べて==1なら
 歩くのをやめさせる。

という処理を書いて、実行させてみると、壁に当たり判定がついているのではなく、壁とは若干座標がずれたところにあたり判定がついていました

これは、どのようにして直せばよいでしょうか?

閉鎖

“C言語何でも質問掲示板” へ戻る