ページ 11

上下左右の当たり判定

Posted: 2012年4月04日(水) 22:38
by 狼太郎
真上から見下ろし型でDrawbox関数で生成された赤い四角(プレイヤーは緑の四角)に当たるとその方向へは進めないようにしたいのですが、四角形を表示させることは出来ましたが、当たり判定の作成がどうしても上手くいきません。

形としては四角の四隅に当たり判定を設けて、どの面が接しているか判断させようとしています。

コード:

#include "DxLib.h"
#include<math.h>
void stagecreate(int glid[10][10],int *x,int *y); //ステージ生成関数//
void playerpoint(int glid[10][10],int *x,int *y);//プレイヤーの位置描画&当たり判定関数//
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
	ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);
	int x=50,y=50;
	int Glid[10][10]=  {{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,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},
					   };
	while(ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0){
		stagecreate(Glid,&x,&y);
		playerpoint(Glid,&x,&y);
		
	}
	DxLib_End();
	return 0;
}
void stagecreate(int glid[10][10],int *x,int *y){
	int sx=0,sy=0;
	int Color=0;
	Color=GetColor(255,0,0);
	for(sy=0;sy<10;sy++){
		for(sx=0;sx<10;sx++){
			if(glid[sy][sx]==1){
				DrawBox(sx*20,sy*20,sx*20+20,sy*20+20,Color,TRUE);
			}
		}
	}
}
void playerpoint(int glid[10][10],int *x,int *y){
	int pcolor;
	pcolor=GetColor(0,255,0);
	char keybord[256];
	GetHitKeyStateAll(keybord);
	if(keybord[KEY_INPUT_W] !=0 ) *y-=2;
	if(keybord[KEY_INPUT_S] !=0 ) *y+=2;
	if(keybord[KEY_INPUT_D] !=0 ) *x+=2;
	if(keybord[KEY_INPUT_A] !=0 ) *x-=2;
	if(glid[*x/10][*y/10]==1 || glid[*x/10][(*y+20)/10]==1) *x+=2;
	if(glid[(*x+20)/10][*y/10]==1 || glid[(*x+20)/10][(*y+20)/10]==1) *x-=2;
	if(glid[*x/10][*y/10]==1 || glid[(*x+20)/10][*y/10]==1)*y+=2;
	if(glid[*x/10][(*y+20)/10]==1 || glid[(*x+20)/10][(*y+20)/10]==1)*y-=2;
	DrawBox(*x,*y,*x+20,*y+20,pcolor,TRUE);
}
何度も考えて改変したのですが上手くいきません。どこか間違っているところを教えて下さい。

Re: 上下左右の当たり判定

Posted: 2012年4月05日(木) 10:46
by softya(ソフト屋)
ざっと見た感じでglidと座標の比率は1:10か1:20のどちらでしょう?
今のコードではstagecreateの表示では1:20ですが、playerpointの当たり判定では1:10になっています。

Re: 上下左右の当たり判定

Posted: 2012年4月05日(木) 11:47
by softya(ソフト屋)
glidが[y][x]で参照している所と[x][y]で参照している所があったので統一して1:20で統一、当たり判定を視覚化してみました。

コード:

#include "DxLib.h"
#include<math.h>
void stagecreate(int glid[10][10],int *x,int *y); //ステージ生成関数//
void playerpoint(int glid[10][10],int *x,int *y);//プレイヤーの位置描画&当たり判定関数//
int glidCheck(int glid[10][10],int x,int y);
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
    ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);
    int x=50,y=50;
    int Glid[10][10]=  {{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,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},
                       };
    while(ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0){
        stagecreate(Glid,&x,&y);
        playerpoint(Glid,&x,&y);
        
    }
    DxLib_End();
    return 0;
}
void stagecreate(int glid[10][10],int *x,int *y){
    int sx=0,sy=0;
    int Color=0;
    Color=GetColor(0,0,255);
    for(sy=0;sy<10;sy++){
        for(sx=0;sx<10;sx++){
            if(glid[sy][sx]==1){
                DrawBox(sx*20,sy*20,sx*20+20,sy*20+20,Color,TRUE);
            }
        }
    }
}
void playerpoint(int glid[10][10],int *x,int *y){
    int pcolor;
    pcolor=GetColor(0,255,0);
    char keybord[256];
    GetHitKeyStateAll(keybord);
    if(keybord[KEY_INPUT_W] !=0 ) *y-=2;
    if(keybord[KEY_INPUT_S] !=0 ) *y+=2;
    if(keybord[KEY_INPUT_D] !=0 ) *x+=2;
    if(keybord[KEY_INPUT_A] !=0 ) *x-=2;
    if(glidCheck(glid,*x,*y)	|| glidCheck(glid,*x,*y+20) ) 		*x+=2;
    if(glidCheck(glid,*x+20,*y)	|| glidCheck(glid,*x+20,*y+20) )	*x-=2;
    if(glidCheck(glid,*x,*y)	|| glidCheck(glid,*x+20,*y) )		*y+=2;
    if(glidCheck(glid,*x,*y+20)	|| glidCheck(glid,*x+20,*y+20) )	*y-=2;
    DrawBox(*x,*y,*x+20,*y+20,pcolor,TRUE);
}

int glidCheck(int glid[10][10],int x,int y)
{
	int mx = x / 20;
	int my = y / 20;
	int cx = mx * 20;
	int cy = my * 20;
	
	int check = ( glid[my][mx] == 1 );
	
	//	当たり判定の視覚化
	if( check ) {
	    DrawBox(cx,cy,cx+20,cy+20,GetColor(255,0,0),FALSE);
	} else {
	    DrawBox(cx,cy,cx+20,cy+20,GetColor(255,255,255),FALSE);
	}
	return check;
}


Re: 上下左右の当たり判定

Posted: 2012年4月06日(金) 20:53
by 狼太郎
回答ありがとうございました。
どこが間違っていたのかわかりましたが、
実行すると上と下にあたった時に勝手に左右に動いてしまいます。
何度もすみませんが、どのような条件式を追加すればいいのでしょうか?

Re: 上下左右の当たり判定

Posted: 2012年4月06日(金) 21:13
by softya(ソフト屋)
今の処理は移動後に移動出来なかったら移動を取り消してますが、その条件が4方向同時に調べているので問題があります。
移動する方向を先に調べて移動できるなら移動する形にした方が良いと思います。

Re: 上下左右の当たり判定

Posted: 2012年5月05日(土) 22:54
by 狼太郎
回答有難うございました。改良して一応上下左右の当たり判定を作ることができました。
しかし、確かに四方向で止まるようになったのですが、止まったあと、不自然にのめり込むというかスライドしません。
左側は滑るのですが右側がつっかかります。

コード:

#include "DxLib.h"
#include<math.h>
void stagecreate(int glid[10][10],int *x,int *y); //ステージ生成関数//
void playerpoint(int glid[10][10],int *x,int *y);//プレイヤーの位置描画&当たり判定関数//
int glidCheck(int glid[10][10],int x,int y);
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
    ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);
    int x=50,y=50;
    int Glid[10][10]=  {{0,0,0,1,0,0,0,0,0,0},
                        {0,0,0,1,0,0,0,0,0,0},
                        {0,0,0,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,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},
                       };
    while(ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0){
        stagecreate(Glid,&x,&y);
        playerpoint(Glid,&x,&y);
        
    }
    DxLib_End();
    return 0;
}
void stagecreate(int glid[10][10],int *x,int *y){
    int sx=0,sy=0;
    int Color=0;
    Color=GetColor(0,0,255);
    for(sy=0;sy<10;sy++){
        for(sx=0;sx<10;sx++){
            if(glid[sy][sx]==1){
                DrawBox(sx*20,sy*20,sx*20+20,sy*20+20,Color,TRUE);
            }
        }
    }
}
void playerpoint(int glid[10][10],int *x,int *y){
    int pcolor;
	int flagu=0,flagd=0,flagl=0,flagr=0;
    pcolor=GetColor(0,255,0);
    char keybord[256];
    GetHitKeyStateAll(keybord);
    if(keybord[KEY_INPUT_W] !=0 ) flagu=1;
    if(keybord[KEY_INPUT_S] !=0 ) flagd=1;
    if(keybord[KEY_INPUT_D] !=0 ) flagr=1;
    if(keybord[KEY_INPUT_A] !=0 ) flagl=1;
    if((glidCheck(glid,*x,*y)    || glidCheck(glid,*x,*y+20)) &&  !glidCheck(glid,*x+20,*y) && !glidCheck(glid,*x+20,*y+20))       flagl=0;
	if((glidCheck(glid,*x+20,*y) || glidCheck(glid,*x+20,*y+20)) &&  !glidCheck(glid,*x,*y+20) && !glidCheck(glid,*x,*y))    flagr=0;
	if(glidCheck(glid,*x,*y)    || glidCheck(glid,*x+20,*y) && !glidCheck(glid,*x+20,*y+20) && !glidCheck(glid,*x,*y+20))       flagu=0;
	if(glidCheck(glid,*x,*y+20) || glidCheck(glid,*x+20,*y+20) && !glidCheck(glid,*x+20,*y) && !glidCheck(glid,*x,*y))    flagd=0;
	if(flagu==1) *y=*y-2;
	if(flagd==1) *y=*y+2;
	if(flagr==1) *x=*x+2;
	if(flagl==1) *x=*x-2;
    DrawBox(*x,*y,*x+20,*y+20,pcolor,TRUE);
}
 
int glidCheck(int glid[10][10],int x,int y)
{
    int mx = x / 20;
    int my = y / 20;
    
    int check = ( glid[my][mx] == 1 );

    return check;
}

Re: 上下左右の当たり判定

Posted: 2012年5月06日(日) 00:27
by softya(ソフト屋)
前のプログラムに書いた当たり判定ボックスを復活して見てもらうと分かると思うのですが、当たり判定ボックスが移動の先を指していない事があるのが分かると思います。
これを修正出来れば食い込むことはなくなると思います。