こんにちは kameoです。
今度はキャラクターの当たり判定についての質問があります。
次のようなプログラムを作成したいと思います。
①プレイヤーが移動量が4*fで動いている。
②通常ならば、f=1
③もし、壁に衝突するならば、
④f=0にする。
実際のサンプルコードはこのようになりました。(壁衝突判定はhttp://dixq.net/g/26.htmlのを使わせてもらいました)
#include "DxLib.h"
typedef struct{ //プレイヤー
int x,y,img;
}ch_t;
int image[9];//画像イメージ
char Key[256];
ch_t ch;
int hantei[15][20] = {
{ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1 },
{ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 },
{ 1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
};
int can_or_cannot(int x,int y,int muki){//進めるかを判定する
if(muki==0)//上向きなら
if(hantei[y/32-1][x/32]==1)//進めるか判定
return 1;//エラー
if(muki==3)//左向きなら
if(hantei[y/32][x/32-1]==1)
return 1;
if(muki==1)//下向きなら
if(hantei[y/32+1][x/32]==1)
return 1;
if(muki==4)//右向きなら
if(hantei[y/32][x/32+1]==1)
return 1;
return 0;//正常
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //ウィンドウ化と初期化処理
//プレイヤー座標及び向き
ch.x =32;
ch.y =32;
int muki=0;
int i,j;
SetDrawScreen( DX_SCREEN_BACK ) ; //描画先を裏画面に設定
LoadDivGraph( "jiji.png" , 9 , 3 , 3 , 32 , 32 , image ) ;//画像を分割してimage配列に保存
while(1){
ClearDrawScreen();
GetHitKeyStateAll(Key);
if(ProcessMessage()==-1)break;
for(i=0;i<15;i++)//障害物描写
for(j=0;j<20;j++)
if(hantei[j]==1)
DrawBox(j*32,i*32,(j+1)*32,(i+1)*32,GetColor(255,255,255),TRUE);
if (can_or_cannot(ch.x,ch.y,muki)==1) f=0; //上記③④参考
else f=1;
//移動
if( Key[ KEY_INPUT_RIGHT ] == 1 ) {
ch.x+=4*f ;
muki=4;
}
if( Key[ KEY_INPUT_LEFT ] == 1 ) {
ch.x-=4*f ;
muki=3;
}
if( Key[ KEY_INPUT_UP ] == 1 ) {
ch.y-=4*f ;
muki=0;
}
if( Key[ KEY_INPUT_DOWN ] == 1 ) {
ch.y+=4*f ;
muki=1;
}
//プレイヤー描写
ch.img=image[muki];
DrawGraph( ch.x , ch.y, ch.img , TRUE ) ;
if (Key[KEY_INPUT_ESCAPE]==1) break;
ScreenFlip();//裏画面を表画面に反映
}
DxLib_End();
return 0;
}
このプログラムを実行したとき、壁によってはプレイヤーがすり抜けてしまったり、壁にぶつかっていないにも
関わらず、動作が途中で止まってしまったりしています。
どうしてこのような現象が起こるのでしょうか?
アドバイスお願いします。
壁との当たり判定
Re:壁との当たり判定
はじめまして、白い時空といいます。
卒業して暇になったので質問に答えたいと思います。
111111
000人00
このとき左向きとし、上を押すと、向き(mukiの値)はまだ左なので
can_or_cannot()で0が返ってしまいf=1で上に移動してしまいます。
このとき上向きとし、左を押すと、向きはまだ上なので
can_or_cannot()で1が返ってしまいf=0で移動できません。
mukiはcan_or_cannot()の前で変更するべきです。
あと、移動のif文ですがelse if文にしないと斜め移動します。
斜め移動がしたいなら、上下と左右の移動判定を別々にするべきです。
卒業して暇になったので質問に答えたいと思います。
111111
000人00
このとき左向きとし、上を押すと、向き(mukiの値)はまだ左なので
can_or_cannot()で0が返ってしまいf=1で上に移動してしまいます。
このとき上向きとし、左を押すと、向きはまだ上なので
can_or_cannot()で1が返ってしまいf=0で移動できません。
mukiはcan_or_cannot()の前で変更するべきです。
あと、移動のif文ですがelse if文にしないと斜め移動します。
斜め移動がしたいなら、上下と左右の移動判定を別々にするべきです。