一定のゲームカウンタ内でランダムに敵を表示する。

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

一定のゲームカウンタ内でランダムに敵を表示する。

#1

投稿記事 by kazz » 12年前

1、概要
DXライブラリでハエ叩きゲームのようなものを作っています。今はそのなかで、現在敵キャラクターが画面の左右からランダムなタイミングでy軸のランダムな場所から出現し反対側へ抜けていくというプログラムを書いています。しかし、下記のコードを実行したところ敵キャラが一体だけ画面端に現れ動かないという現象が起きました。自分ではsyusyu_searcher()関数で空いている敵キャラクターがないときの処理が不十分なためだと思いますが、解決方法がわかりません。
2、問題のプログラム

コード:

#include "GV.h"
//行動パターン0
void syusyu_pattern(int i)
{
	if(syusyu[i].muki==1)
	{
		syusyu[i].x+=2.0;
	}else
	{
		syusyu[i].x-=2.0;
	}
}
//flag==0のしゅしゅを探す関数
int syusyu_searcher()
{
	int i;
	for(i=0;i<SYUSYU_MAX;i++)
	{
		if(syusyu[i].flag == 0)
		{
			return i;
			break;
		}else
		{
			return -1;
		}
		
	}
}

void syusyu_enter()
{
	if(syusyu_searcher() != -1)
	{
		int i;
		i = syusyu_searcher();
		syusyu[i].muki =GetRand(1);
		syusyu[i].flag = 1;
		syusyu[i].in_cnt =GetRand(100);
		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 && syusyu[i].in_cnt == stage_count)//そのしゅしゅミクのフラグがオンになっていたら
		{
			syusyu_pattern(i);
			syusyu[i].cnt++;
			syusyu[i].img=(syusyu[i].cnt%12)/6;
			//しゅしゅが画面外にでたら消す
			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 = 0;
			}
		}
	}
}

//しゅしゅミク処理メイン
void syusyu_main()
{
	syusyu_searcher();
	syusyu_enter();
	syusyu_act();
}
3、今のCの知識
Cの基本的な文法は理解しています。またDXライブラリの知識は同サイトの【龍神録プログラミング】で一通り学習しています。

4、実行環境
PC: windows7 32bit版
コンパイラ: Visual C++ 2010 Express
使用ライブラリ: DXライブラリ

5、追記
問題と思う箇所があるのは上記した箇所だと思いますが、ほかのファイルが必要な場合は教えてください。

nil
記事: 428
登録日時: 12年前

Re: 一定のゲームカウンタ内でランダムに敵を表示する。

#2

投稿記事 by nil » 12年前

syusyu_searcherですが……

forでループ

syusyu.flagが0ならiを返す
そうでなければ-1を返す

という流れですね?

ですが、コレだと
syusyu[0]のflagが0だった場合ループせずに-1を返してしまいますよね?

問題はこの仕組です。

あとreturnのあとにbreakは不要だと思うのですが……

kazz

Re: 一定のゲームカウンタ内でランダムに敵を表示する。

#3

投稿記事 by kazz » 12年前

syusyu[0]のflagが0だった場合ループせずに-1を返してしまいますよね?
すみません。ループしない理由がちょっとわかりません。詳しく教えてくださいますか?
あとreturnのあとにbreakは不要だと思うのですが……
本当はflagが0のsyusyuが見つかり次第ループを抜けるという処理をしたかったのですが、確かにこれではうまくいきませんでしたorz
while文で書くべきだったでしょうか?

kazz

Re: 一定のゲームカウンタ内でランダムに敵を表示する。

#4

投稿記事 by kazz » 12年前

コード:

int syusyu_searcher()
{
	int i=0;
    do{
	
		if(syusyu[i].flag ==0)
	    {
			return i;
			break;
		}
        i++;
	}while(i == SYUSYU_MAX);
}
syusyu_searcher()関数をwhile文で書き直しました。
実行すると敵が両端で荒ぶる現象が起きました。
syusyu[0].flag
syusyu[0].in_cnt
syusyu[0].cnt
を監視したところ、flagはすぐに1になりin_cntは0~1000までのランダムな数でセットされました。
しかし、ゲームカウンタがin_cntの値になったときcntは1のまま動きませんでした。

nil
記事: 428
登録日時: 12年前

Re: 一定のゲームカウンタ内でランダムに敵を表示する。

#5

投稿記事 by nil » 12年前

まずですが、ループ中であれreturnを使えば関数を終了します。
関数を終了するということはループの中からもでるということです

コード:


int TestLoop(){
    for( int i=0; i<5; i++ ){
        printf( "%d\n", i );
        return 0;
    }
    return 1;
}

int main(){
    TestLoop();
    return 0;
}


kazz

Re: 一定のゲームカウンタ内でランダムに敵を表示する。

#6

投稿記事 by kazz » 12年前

ループ中であれreturnを使えば関数を終了します。
関数を終了するということはループの中からもでるということです
なるほど!そういうことでしたか。Cの基本的な文法をわかっているといっておきながら、お恥ずかしい・・・。

kazz

Re: 一定のゲームカウンタ内でランダムに敵を表示する。

#7

投稿記事 by kazz » 12年前

自己解決しました。
変更点
syusyu.cpp

コード:

#include "GV.h"
//行動パターン0
void pattern0(int i)
{
	if(syusyu[i].muki==1)
    {
		syusyu[i].x+=2.0;
	}else
	{
	    syusyu[i].x-=2.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;
				syusyu[i].cnt = 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 )//そのしゅしゅミクのフラグがオンになっていたら
        {
			pattern0(i);
            syusyu[i].cnt++;
            syusyu[i].img=(syusyu[i].cnt%12)/6;
            //しゅしゅが画面外にでたら消す
            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 = 0;				
            }
        }
    }
}
 
//しゅしゅミク処理メイン
void syusyu_main()
{
    syusyu_enter();
    syusyu_act();
	int i=syusyu_searcher();
	
}
load.cpp

コード:

#include "GV.h"

void syusyu_arrival_F()
{
	for(int i=0;i<SYUSYU_MAX;i++)
	{
        syusyu[i].in_cnt =GetRand(1000);   
	}
	int tmp;
	int j;
	for(int i = 1 ; i< SYUSYU_MAX; i++)
	{
		tmp= syusyu[i].in_cnt;
		if(syusyu[i-1].in_cnt >tmp)
		{
			j=i;
			do{
				syusyu[j].in_cnt = syusyu[j-1].in_cnt;
				j--;
			}while(j>0 && syusyu[j-1].in_cnt > tmp);
			syusyu[j].in_cnt=tmp;
		}
	}
			
}
void load(){
	LoadDivGraph( TEXT("syusyu0.png") , 3 , 3 , 1 , 64 , 96 , img_syusyu ) ;//しゅしゅミク読み込み
	LoadDivGraph(TEXT("chikuwa.png"),2,1,2,20,8,img_chikuwa);//ちくわ読み込み
}
1.出現タイミングの決定をあらかじめセットしておき挿入ソートで並び替えておきました。
2. 敵が出るタイミングでフラグを1にセットすることにしました。

なんとか思っていた通りの動きをさせることができましたがこのコードだと敵の数はコードであらかじめセットしてある数しかでないので、例えばエターナルモードなどを実装することができないという問題点がまだ残っています。しかし、エターナルモードは実装する気はないのでこれで解決とさせていただきます。涼雅さん、勉強になるお返事ありがとうございました!

閉鎖

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