23. 行けない所を作る。〜1D〜


ダンジョンの中には進めない場所もありますよね。次は進めない場所をどうやって判定するか、勉強していきましょう。

まず、せっかく32x32ピクセルの範囲に1単位を定義したんですから、その区間を利用しましょう。

2次元で考える前にまず、1次元で考えて見ます。

横方向に32x32ピクセル単位で分割し、その中を歩いている感じを思い浮かべてください。



その区間が0の場所は通れるとし、1の場所は通れないと考えれば、通れない場所が作れますね。

横幅は640ピクセルありますから、32で割ると、20個の区間があります。ですから変数としては図の通りだと

int hantei[20] = { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1} ;

こういう風に作ればいいのです。区間の大きさは1つ32ピクセルですから

現在のx座標を32で割れば、現在いる区間の配列要素番号になります。

次に進もうとする方向の区間の配列要素が1ならば進めない、そんな判定をする関数を書いてみましょう。

int IsAbleToGo(int x,int y,int muki){
  if(muki==1)
    if(hantei[x/32+1]==1)
      return 1;
  if(muki==3)
    if(hantei[x/32-1]==1)
      return 1;
  return 0;
}


リターン1は進めない、リターン0は進める事を意味します。

右向き進行なら配列要素+1で判定すればいいし、左向きなら配列要素-1で判定すればいいのです。

では以下のサンプルプログラムを見てみましょう。

少々長いプログラムですが、新しく書いたIsAbleToGo関数と、それを呼んでいる部分しか変更していないので

そこだけ見てください。


#include "DxLib.h"
 
typedef struct{
        int x,y,img,muki,walking_flag;
}ch_t;
 
int hantei[20] = { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 } ;
 
int IsAbleToGo(int x,int y,int muki){//進む方向が通れるか通れないかを判定
        if(muki==1)//左向きなら
                if(hantei[x/32-1]==1)//通れないなら
                        return 1;//エラー
        if(muki==3)//右向きなら
                if(hantei[x/32+1]==1)//通れないなら
                        return 1;//エラー
        return 0;//正常
}
 
 
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
        
    int image[16];
    char Key[256];
    ch_t ch;
 
    if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //ウィンドウ化と初期化処理
 
    ch.x    =320;
    ch.y    =160;
    ch.walking_flag=0;
    ch.muki=3;
 
    SetDrawScreen( DX_SCREEN_BACK ) ;                                                 //描画先を裏画面に設定
    LoadDivGraph( "char.png" , 16 , 4 , 4 , 32 , 32 , image ) ;//画像を分割してimage配列に保存
 
    while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
            //↑メッセージ処理        ↑画面をクリア         ↑キーボード入力状態取得       ↑ESCが押されると終了
 
        if(ch.x%32==0 && ch.y%32==0){         //座標が32で割り切れたら入力可能
            ch.walking_flag=1;         //歩くフラグを立てる。
            if     ( Key[ KEY_INPUT_UP   ]  == 1 )  //上ボタンが押されたら
                    ch.muki=0;         //上向きフラグを立てる
            else if( Key[ KEY_INPUT_LEFT ]  == 1 )  //左ボタンが押されたら
                    ch.muki=1;         //左向きフラグを立てる
            else if( Key[ KEY_INPUT_DOWN ]  == 1 )  //下ボタンが押されたら
                    ch.muki=2;         //下向きフラグを立てる
            else if( Key[ KEY_INPUT_RIGHT]  == 1 )  //右ボタンが押されたら
                    ch.muki=3;         //右向きフラグを立てる
            else                                    //何のボタンも押されてなかったら
                    ch.walking_flag=0; //歩かないフラグを立てる
            if(ch.walking_flag==1)    //もし歩くなら
                if(IsAbleToGo(ch.x,ch.y,ch.muki)==1)//行き先が歩けないなら
                    ch.walking_flag=0;                  //歩かないフラグを立てる。
        }
 
        if(ch.walking_flag==1){        //歩くフラグが立っていたら
            if     (ch.muki==0)        //上向きならch.y座標を減らす
                    ch.y--;
            else if(ch.muki==1)        //左向きならch.x座標を減らす
                    ch.x--;
            else if(ch.muki==2)        //下向きならch.y座標を増やす
                    ch.y++;
            else if(ch.muki==3)        //右向きならch.x座標を増やす
                    ch.x++;
        }
 
        ch.img=image[(ch.x%32+ch.y%32)/8 + ch.muki*4];            //画像をセット
 
        DrawGraph( ch.x , ch.y , ch.img , TRUE ) ;//画像を描画
 
        ScreenFlip();//裏画面を表画面に反映
    }
 
    DxLib_End();
    return 0;
}

実行結果

注意)黄色い文字や線は表示されません。

左右とも、配列が1にあたる部分でとまります。

→掲示板で質問する



- Remical Soft -