敵にぶつかったら止めたい

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

敵にぶつかったら止めたい

#1

投稿記事 by yaegasi » 13年前

http://dixq.net/g/26.htmlこちらのサンプルを改造しただけのコードですが
敵にぶつかったら止めたいのですが
行き先がダブるとバグって止まります
どうすれば直るでしょうか

コード:


#include "DxLib.h"
 
typedef struct{
        int x,y,img,muki,walking_flag;
}ch_t;    ch_t ch;
 
typedef struct{
        int x,y,counter,img,muki,speed,walking_flag,flag;
}enemy_t;//敵の初期位置xyは32で割り切れる数でなければならない。でないと壁抜けしたり向きがおかしくなる
     enemy_t enemy[50] = {
		{ 320,160,7,2,1,2,1,1 },
		{ 288,128,7,2,1,2,1,1},
		{ 256,96,7,2,2,2,1,1},
		{ 400,400,7,2,2,2,1,1},
		{ 640,96,7,2,2,2,1,1},
		{ 672,96,7,2,0,2,1,1 },
		{ 43,3,4,2,3,2,1 ,0},
		{ 5,4,5,2,0,2,1,0},
		{ 4,4,7,2,2,2,1 ,0},
		{ 12,13,7,2,2,2,1 ,0},
		{ 3,2,8,2,2,2,1 ,0},
		{ 4,3,9,2,2,2,1 ,0},
		{ 32,32,10,2,2,2,1,0},
		{ 4,4,7,2,2,2,0 ,0},
		{ 12,13,7,2,2,2,0 ,0},
		{ 13,2,7,2,1,2,0 ,0},
		{ 14,3,7,2,2,2,0 ,0},
		{ 15,4,7,2,3,2,0,0},
		{ 5,4,7,2,2,3,0 ,0},
		{ 221,132,7,2,0,2,1 ,0},};


int hantei[15][34] = {
        { 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 },
        { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,0,1,0,0,0,0,0,0 },
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,0,0,1,0,0,0,0,0,0 },
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0 },
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,0,0,0,1,1,1,1,0,0,0 },
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0 },
        { 1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0 },
        { 1,1,1,1,1,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,1,0,0,0 },
        { 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,0,0,1,0,0,0 },
        { 1,1,1,1,1,0,0,0,1,1,1,0,0,0,1,0,0,0,1,1,0,0,0,0,1,0,0,0,0,0,1,1,1,1 },
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,0,1,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,1,1,0,0,0,0,1,0,0,0,0,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,0,0,0,0,1,1,1,1,1,1,0,0,0,0 },
        { 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 },
        { 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 }, 
};
 
int IsAbleToGo(int x,int y,int muki){//進めるかを判定する
        if(muki==0){//上向きなら
                if(hantei[y/32-1][x/32]==1)//進めるか判定。||より右は敵と自キャラのグリッド上の座標がダブったら
                        return 1;if(y/32==ch.y/32-1&&x/32==ch.x/32)return 2;}
        if(muki==1){//左向きなら
                if(hantei[y/32][x/32-1]==1)
                        return 1;if(y/32==ch.y/32&&x/32==ch.x/32-1)return 2;}
        if(muki==2){//下向きなら
                if(hantei[y/32+1][x/32]==1)
                        return 1;if(y/32==ch.y/32+1&&x/32==ch.x/32)return 2;}
        if(muki==3){//右向きなら
                if(hantei[y/32][x/32+1]==1)
                        return 1;if(y/32==ch.y/32&&x/32==ch.x/32+1)return 2;}
        return 0;//正常
}

int Chcolision(int x,int y,int muki){
        if(muki==0)//上向きなら
               if(y/32==ch.y/32-1&&x/32==ch.x/32)//進めるか判定。||より右は敵と自キャラのグリッド上の座標がダブったら
                        return 1;
        if(muki==1)//左向きなら
               if(y/32==ch.y/32&&x/32==ch.x/32-1)
                        return 1;
        if(muki==2)//下向きなら
                if(y/32==ch.y/32+1&&x/32==ch.x/32)
                        return 1;
        if(muki==3)//右向きなら
               if(y/32==ch.y/32&&x/32==ch.x/32+1)
                        return 1;
        return 0;//正常
}
int Enecolision(int x,int y,int muki){
        if(muki==0)//上向きなら
               if(y/32-1==ch.y/32&&x/32==ch.x/32)//進めるか判定。||より右は敵と自キャラのグリッド上の座標がダブったら
                        return 1;
        if(muki==1)//左向きなら
               if(y/32==ch.y/32&&x/32-1==ch.x/32)
                        return 1;
        if(muki==2)//下向きなら
                if(y/32+1==ch.y/32&&x/32==ch.x/32)
                        return 1;
        if(muki==3)//右向きなら
               if(y/32==ch.y/32&&x/32+1==ch.x/32)
                        return 1;
        return 0;//正常
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
        
    int image[16],i,j;
    char Key[256];

 
    if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //ウィンドウ化と初期化処理

    ch.x    =320;
    ch.y    =160;
    ch.walking_flag=0;
    ch.muki=3;
 int scrmapX=32,scrmapY=32;
    SetDrawScreen( DX_SCREEN_BACK ) ;                                                 //描画先を裏画面に設定
    LoadDivGraph( "char.png" , 16 , 4 , 4 , 32 , 32 , image ) ;//画像を分割してimage配列に保存

    while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
            //↑メッセージ処理        ↑画面をクリア         ↑キーボード入力状態取得       ↑ESCが押されると終了
 
                /*白い壁を描画*/
                for(i=0;i<15;i++)
                        for(j=0;j<34;j++)
                                if(hantei[i][j]==1)
                                        DrawBox(j*32+scrmapX,i*32+scrmapY,(j-1)*32+scrmapX,(i-1)*32+scrmapY,GetColor(255,255,255),TRUE);
 
                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;                  //歩かないフラグを立てる。
        }

		for(int i = 0 ; i < 50 ; i ++ )
		{ if(Chcolision(enemy[i].x,enemy[i].y,ch.muki)==1)//行き先が歩けないなら(このマップは0が壁で1が通路であるから注意)
     ch.walking_flag=0;
		}
 
        if(ch.walking_flag==1){        //歩くフラグが立っていたら
            if     (ch.muki==0){       //上向きならch.y座標を減らす
                    ch.y--;scrmapY++;}
            else if(ch.muki==1){        //左向きならch.x座標を減らす
                    ch.x--;scrmapX++;}
            else if(ch.muki==2){       //下向きならch.y座標を増やす
                    ch.y++;scrmapY--;}
            else if(ch.muki==3){         //右向きならch.x座標を増やす
                    ch.x++;scrmapX--;}
        }
 
		for(int i = 0 ; i < 50 ; i ++ )
		{//if(enemy[i].flag==1){と書いてはいけない。画面外に出ても存在してるから。画面出たら描画部分だけコレ書いて消して座標の計算部分だけは計算しとくほうがいい
                //共にx、y座標が32の余りが0なら一旦止まって一個先いけるか調べる
             if(enemy[i].x%32==0 && enemy[i].y%32==0 ){   if(IsAbleToGo(enemy[i].x,enemy[i].y,enemy[i].muki)==1){//行き先が歩けないなら(このマップは0が壁で1が通路であるから注意)
        for(int j=0;j<=3;j++){//も一回いける方向探す
			if(IsAbleToGo(enemy[i].x,enemy[i].y,j)==0){enemy[i].muki=j;break;}
		}}}}

		for(int i = 0 ; i < 50 ; i ++ )
		{ if(Enecolision(enemy[i].x,enemy[i].y,enemy[i].muki)==1){//行き先が歩けないなら(このマップは0が壁で1が通路であるから注意)
    enemy[i].walking_flag=0;}else enemy[i].walking_flag=1;
		}
	
		
		for(int i = 0 ; i < 50 ; i ++ )
		{		
	   	if( enemy[i].walking_flag==1) {
	if(enemy[i].muki==0) { 
                  enemy[i].y--;}
	        else if(enemy[i].muki==1)        //左向きならch.x座標を減らす
                    enemy[i].x--;
            else if(enemy[i].muki==2)        //下向きならch.y座標を増やす
                    enemy[i].y++;
            else if(enemy[i].muki==3)        //右向きならch.x座標を増やす
                    enemy[i].x++;
}}
        ch.img=image[(ch.x%32+ch.y%32)/8 + ch.muki*4];            //画像をセット
 		
		for( i = 0 ; i < 50 ; i ++ )
		{
        enemy[i].img=image[(enemy[i].x%32+enemy[i].y%32)/8 + enemy[i].muki*4];            //画像をセット
 	}
   
        DrawGraph( 320 , 160 , ch.img , TRUE ) ;//画像を描画
 		for( i = 0 ; i < 50 ; i ++ ){  //なぜか一個ずれてたんで-32   
			DrawGraph( enemy[i].x-32 + scrmapX, enemy[i].y-32 + scrmapY   , enemy[i].img , TRUE ) ;
}  
		DrawFormatString( 0, 80, GetColor(0,0,255), "ch.x%d",ch.x);
		DrawFormatString( 0, 100, GetColor(0,0,255), "ch.y%d",ch.y); 
		DrawFormatString( 0, 120, GetColor(0,0,255), "enemy.x%d",enemy[0].x/32);
		DrawFormatString( 0, 140, GetColor(0,0,255), "enemy.y%d",enemy[0].y/32); 
        ScreenFlip();
    }
 
    DxLib_End();
    return 0;
}


 

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 敵にぶつかったら止めたい

#2

投稿記事 by softya(ソフト屋) » 13年前

前の質問で、
「移動スピードを上げたい • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3&t=12487
とおなじ方ですよね?

フォーラムルールで名前の統一と解決内容の説明をお願いしております。
http://dixq.net/board/board.html
まず、過去の質問から片づけましょう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

yaegasi

Re: 敵にぶつかったら止めたい

#3

投稿記事 by yaegasi » 13年前

すいません
for(int i = 0 ; i < 50 ; i ++ )
{ if(Chcolision(enemy.x,enemy.y,ch.muki)==1)//行き先が歩けないなら(このマップは0が壁で1が通路であるから注意)
if(ch.x%32==0 && ch.y%32==0)ch.walking_flag=0;
}

としたら解決しました

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 敵にぶつかったら止めたい

#4

投稿記事 by softya(ソフト屋) » 13年前

yaegasi さんが書きました:すいません
for(int i = 0 ; i < 50 ; i ++ )
{ if(Chcolision(enemy.x,enemy.y,ch.muki)==1)//行き先が歩けないなら(このマップは0が壁で1が通路であるから注意)
if(ch.x%32==0 && ch.y%32==0)ch.walking_flag=0;
}

としたら解決しました


このソースコード場合、インデントが乱れているのでバグの原因となりやすく、他の人が内容を理解するのが困難です。
そこを改められたほうが良いと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

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