ページ 11

無題

Posted: 2008年8月20日(水) 17:58
by yasya
こんにちは。
さっそく質問なんですが、ゲームプログラミングの館の25aのサンプルプログラムを参考にして、敵と遭遇させるプログラムを作ってみたのですが、敵と遭遇してマップ画面に戻って来たとき、何もキーを押してないのにキャラが勝手に動いてしまいます。マップ画面に戻ってきてもキャラが勝手に動かなくなるようにするにはどうしたらいいんでしょうか。

Re:無題

Posted: 2008年8月20日(水) 18:18
by kazuoni
ちょっとこれだけだけだと「ここがいけない」ってのが言えないのでコードをみせていただけませんか?そうすればいい回答が得られると思います。

なんだか戦闘シーンに入るときのマップのフラグ処理がいけない(忘れている)気がしますが・・・

Re:無題

Posted: 2008年8月20日(水) 19:32
by yasya
#include "DxLib.h"

char Key[256];
int func_states=0;
int White;
int image[16],i,j;
typedef struct{
        int x,y,img,muki,walking_flag;
}ch_t;
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,1,1,1,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,1,1 },
        { 1,1,1,1,1,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,1,1 },
        { 1,1,1,1,1,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,1,0,0,0,0,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,1,1,1,0,0,0,1,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1 },
        { 1,1,1,1,1,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,1,1 },
        { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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==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 map(){//マップ画面	
//長いので省略します(ゲームプログラミングの館の25aを参照してください^^;)//
}

void battle(){          //戦闘画面
//長いので省略します。//
	if(Key[ KEY_INPUT_Z ]==1){
		func_states=0;
	}
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
        if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //初期化処理
        SetDrawScreen( DX_SCREEN_BACK );        //裏画面に設定
		ch.x    =320;
		ch.y    =160;
		ch.walking_flag=0;
		ch.muki=3;
		LoadDivGraph( "char.png" , 16 , 4 , 4 , 32 , 32 , image ) ;//画像を分割してimage配列に保存

        while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
			switch(func_states){
                         case 0:
							 map();
							 break;
						 case 1:
							 battle();
							 break;
			}
			if( ProcessMessage() == -1 ) break ;                 
			ScreenFlip();
        }
        DxLib_End();
        return 0;
}
こんな感じです。

Re:無題

Posted: 2008年8月20日(水) 23:38
by 管理人
25.aのサンプルの中に

            if(ch.walking_flag==1)
                if(GetRand(4)==0)
                    printfDx("敵");

このように書かれていると思います。
32,32で割り切れるときに、そして歩くフラグが立っている時に判断しています。
つまり、このまま32ピクセル歩く状態です。
なので、条件にマッチした時(敵に遭遇した時)はch.walking_flagを0にして下さい。
 

Re:無題

Posted: 2008年8月21日(木) 00:06
by kazuoni
返事が遅れてしまって申し訳ありませんでした。。もし省略の部分が25.aの通りなら管理人さんのおっしゃる通りです。
ほかにも
if(ch.walking_flag==1 && func_states==0){        //歩くフラグが立っていたら(ifの条件を付け加えています)
            if     (ch.muki==0)        //上向きならch.y座標を減らす
                    ch.y--;
            else if(ch.muki==1)        //左向きならch.x座標を減らす
...............
でもいけると思います^^

Re:無題

Posted: 2008年8月21日(木) 00:43
by 管理人
>if(ch.walking_flag==1 && func_states==0){

いや、mapはfunc_statesが0の時にしかメインから呼ばれませんから、
これではダメじゃないでしょうか?
戻ってきた時、動いてしまうと思います。

Re:無題

Posted: 2008年8月21日(木) 01:05
by kazuoni
void map(){//マップ画面	
	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(can_or_cannot(ch.x,ch.y,ch.muki)==1)//行き先が歩けないなら
                    ch.walking_flag=0;                  //歩かないフラグを立てる。
            if(ch.walking_flag==1)
                if(GetRand(10)==0)
		func_states=1;
	}
	if(ch.walking_flag==1 && func_states==0){        //歩くフラグが立っていたら
            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 ) ;//画像を描画
}
本当にすみません。。自分はmap()の中身を↑のように解釈しました。なので、今回のエラーは方向キーを押して、敵のフラグが立ったが、chをインクリメント(デクリメント)してしまい、それでbattle()へ。戻ってきたときには32で割れないので進んでしまう・・・

このように解釈していたのでこれでもいいかなと。。勝手な判断でしたので、yasyaさんの回答に直結しないかもしれないですね。。本当にすみませんでした。

Re:無題

Posted: 2008年8月21日(木) 07:43
by 管理人
条件マッチした時に、やはりch.walking_flagを0にしないと、戻ってきた時に動いてしまわないでしょうか?

Re:無題

Posted: 2008年8月21日(木) 08:15
by kazuoni
ちょっと調べてみましたが、やはりbattle()から戻ってくるとちゃんと何も押さない時のifにあてはまり、座標は変わらずにch.walking_flag=0でした。

そのときのコードです。

Re:無題

Posted: 2008年8月21日(木) 08:51
by 管理人
あぁ、なるほど、そういうことでしたか。
それだとうまくいくと思います。失礼しましたm(_ _)m

Re:無題

Posted: 2008年8月21日(木) 17:24
by yasya
kazuoniさん、管理人さん、ありがとうございます。
おかげで、無事解決することができました。
本当にありがとうございます^^