レーザーにおけるバグ

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

レーザーにおけるバグ

#1

投稿記事 by niconico » 16年前

龍神録を使ってシューティングを作らせてもらってます
ザコ敵にもレーザーを実装してみたところ、バグが発生しました
放置しておけばそのうち治るかと思ったのですが、そうではなさそうで、さらに自分ではわからないので投稿させていただきます

自分の困っているバグはレーザーを出してくる敵を全部殺してしまった場合起こってしまいます。
よく表れる症状はレーザーが細いまま、回転するのが一瞬、などです

殺さなかったら、ちゃんと自分の思った通りのレーザーがでるのでプログラムは間違っていないと思うのですが……

あと、エクセルを使った敵の読み込みもただ敵を消しただけなのに、読み込みエラーが発生したりします

どうやったら解決できるか、よろしくお願いします

BEMANI

Re:レーザーにおけるバグ

#2

投稿記事 by BEMANI » 16年前

>>niconicoさん
>ザコ敵にもレーザーを実装してみたところ、バグが発生しました
ザコ敵に実装する前はしっかりレーザーを撃てていたのでしょうか?
前回レーザーで御質問なさった時に、敵が複数いる場合のレーザー発射の問題は
解決したように書かれていましたので気になりました。
あの記事とは別の問題でしょうか。


>よく表れる症状はレーザーが細いまま、回転するのが一瞬、などです
すいませんが、症状がよく解らないです。
文章で書くならもう少し具体的にお願いします;


>殺さなかったら、ちゃんと自分の思った通りのレーザーがでるのでプログラムは間違っていないと思うのですが……
仮に敵を全部倒さないとどうなるのでしょうか。
例えば画面に3匹出てきたとして、3匹がレーザーを撃つとします。
その内の1匹あるいは2匹を倒すとどうなるのでしょうか・・・という事です。

敵を倒した時の初期化を間違えているとか、レーザーを発射するタイミングで敵がいなくなっている
といったプログラムになっていませんか?


>あと、エクセルを使った敵の読み込みもただ敵を消しただけなのに、読み込みエラーが発生したりします
>どうやったら解決できるか、よろしくお願いします
ソースを見ないとなぜかは解りません。
差し支えなければソースを載せて頂けると解決策が見えるかもしれません。

niconico

Re:レーザーにおけるバグ

#3

投稿記事 by niconico » 16年前

BEMANIさん、またよろしくお願いします
ホント感謝です

>ザコ敵に実装する前はしっかりレーザーを撃てていたのでしょうか?
>前回レーザーで御質問なさった時に、敵が複数いる場合のレーザー発射の問題は
>解決したように書かれていましたので気になりました。
>あの記事とは別の問題でしょうか。
あのあと、複数の敵がレーザーを撃つことには成功したのですが、実際に普通の敵が出るステージに実装して友達にやらせてみたら、今回のバグを発見しました
うまく行く時はレーザーはちゃんと撃ってくるので、別の問題だと思われます


>すいませんが、症状がよく解らないです。
>文章で書くならもう少し具体的にお願いします;
なんといえば、いいんでしょうか……
数字での説明するならば、

細いままというのは、レーザーを10に設定しているはずなのに、1ぐらいの太さしかない
回転のほうは、100カウントかけて回転するところを1~10カウントで回転させてる

といったところです


>仮に敵を全部倒さないとどうなるのでしょうか。
>例えば画面に3匹出てきたとして、3匹がレーザーを撃つとします。
>その内の1匹あるいは2匹を倒すとどうなるのでしょうか・・・という事です。
細いレーザーは敵が引っこんでも(本来は画面から消えたら、収束して消えます)しばらく残り続けたのち、消えます
倒した場合でも、そうなってしまいます。
複数だした場合、レーザーが成功する敵としない敵ができます。
試してみたところ、あまり敵同士の関連性はないようです。
成功したやつはちゃんとした動作をしますが、しなかったやつはしません
あと、うまくいかないのはレーザーだけで、敵キャラの動きには問題はないです(一応

初期化に関しては問題ないと思うのですが……調べてみます

>ソースを見ないとなぜかは解りません。
>差し支えなければソースを載せて頂けると解決策が見えるかもしれません。
入りきらなそうなので次にいきます

niconico

Re:レーザーにおけるバグ

#4

投稿記事 by niconico » 16年前

//敵の出現情報をエクセルから読み込んで格納する関数
void load_story(){
	char *fname;
	int n,num,i,fp;
	int input[64];
	char inputc[64];
	
	switch(stage_number){
	case 1:
	fname="../dat/csv/storyH0.csv";
	break;

	case 2:
	fname="../dat/csv/storyH0.csv";
	break;

	case 3:
	fname="../dat/csv/storyH0.csv";
	break;
	
	case 4:
	fname="../dat/csv/11章/storyH0.csv";
	break;
	
	case 5:
	fname="../dat/csv/11章/storyH0.csv";
	break;

	case 6:
	fname="../dat/csv/11章/storyH0.csv";
	break;

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

	fp = FileRead_open(fname);//ファイル読み込み
	if(fp == NULL){
		printfDx("read error\n");
		return;
	}
	for(i=0;i<2;i++)//最初の2行読み飛ばす
		while(FileRead_getc(fp)!='\n');

	n=0 , num=0;
	while(1){
		for(i=0;i<64;i++){
			inputc=input=FileRead_getc(fp);//1文字取得する
			if(inputc=='/'){//スラッシュがあれば
				while(FileRead_getc(fp)!='\n');//改行までループ
				i=-1;//カウンタを最初に戻して
				continue;
			}
			if(input==',' || input=='\n'){//カンマか改行なら
				inputc='\0';//そこまでを文字列とし
				break;
			}
			if(input==EOF){//ファイルの終わりなら
				goto EXFILE;//終了
			}
		}
		switch(num){
			case 0:	enemy_order[n].cnt		=atoi(inputc);break;
			case 1:	enemy_order[n].pattern	=atoi(inputc);break;
			case 2:	enemy_order[n].knd		=atoi(inputc);break;
			case 3:	enemy_order[n].x		=atof(inputc);break;
			case 4:	enemy_order[n].y		=atof(inputc);break;
			case 5:	enemy_order[n].sp		=atof(inputc);break;
			case 6:	enemy_order[n].bltime	=atoi(inputc);break;
			case 7:	enemy_order[n].blknd	=atoi(inputc);break;
			case 8:	enemy_order[n].col		=atoi(inputc);break;
			case 9:	enemy_order[n].hp		=atoi(inputc);break;
			case 10:enemy_order[n].blknd2	=atoi(inputc);break;
			case 11:enemy_order[n].wait		=atoi(inputc);break;
			case 12:enemy_order[n].item_n[0]=atoi(inputc);break;
			case 13:enemy_order[n].item_n[1]=atoi(inputc);break;
			case 14:enemy_order[n].item_n[2]=atoi(inputc);break;
			case 15:enemy_order[n].item_n[3]=atoi(inputc);break;
			case 16:enemy_order[n].item_n[4]=atoi(inputc);break;
			case 17:enemy_order[n].item_n[5]=atoi(inputc);break;
			case 18:enemy_order[n].till		=atoi(inputc);break;
		}
		num++;
		if(num==19){
			num=0;
			n++;
		}
	}
EXFILE:
	FileRead_close(fp);
}


です
最初のcase文はステージごとに変えたかったので、無理やりです
拙い知識とグーグル先生を使って使ったので間違えている可能性が高いです

niconico

Re:レーザーにおけるバグ

#5

投稿記事 by niconico » 16年前

ちなみに読み込むファイルはこれです

ねこ

Re:レーザーにおけるバグ

#6

投稿記事 by ねこ » 16年前

前回の内容があるみたいなので見たのですが思ったより長く把握し切れなかったので軽く推測で。

<よく表れる症状は
という表現から常に起こるわけではないのだと思いますが

<細いままというのは、レーザーを10に設定しているはずなのに、1ぐらいの太さしかない
<回転のほうは、100カウントかけて回転するところを1~10カウントで回転させてる
との内容から、配列に別の敵情報やショット情報が入ったりしていませんか?
龍神録プロジェクトなら敵やショットを追加する際、存在フラグをチェックしていると思いますので
レーザーに使用する情報なのにどこか上書きされてるか等。
そのあたりにバグが潜んでるのかもしれません。

また、レーザーの変化に関連するのはカウント系だと思います。
ちょっと邪魔になりますが、レーザー配列の0~必要数分のカウントをリアルタイムに画面に表示し
「予期しない増え方・減り方・停止」をチェックするとバグを起こしている原因が見えてくるかもしれません。

BEMANI

Re:レーザーにおけるバグ

#7

投稿記事 by BEMANI » 16年前

>>niconicoさん
御質問の内容に「エクセルを使った敵の読み込みもただ敵を消しただけなのに、読み込みエラーが発生したりします」
と書いてありますが、敵を消しただけなのに読み込みエラーと言うのはどういうことなのでしょうか?
もう少し具体的に書いて頂けると助かります。



まず、読み込みエラーが出る原因を追求していきましょう。
自分が気になったのは三点。

【一つ目】
switch(stage_number){ ~ }とありますが、この「stage_number」はどこにありますか?
引数で送られてきてるようでもありませんし、load_story()内で宣言・定義している所ははありませんでした。
グローバル変数で取っているのでしょうか?

【二つ目】
例えば case 0の処理ですが、「fname="../dat/csv/storyH0.csv";」と書いてあり、
csvファイルを読み込んでいます。
・・・が、添付されているファイルを見ると .xls とエクセルデータになっています。
csvを読み込むのであればらcsvファイルを出力して下さい。


【三つ目】
case 4 の処理にあります「fname="../dat/csv/11章/storyH0.csv";」ですが、
ファイル名に半角英数字以外(ひらがなや漢字等)を自分が使ったこと無かったのでちょっと疑問に思いましたが
これで読み込めるなら大丈夫です。
もしこれでうまく読み込めていないのなら、半角英数字でファイル名を付けてみては如何でしょうか。


読み込みエラーと言う事はなにかしら原因でうまく読み込めていないという事なので
読み込むデータがきちんと変数に入っているか確認する必要があります。
デバッガを使えるならそれで構いませんし、それはまだ使えないというのであれば
DxLibで、printf的なものがあるかは知らないですが、もしあるならそれを使って画面に出力したりして
変数の中身をトレスしてみて下さい。
(stage_number や enemy_order[n].メンバ など。)


もし画面に出力した段階でうまく出力されているのならば他が間違っていますし、
うまく出力されていないなら読み込む処理が間違っていることになります。

niconico

Re:レーザーにおけるバグ

#8

投稿記事 by niconico » 16年前

>>ねこさん

よく表れるというよりは、条件を満たすと出てしまうといった感じですね
なんか敵がバグを出して来ててレーザーが打てないです……
まずは、敵のバグをなんとかしなくちゃいけませんね
それが解決したら、やってみます

ちなみに前の質問ではザコ敵にレーザーを個別の変数を持たせるというものでした

>>BEMANIさん
>御質問の内容に「エクセルを使った敵の読み込みもただ敵を消しただけなのに、読み込みエラーが発生したりします」
>と書いてありますが、敵を消しただけなのに読み込みエラーと言うのはどういうことなのでしょうか?
>もう少し具体的に書いて頂けると助かります。
ホントにそのまんまで、一番下の列を消したら、バグりました

>switch(stage_number){ ~ }とありますが、この「stage_number」はどこにありますか?
>引数で送られてきてるようでもありませんし、load_story()内で宣言・定義している所ははありませんでした。
>グローバル変数で取っているのでしょうか?
そのとおりです。
グローバル変数で宣言してます。
説明不足ですみません
何ステージ目か表す変数です


>例えば case 0の処理ですが、「fname="../dat/csv/storyH0.csv";」と書いてあり、
>csvファイルを読み込んでいます。
>・・・が、添付されているファイルを見ると .xls とエクセルデータになっています。
>csvを読み込むのであればらcsvファイルを出力して下さい。
こちらではcsvファイルになっているのですが……どういうことなのでしょうか?
一応、../dat/csv/storyH0.xlsにしてみたところ、読み込みエラーと表示されました
csvでよさそうな感じがします

>case 4 の処理にあります「fname="../dat/csv/11章/storyH0.csv";」ですが、
>ファイル名に半角英数字以外(ひらがなや漢字等)を自分が使ったこと無かったのでちょっと疑問に思いましたが
>これで読み込めるなら大丈夫です。
>もしこれでうまく読み込めていないのなら、半角英数字でファイル名を付けてみては如何でしょうか。
半角だけにしても同じことが起こってしまいました



すみません続きがあります

niconico

Re:レーザーにおけるバグ

#9

投稿記事 by niconico » 16年前

実は上で書いたload_story関数には続く関数があって
//敵情報を登録
void enemy_enter(){//敵の行動を登録・制御する関数
    int i,j,t;
	if(boss.flag!=0)return;
    for(t=0;t<ENEMY_ORDER_MAX;t++){
        if(enemy_order[t].cnt==stage_count){//現在の瞬間がオーダーの瞬間なら
            if((i=enemy_num_search())!=-1){
                enemy.flag    =1;//フラグ
                enemy.cnt    =0;//カウンタ
                enemy.pattern=enemy_order[t].pattern;//移動パターン
                enemy.muki    =1;//向き
                enemy.knd    =enemy_order[t].knd;//敵の種類
                enemy.x        =enemy_order[t].x;//座標
                enemy.y        =enemy_order[t].y;
                enemy.sp        =enemy_order[t].sp;//スピード
                enemy.bltime    =enemy_order[t].bltime;//弾の発射時間
                enemy.blknd    =enemy_order[t].blknd;//弾幕の種類
                enemy[i].blknd2    =enemy_order[t].blknd2;//弾の種類
                enemy[i].col    =enemy_order[t].col;//色
                enemy[i].wait    =enemy_order[t].wait;//色
                enemy[i].hp        =enemy_order[t].hp;//体力
                enemy[i].hp_max =enemy[i].hp;//体力最大値
				enemy[i].back_col=GetRand(4);
                enemy[i].vx     =0;//水平成分の速度
                enemy[i].vy     =0;//鉛直成分の速度
                enemy[i].ang    =0;//角度
                for(j=0;j<6;j++)
                    enemy[i].item_n[j]=enemy_order[t].item_n[j];//落とすアイテム
            }
        }
    }
}

//敵の行動制御
void enemy_act(){
    int i;
    for(i=0;i<ENEMY_MAX;i++){
        if(enemy[i].flag==1){//その敵のフラグがオンになってたら
            if(0<=enemy[i].pattern && enemy[i].pattern<ENEMY_PATTERN_MAX){
                enemy_pattern[enemy[i].pattern](i);
                enemy[i].x+=cos(enemy[i].ang)*enemy[i].sp;
                enemy[i].y+=sin(enemy[i].ang)*enemy[i].sp;
                enemy[i].x+=enemy[i].vx;
                enemy[i].y+=enemy[i].vy;
                enemy[i].cnt++;
                enemy[i].img=enemy[i].muki*3+(enemy[i].cnt%18)/6;
                //敵が画面外に外れたら消す
                if(enemy[i].x<-20 || FMX+20<enemy[i].x || enemy[i].y<-20 || FMY+20<enemy[i].y)
                    enemy[i].flag=0;
				if(enemy[i].bltime==enemy[i].cnt)
					enter_shot(i);
			}
            else
                printfDx("enemy[i].patternの%d値が不正です。",enemy[i].pattern);
        }
    }
}



があるのですが、(load_story→enemy_enter→enemy_actの順に読み込みます)、このenemy_actの最後の
printfDx("enemy[i].patternの%d値が不正です。",enemy[i].pattern);
を使ってわかったことなのですが、どうやらロードするのがうまくいっていないみたいです
たとえば、enemy[i].patternにenemy[i].waitの値が入ってしまっているらしいです
調べてみないとわかりませんが、たぶんすべての関数にほしい値が入ってないように思われます
しかも、ずっとenemy[i].patternにenemy[i].waitが入るべき変数が入っているのならわかるんですが、enemy[i].yが入ったりします
正直わけがわからないです……

pooka

Re:レーザーにおけるバグ

#10

投稿記事 by pooka » 16年前

load_story関数に
>case 18:enemy_order[n].till = atoi(inputc);break;
とありますが、添付されたcsvファイル(xlsとなってますが)にはそれに対応する部分の値がないようです。(アイテムまで)
なので次の行の値を読み込んでいき、だんだん対応関係がずれてしまっているようです。

niconico

Re:レーザーにおけるバグ

#11

投稿記事 by niconico » 16年前

>>pooka
おお!
できました!
ありがとうございます
まさか、自分の付け足した関数が原因だったとは……


ということでバグを起こしているときの画像です
二体いますが、右側にいる方が正しい動作をしています
ちなみに、同じものを同じ時間に撃ったものです

niconico

Re:レーザーにおけるバグ

#12

投稿記事 by niconico » 16年前

>>ねこさん
>龍神録プロジェクトなら敵やショットを追加する際、存在フラグをチェックしていると思いますので
>レーザーに使用する情報なのにどこか上書きされてるか等。
>そのあたりにバグが潜んでるのかもしれません。

ということはなさそうです。他のレーザーをすべて消してやってみましたが、それでもだめでした

閉鎖

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