配列全体の条件分岐

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

配列全体の条件分岐

#1

投稿記事 by kazz » 14年前

今、マウス操作のハエ叩きゲームもどきをDXライブラリを用いて作っています。
そこでゲーム中クリックしたときにその座標に敵がいなければスコアを-10するという処理をやりたいのですがうまく行きません。

コード:

#include "GV.h"
//行動パターン0
void pattern0(int i)
{
	if(syusyu[i].muki==1)
    {
		syusyu[i].x+=2.0;
	}else
	{
	    syusyu[i].x-=2.0;
    }
}

void pattern1(int i)
{
	if(syusyu[i].muki==1)
    {
		syusyu[i].x+=2.0;
	}else
	{
	    syusyu[i].x-=2.0;
    }
	syusyu[i].yv += 0.5;
	syusyu[i].y += syusyu[i].yv;
}
//しゅしゅのスコア処理
void syusyu_score(int i)
{
	if(syusyu[i].cnt <= 100)
	{
		score += 300;
	}else if(syusyu[i].cnt > 100 && syusyu[i].cnt <= 200 )
	{
		score += 200;
	}else if(syusyu[i].cnt >200)
	{
		score += 100;
	}
}
int miss_score()
{
	int i=0;
	for(i=0;i<SYUSYU_MAX;i++)
	{
		if(ms_x>syusyu[i].x-32 && ms_x <syusyu[i].x + 32 && ms_y > syusyu[i].y-14 && ms_y < syusyu[i].y+44)
		{
			return 1;
		}
	}
	return 0;
}




//flag==0のしゅしゅを探す関数
int syusyu_searcher()
{
	for(int i=0;i<SYUSYU_MAX;i++)
	{
		if(syusyu[i].flag==0)
		{
			return i;
		}
	}
	return -1;
}

void syusyu_enter()//しゅしゅに仕事を与える
{
	int i,t;
	for(t=0;t<SYUSYU_MAX;t++){
		if(syusyu[t].in_cnt == stage_count)
		{
			if((i=syusyu_searcher()) != -1)
			{
				i = syusyu_searcher();
                syusyu[i].muki =GetRand(1);
                syusyu[i].flag = 1;
				chikuwa[i].flag = 1;
				syusyu[i].life_flag = 1;
				syusyu[i].cnt = 0;
				chikuwa[i].cnt = 0;
				syusyu[i].yv = 0;
                if(syusyu[i].muki==1)
                {
                syusyu[i].x =0;
            }else
            {
                syusyu[i].x = FIELD_MAX_X;
            }
            syusyu[i].y      =GetRand(FIELD_MAX_Y-96);
			}
		}
	}
}


 
void syusyu_act(){
    int i;
    for(i=0;i<SYUSYU_MAX;i++){
        if(syusyu[i].flag ==1 )//そのしゅしゅミクのフラグがオンになっていたら
        {
			if(syusyu[i].life_flag == 1)
			{
			    pattern0(i);
				syusyu[i].img=(syusyu[i].cnt%12)/6;
			}else
			{
				pattern1(i);
				syusyu[i].img = 2;
			}
            syusyu[i].cnt++;
            
            //しゅしゅが画面外にでたら消す
            if(syusyu[i].x<-50 || FIELD_MAX_X+50<syusyu[i].x || syusyu[i].y<-50 || FIELD_MAX_Y+50<syusyu[i].y)
            {
                syusyu[i].flag = 2;				
            }
			//しゅしゅがクリックされたとき
			if(mflag == 1)
			{
				se_flag[0]= 1;
				if(ms_x>syusyu[i].x-32 && ms_x <syusyu[i].x + 32 && ms_y > syusyu[i].y-14 && ms_y < syusyu[i].y+44)
				{
					if(syusyu[i].life_flag != 0)
					{
						syusyu_score(i);
					    se_flag[1]= 1;
						
					}
					syusyu[i].life_flag = 0;
				}
				if(miss_score() == 0)
					score -= 10;
			}
        }
    }
}


//しゅしゅミク処理メイン
void syusyu_main()
{
    syusyu_enter();
    syusyu_act();
	int i=syusyu_searcher();
	
}

コード:

#define GLOBAL_INSTANCE
#include "GV.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
			 LPSTR lpCmdLine, int nCmdShow )
{
	

	ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);//ウィンドウモード変更、初期化、裏画面設定
	SetBackgroundColor(255, 255, 255 );//背景色を白に設定
	// キーが押されるまでループ(キー判定には『CheckHitKeyAll』を使用)
	while( ScreenFlip() == 0 && ProcessMessage()==0 && ClearDrawScreen() == 0 )
	{
		music_ini();
		switch(func_state){
		case 0:
			load();
			func_state =1;
			break;
		case 1:
			ini();
			syusyu_arrival_F();
			func_state = 2;
			break;
		case 2:
			GetMousePoint(&ms_x,&ms_y);
			mflag = mouse();
			if(stage_count == 1500)
			{
				stage_count = 1;
				img_buttonF[0] = 0;
				
				if(hiscore < score)
					hiscore = score;
				score = 0;
				for(int i=0 ; i<SYUSYU_MAX ; i++)
				{
				syusyu[i].flag = 0;
				}
			}
			if(img_buttonF[0] == 0 || img_buttonF[0] == 1)
			{
				menu_main();
			}else if(img_buttonF[0] == 2)
			{
				syusyu_main();
				chikuwa_main();
				stage_count++;
			}

			graph_main();
			
			break;
		default:
			printfDx(TEXT("不明なfunc_state\n"));
			break;
		}
		music_play();
	}

	DxLib_End() ;			// DXライブラリ使用の終了処理

	return 0 ;			// ソフトの終了
}

とりあえずいろいろ考えてこのようなコードで実行してみたところ減点はするのですが敵の数に応じて減点点数が変わっていってしまいます。一定にしたいのですがどうしたらいいですか?

開発環境
windows7 32bit
visual C++ Express 2010
DXライブラリ

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 配列全体の条件分岐

#2

投稿記事 by beatle » 14年前

スコアを-10する条件を、日本語で整理してみましょう。
  1. func_stateが2になる。
  2. img_buttonF[0]が2になる。
  3. syusyu.flag == 1となる全てのiに対して、mflag == 1かつmiss_score() == 0ならばスコアを-10する。

ここで3番目の処理は、syusyu_act関数のforループ中で行われています。

このループ中ではmflagは変更されません。
miss_score関数を見てみると、miss_score関数が依存するms_x, ms_yはループ中で変更されません。syusyu.xとsyusyu.yは、ぱっと見よくわかりませんが、恐らくループ中で変更されてないと思います。

要するに、syusyu_act関数のループ中、mflagの値とmiss_score関数の戻り値は、ずっと同じです。従いまして、syusyu.flag == 1となっている「しゅしゅ」の数だけ、スコアから10が引かれます。

これを防ぐには、syusyu_act関数のループのなかで、それぞれのしゅしゅに対してクリックされているかどうかを毎回計算すればいいでしょう。

・・・今回のバグは、グローバル変数に頼りきっている事が原因の一つだと思います。グローバル変数を上手く扱う自信がないなら、グローバル変数を使わない工夫をするのもいいでしょう。

kazz

Re: 配列全体の条件分岐

#3

投稿記事 by kazz » 14年前

お返事が遅くなってしまいました。すみません・・・
miss_score()関数を

コード:

#define GLOBAL_INSTANCE
#include "GV.h"
	int i ;
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
			 LPSTR lpCmdLine, int nCmdShow )
{
	

	ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);//ウィンドウモード変更、初期化、裏画面設定
	SetBackgroundColor(255, 255, 255 );//背景色を白に設定
	// キーが押されるまでループ(キー判定には『CheckHitKeyAll』を使用)
	while( ScreenFlip() == 0 && ProcessMessage()==0 && ClearDrawScreen() == 0 )
	{
		music_ini();
		switch(func_state){
		case 0:
			load();
			func_state =1;
			break;
		case 1:
			ini();
			syusyu_arrival_F();
			func_state = 2;
			break;
		case 2:
			GetMousePoint(&ms_x,&ms_y);
			mflag = mouse();
			if(stage_count == 1500)
			{
				stage_count = 1;
				img_buttonF[0] = 0;
				
				if(hiscore < score)    //ココ
					hiscore = score;
				score = 0;
				for(int i=0 ; i<SYUSYU_MAX ; i++)
				{
				syusyu[i].flag = 0;
				}
			}
			if(img_buttonF[0] == 0 || img_buttonF[0] == 1)
			{
				menu_main();
			}else if(img_buttonF[0] == 2)
			{
				if(miss_score() == 1)
					score -= 10;
				syusyu_main();
				chikuwa_main();
				stage_count++;
			}

			graph_main();
			
			break;
		default:
			printfDx(TEXT("不明なfunc_state\n"));
			break;
		}
		music_play();
	}

	DxLib_End() ;			// DXライブラリ使用の終了処理

	return 0 ;			// ソフトの終了
}
の位置に書き換えることで解決しました。syusyu_act()内でやってしまうと-10する処理が繰り返されるというのがbeatleさんのコメントでやっとわかりました。日本語にして整理する方法は頭の整理がつきやすいので今後積極的に使っていきたいです。またグローバル変数に頼り過ぎないように気をつけます。ありがとうございました!

閉鎖

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