龍神録プログラミングの11章について

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

龍神録プログラミングの11章について

#1

投稿記事 by エレン・ジェタイド » 14年前

初めまして、エレン・ジェタイドという者です。
龍神録のプログラミングを参考にしながら、シューティングゲームを作っています。
私は入門サイトなど駆使しながらやっていますので、入門編は多分理解していると思います。

質問ですが、現在龍神録の第11章で詰まっています。
ソースコードを元にプログラムを打ち実行しますと、敵が一瞬だけ出現して消えるという現象が起きています。
ソースコード、誤字とかもチェックしましたが原因がまったく発見できませんでした。
だれか心お優しい方、教えて頂けないでしょうか。
拙い文章で申し訳ありませんが、よろしくお願いします。

使っているOS: windows 7
コンパイルソフト:Visual C++ 2008です

以下がソースになります

コード:

void enemy_pattern_0(int i){
	int t=enemy[i].cnt;
	if(t==0){
		enemy[i].fy=2;
	}
	if(t==60){
		enemy[i].fy=0;
    }
	if(t==60+enemy[i].wait){
		enemy[i].fy=-2;
    }
}

//------------------------------
//関数名:enemy_null_search()
//機能 :空き番号の検索
//------------------------------

//フラグの立っていないenemyを探す
int enemy_null_search(){
	int i;
	for(i=0; i<ENEMY_MAX; i++){
		if(enemy[i].flag==0){
			//使用可能な配列番号を格納する
			return i;
		}
	}
	//埋まっていたら-1(失敗)と返す
	return -1;
}

//敵データの登録
void enemy_enter(){
	int i;
	int j;
	int k;
	for(k=0; k<ENEMY_ODER_MAX; k++){
		if(enemy_oder[k].oder_cnt==stage_cnt){ //ゲームが始まって100カウント
			if((i=enemy_null_search())!=-1){
			enemy[i].flag     =1;   //フラグ
			enemy[i].cnt      =0;	//カウンタ
			enemy[i].pattern  =enemy_oder[k].oder_pattern; //行動パターン
			enemy[i].muki     =1;   //向き
			enemy[i].kind     =enemy_oder[k].oder_kind;    //出現する敵の種類
			enemy[i].x        =enemy_oder[k].oder_x;
			enemy[i].y        =enemy_oder[k].oder_y;
			enemy[i].sp       =enemy_oder[k].oder_speed;     //スピード
			enemy[i].sttime   =enemy_oder[k].oder_start_time;//弾幕開始時間
			enemy[i].dankind  =enemy_oder[k].oder_danmag_kind; //弾幕の種類
			enemy[i].dankind2 =enemy_oder[k].oder_danmag_kind2; //弾の種類
			enemy[i].color    =enemy_oder[k].oder_enemy_color; //色
			enemy[i].wait     =enemy_oder[k].oder_wait;  //停滞時間
			enemy[i].hp       =enemy_oder[k].oder_enemy_hp;   //HP
			enemy[i].hpmax    =enemy[i].hp;  //体力の初期値
			enemy[i].fx       =0; //水平方向
			enemy[i].fy       =0; //鉛直方向
			enemy[i].angle    =0; //角度
			for(j=0; j>6; j++){
				enemy[i].drop_n[j]=enemy_oder[k].oder_item[j];
			}
			}
		}
	}
}
	
/*敵の行動制御(移動パターンなどの基盤となるプログラム) 関数名:enemy_control (戻り値、返り値なし) */

void enemy_control(){
	int i;  //ローカル変数 i を定義。iはenemy_pattern関数などにも使用される共用変数
	for(i=0; i<ENEMY_MAX; i++){
		if(enemy[i].flag==1){
			enemy_pattern_0(i);  //enemy_pattern_0関数にiの内容を渡す
			enemy[i].x+= cos(enemy[i].angle)*enemy[i].sp;
			enemy[i].y+= sin(enemy[i].angle)*enemy[i].sp;
			enemy[i].x+= enemy[i].fx;
			enemy[i].y+= enemy[i].fy;
			enemy[i].cnt++;
			enemy[i].img=enemy[i].muki*3+(enemy[i].cnt%16)/6;  //enemy[3][i](iは分割画像のNo)を指定する) 値は3~5 (中央画像の指定している)

			//フラグを0にする
			if(enemy[i].x < -20 || enemy[i].y <-20|| FIELD_MAX_X+20 < enemy[i].x || FIELD_MAX_Y+20 < enemy[i].y )
				enemy[i].flag=0;
			}
		}
	}

	//敵処理メイン
	void enemy_main(){
		enemy_enter();
		enemy_control();
	}

コード:

//----------------------------------------------------
//変数名:load_enemy_oder()
//機能 :敵の出現情報をエクセルから読み込んで格納する
//----------------------------------------------------

void load_enemy_oder(){
	//変数の定義
	int n,num,i,fp;
    //ファイルネームのロード
	char fname[32] = {"../dat/csv/11章/storyH0.csv"};
	//全角用・半角用の配列
	int  input  [64]; //全角
	char inputc [64]; //半角

	//ファイル読み込み
	fp = FileRead_open(fname);
	//ファイル名の途中で空白文字を感知したらエラーを返す
	if(fp == NULL){
		printfDx("Read Error\n");
		return;
	}

	//textファイルで展開する際に、最初の2行はデータではないので読み飛ばす
	for(i=0; i<2; i++)
		while(FileRead_getc(fp)!='\n');

		n=0,num=0;
		while(1){
			for(i=0; i<64; i++){
				//1文字を取得する
				inputc[i]=input[i]=FileRead_getc(fp);
				//スラッシュがあれば改行までループ
				if(inputc[i]=='/'){
					while(FileRead_getc(fp)!='\n');
					i=-1;
					continue;
				}

				//\nがあればそこまでを文字列として出力
				if(input[i] == '.' || input[i] == '\n'){
					inputc[i]='\0';
					break;
				}

				//ファイルがEOFなら終了
				if(input[i]==EOF){
					goto EXFILE;
				}
			}
			//エクセル読み込み(格納データは18個)
			switch(num){
				case 0 :enemy_oder[n].oder_cnt         = atoi(inputc); break;
				case 1 :enemy_oder[n].oder_pattern     = atoi(inputc); break;
				case 2 :enemy_oder[n].oder_kind        = atoi(inputc); break;
				case 3 :enemy_oder[n].oder_x           = atof(inputc); break;
				case 4 :enemy_oder[n].oder_y           = atof(inputc); break;
				case 5 :enemy_oder[n].oder_speed       = atof(inputc); break;
				case 6 :enemy_oder[n].oder_start_time  = atoi(inputc); break;
                case 7 :enemy_oder[n].oder_danmag_kind = atoi(inputc); break;
				case 8 :enemy_oder[n].oder_enemy_color = atoi(inputc); break;
				case 9 :enemy_oder[n].oder_enemy_hp    = atoi(inputc); break;
				case 10:enemy_oder[n].oder_danmag_kind2= atoi(inputc); break;
				case 11:enemy_oder[n].oder_wait        = atoi(inputc); break;
				case 12:enemy_oder[n].oder_item[0]     = atoi(inputc); break;
				case 13:enemy_oder[n].oder_item[1]     = atoi(inputc); break;
				case 14:enemy_oder[n].oder_item[2]     = atoi(inputc); break;
				case 15:enemy_oder[n].oder_item[3]     = atoi(inputc); break;
				case 16:enemy_oder[n].oder_item[4]     = atoi(inputc); break;
				case 17:enemy_oder[n].oder_item[5]     = atoi(inputc); break;
			}
			num++;
			if(num==18){
				num=0;
				n++;
			}
		}
EXFILE:
		FileRead_close(fp);
}

アバター
kimuchi
記事: 163
登録日時: 14年前
住所: 東京

Re: 龍神録プログラミングの11章について

#2

投稿記事 by kimuchi » 14年前

enemy.fx,enemy.fyではなく
enemy.vx,enemy.vyだったと思います。

それとも構造体はご自分で変更されたのでしょうか?

エレン・ジェタイド

Re: 龍神録プログラミングの11章について

#3

投稿記事 by エレン・ジェタイド » 14年前

返信ありがとうございます
kimuchiの仰る通り、構造体はソースを元に一部名前を変更したものを使っています

ソースはこれです

コード:

//enemyの構造体(enemy1体に含まれる)
typedef struct{
	int flag;       //フラグ
	int cnt;		//カウント
	int pattern;	//行動パターン
	int muki;		//敵の方向
	int kind;		//敵の種類
	int hp;			//敵HP
	int hpmax;		//敵の最大HP
	int drop_n[6];	//ドロップアイテム[個数]
	int img;		//画像
	int sttime;		//弾幕開始タイム
	int dankind;    //弾幕の種類
	int dankind2;	//弾の種類
	int color;      //色
	int waitstate;  //待機状態
	int wait;       //待機時間
	double x,y;     //enemyの座標(浮動小数点型) ※こちらのほうが処理速度が速いから(floatだと変換設定が必要となってしまう)
	double fx,fy;   //enemyに関わる速度成分(水平方向・鉛直方向)
	double sp;      //スピード()
	double angle;   //角度()
}enemy_t;           //敵の構造体名再定

コード:

//--------------------------
//構造体名:oder_t
//機能  :敵の出現情報
//--------------------------

typedef struct{
 //-----------------基本情報
	//カウンタ
	int oder_cnt;

	//出現パターン
	int oder_pattern;

	//出現する敵の種類
	int oder_kind;

 //-----------------enemyの座標と移動速度
	//enemyの座標
	double oder_x;
	double oder_y;

	//enemyの移動速度
	double oder_speed;

 //----------------enemyの弾幕変数など
	//弾幕発射開始時間
	int oder_start_time;

	//弾幕の種類
	int oder_danmag_kind;

	//敵の色
	int oder_enemy_color;

	//enemyの体力
	int oder_enemy_hp;

	//弾の種類
	int oder_danmag_kind2;

	//enemyの停滞時間
	int oder_wait;

	//アイテムの種類(6種類)
	int oder_item[6];

}oder_t;

アバター
kimuchi
記事: 163
登録日時: 14年前
住所: 東京

Re: 龍神録プログラミングの11章について

#4

投稿記事 by kimuchi » 14年前

一瞬画像が表示される具体的な位置などは分かりますか?
また、storyH0.csvの方はどのようなものになっていますか?
よろしければ合わせて御掲示お願い致します。

アバター
Dixq (管理人)
管理人
記事: 1662
登録日時: 14年前
住所: 北海道札幌市
連絡を取る:

Re: 龍神録プログラミングの11章について

#5

投稿記事 by Dixq (管理人) » 14年前

消える時はどういう状態なのか、ブレイクポイントを置いてみていってはいかがでしょう?
消えるという事は、どこかで、enemy[*].flag=0をしているのだと思います。
もしくは、まだ使用中の敵配列要素を使ってしまったとか。
そういうところが無いか見ていってはどうでしょう。

エレン・ジェタイド

Re: 龍神録プログラミングの11章について

#6

投稿記事 by エレン・ジェタイド » 14年前

返信遅くなってしまい、申し訳ありませんでした。
消えた位置を調査した所、右から2、3番目位の位置に一瞬だけパッと表示されて消えるといった現象が起きています。
エクセルのデータを最後まで読みきれてない感じがします。
管理人さんの仰る通り、どこかでenemy[*].flag=0となってしまってるのではないかと思います。

アバター
kimuchi
記事: 163
登録日時: 14年前
住所: 東京

Re: 龍神録プログラミングの11章について

#7

投稿記事 by kimuchi » 14年前

右から2、3番目と言われましても今一つ分かりません(^^;)
せめてエクセルのデータを見せていただけませんか?

Dixqさんの仰るようにブレークポイントが使えればenemy[*].flag=0の処理部分などで処理を停止させて情報を得ることができ、問題の解決に最も有効だと思います。

エレン・ジェタイド

Re: 龍神録プログラミングの11章について

#8

投稿記事 by エレン・ジェタイド » 14年前

エクセルのデータは、11章のエクセルそのまま使っています。
画像

そしてこれが説明しました右から~の時の画像です。
よく見たら左からの方が正しいかもしれません(^_^;)
画像

アバター
kimuchi
記事: 163
登録日時: 14年前
住所: 東京

Re: 龍神録プログラミングの11章について

#9

投稿記事 by kimuchi » 14年前

エクセルデータは元のままなのですね。
load_enemy_oder関数で

コード:

                if(input[i] == '.' || input[i] == '\n'){
                    inputc[i]='\0';
                    break;
                }
の部分があると思います。
input == '.' (ピリオド)
ではなく
input == ',' (カンマ)
ではないでしょうか?

エレン・ジェタイド

Re: 龍神録プログラミングの11章について

#10

投稿記事 by エレン・ジェタイド » 14年前

kimuchiさん、返信ありがとうございます。
 <input == '.' (ピリオド)
  ではなく
  input == ',' (カンマ)
  ではないでしょうか?

今一度、自分のソースと龍神録のソースを照らし合わせてみたところ確かにピリオドではなく、カンマですね。
修正した上で再度デバック無しで実行してみたら、無事龍神録の実行結果と同じ結果を得ることができました。
細かいとここそしっかり見ないといけないのですね、それがよく分かりました。

kimuchiさん、Dixgさん、昨日の遅くから今日にかけて助言して頂きありがとうございました。
また困ったことがあれば、よろしくお願いしたいと思います。

Suikaba
記事: 194
登録日時: 14年前

Re: 龍神録プログラミングの11章について

#11

投稿記事 by Suikaba » 14年前

解決したのでしたら、解決にしておくといいと思いますよ。

エレン・ジェタイド

Re: 龍神録プログラミングの11章について

#12

投稿記事 by エレン・ジェタイド » 14年前

suikadaさん、助言ありがとうございました。
すっかり忘れていました、これからは気をつけていきます。

閉鎖

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