ページ 11

DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 13:30
by jyony
こんにちは。現在DxLibでマリオみたいな横スクロールのゲームを制作中です。

バイナリファイルを読み込んで、それでマップを作ろうかと思っています。

そこで、ファイル読み込み関数で、「FileRead_gets」を使って、ファイルを読み込みを行っているのですが、
この関数だと一行だけしか読み込めず、ループを使って読み込ませても、char変数が上書きされてしまいます。

一応、縦48行、横64行のバイナリを読み込もうと思っているのですが、複数の行を読み込ませる方法はありませんか?

自分なりに調べてもそれらしきものが見当たらず、困っております。

アドバイスの方、よろしくお願いします。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 13:47
by みけCAT
まず、読み込もうとしているファイルは本当にバイナリファイルですか?
バイナリファイルに対し「一行だけ」とか「縦48行、横64行」とか「複数の行」とかいう表現はあまり使いません。
とりあえず、読み込もうとしているファイルのサンプルをAxfc Uploaderなどにアップロードしてください。
オフトピック
テキストファイルも広義のバイナリファイルですが。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 14:40
by jyony
早速のご回答ありがとうございます。


一応、バイナリファイルをアップロードしました。

http://www1.axfc.net/uploader/File/so/81312
*こちらです。


キーワードは「バイナリ」です。

バイナリファイルの中で「0」がマップでいう「何もない」所で、「1」がブロックを表しています。


また何かご不明な点がありましたらご指摘願います。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 14:47
by nil
これはバイナリではなくただのテキストファイルです。
[追記]
文字コードの範囲などを考慮せずに作成されたファイル。
文字のみで構成されるテキストファイル以外はすべてこれに含まれる。
テキストファイルで使用できない制御コードなどを含むため、テキストエディタでまともに読むことはできない。
e-Worldsより抜粋一部省略
jyonyさんのアップなさったファイルはこの定義を満たしません。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 14:58
by jyony
そうでしたかw。


確かにバイナリ形式に変換してなかったのでテキストの状態でした。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 15:09
by nil
ではバイナリ形式に変換したものをアップしてください。
また、丸投げは禁止です。フォーラムルールにある通り、
jyonyさんの組んだコードを提示してください。

お聞きしますがお使いのバイナリエディタは何ですか?

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 15:13
by softya(ソフト屋)
テキストファイルなのでFileRead_getsで問題なく読み込まれるはずです。
なので、何が問題なのか最初の質問に戻るわけですが問題が再現するソースコードを掲載してもらうのが一番早道ですのでお願いします。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 15:20
by jyony
ソースコードのURLです。

http://www1.axfc.net/uploader/File/so/81313

キーワードは「ソースコード」です。


すみません、バイナリ形式は完成したらその後で変換しようと思っていたんでエディタも持っていません。
ゲーム制作に関しては素人なんでアホな点が多くてすみません。
一応、バイナリエディタを探して今から変換します。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 15:22
by softya(ソフト屋)
バイナリエディタでマップを管理する必要性をあまり感じませんがテキストではダメなのですか?
【補足】なんとなくと言う理由ならバイナリファイルの必要性を感じてからで良いと思います。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 15:26
by jyony
>>softya(ソフト屋) さん


テキストでも全然大丈夫ですw。

というよりも、先に完成することを目標にしているので、ただ問題は複数の行を変数に上書きされずに
格納するか、です。



・・・・・分かりずらい説明ですみません。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 15:31
by softya(ソフト屋)
マップの広さは固定で良いのでしょうか?
固定で良いのならcharの2次元配列にして、iで添字を切り替えてFileRead_getsしていくことで可能です。
ちなみにFileRead_getsで読み込むのは文字列になるのでナル文字の分も考慮して配列宣言して下さい。

【補足】
問題点を書いていませんでしたが、問題点は48回同じ場所に読み込んでいるので残るのは最後に読み込んだ行の情報です。

コード:

void load()
{
	file_h = FileRead_open("maps/map1.txt");

	for(int i=0;i<48;i++)
	{
		FileRead_gets(string, 3072, file_h);	←	毎回stringの先頭から読み込まれる。
	}
	FileRead_close(file_h);

	DrawString(10, 10, string, white);
}

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 15:45
by jyony
固定かどうかはまだ決まっていませんw。

それと、コードのほうですが、以下のようでしょうか?

コード:


void load()
{

	file_h = FileRead_open("maps/map1.txt");

	for(int i=0;i<48;i++)
	{
		for(int j=0;j<65;j++)
		{
			FileRead_gets(string[j][i], 64, file_h);
			
		}

	}

	FileRead_close(file_h);

	

}

実行しても「整数型からポインタ型への変換には reinterpret_cast、C スタイル キャストまたは関数スタイル キャストが必要です。」
みたいなのが出て出来ません。

アドバイスの方、よろしくお願いします。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 16:00
by softya(ソフト屋)
文字列と配列の関係を理解されていますでしょうか?
文字列は一次元の配列と考えて下さい。string[j]でアクセスされるのは文字列ではなく文字です。あとiとjの関係も間違っています。
それとstringの宣言がありませんがナル文字の分はちゃんと考慮しましたか?

マップサイズが固定されない場合は、マップサイズをテキストに含める必要性とmallocなどでメモリ確保の必要があると思います。
あるいは絶対に収まるサイズを宣言して置くかです。400(横)x100(縦)など。

【おまけ】
コードにはstringからmap配列への変換が見当たりませんので、それも問題です。
load()関数内で変換するならstringは予想横幅最大長+ナル文字の1次元配列で事足ります。
string読み込み → map変換
を繰り返すだけですからね。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 16:23
by jyony
すみません、FileRead_getsの第一引数の変数では配列とか扱えないのですか?



「整数型からポインタ型への変換には reinterpret_cast、C スタイル キャストまたは関数スタイル キャストが必要です。」
というエラーが出て配列が扱えません。

コード:

for(int i=0;i<48;i++)
	{
		FileRead_gets(string[i], 65, file_h);
		
			

	}

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 16:33
by softya(ソフト屋)
1次元配列は引数に出来ます。
FileRead_gets(a, 65, file_h);

2次元配列なら1つ添字が必要です。
FileRead_gets(b, 65, file_h);

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 16:46
by jyony
そうなんですか!?


ありがとうございます。それを元にコードを組んでみたのですが、こういうことでしょうか。

コード:


void load()
{

	file_h = FileRead_open("maps/map1.txt");

	for(int i=0;i<48;i++)
	{
		for(int j=0;j<64;j++)
		{
		
			FileRead_gets(string[i], 65, file_h);
	
			maps[j][i] = string[j][i];
		}
	}

	for(int i=0;i<48;i++)
	{
		for(int j=0;j<64;j++)
		{
			DrawString(10, 10, maps[j][i], white);

		}
	}

	FileRead_close(file_h);

	

}


ただ、これだと「DrawString」のところで「DrawString' : 3 番目の引数を 'int' から 'const TCHAR *' に変換できません。」というエラーが出てしまうのですが・・・。


因みに変数mapsはint型です。


アドバイスの方、よろしくお願いします。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 16:50
by softya(ソフト屋)
maps[j]はint型ですからDrawStringできません。文字列じゃないですから。
あとmaps[j] = string[j];で文字型からint型に代入してますが、文字の'0','1','2'と数値の,0,1,2は変換が必要です。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 17:05
by jyony
すみません、char型からint型への変換を探してるのですが、具体的には場合によってはそのままint型をchar型に代入しても勝手に
処理してくれる、というような説明があったのですが、この場合、特別な処理を施す必要はあるのでしょうか?


もしあるとすればどのような感じで処理をするのかご教授願います。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 17:15
by softya(ソフト屋)
>すみません、char型からint型への変換を探してるのですが、具体的には場合によってはそのままint型をchar型に代入しても勝手に
>処理してくれる、というような説明があったのですが、この場合、特別な処理を施す必要はあるのでしょうか?

数値データであればそのとおりです。
文字データも数値データの一種ですが文字コードにより値が変わります。
shift-jis文字コードの場合は数値データ48が文字データ'0'と同じです。
なので、あのまま代入すると48('0')か49('1')がint型に代入されます。
それは意図と違いますよね?

エラーチェックも兼ねるのなら、switch~case で書いたほうが素直です。

コード:

switch(string[j][i]){
case '0':
	maps[j][i] = 0;
	break;
以下続く。

default:
	エラー処理
	break;
}

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 17:22
by みけCAT
softya(ソフト屋) さんが書きました:エラーチェックも兼ねるのなら、switch~case で書いたほうが素直です。

コード:

switch(string[j][i]){
case '0':
	maps[j][i] = 0;
	break;
以下続く。

default:
	エラー処理
	break;
}
一般的なWindows環境ならこれでいいのではないでしょうか?

コード:

if(string[j][i]>='0' && string[j][i]<='9') {
    maps[j][i]=string[j][i]-'0';
} else {
    エラー処理
}
オフトピック
「素直」は「愚直」という意味かな?

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 17:29
by softya(ソフト屋)
みけCAT さんが書きました:
softya(ソフト屋) さんが書きました:エラーチェックも兼ねるのなら、switch~case で書いたほうが素直です。

コード:

switch(string[j][i]){
case '0':
	maps[j][i] = 0;
	break;
以下続く。

default:
	エラー処理
	break;
}
一般的なWindows環境ならこれでいいのではないでしょうか?

コード:

if(string[j][i]>='0' && string[j][i]<='9') {
    maps[j][i]=string[j][i]-'0';
} else {
    エラー処理
}
オフトピック
「素直」は「愚直」という意味かな?
一応0,1,5以外はエラーにしたいとかマップを0,1,Aとかした場合も考慮しました。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 17:58
by jyony
おお、その発想は無かったですw。


ありがとうございます!
おかげで少し進歩しました。


ただ、ブロックが表示したのはいいのですが、テキストの通りに表示しなくなってしまいました。

一応、load関数は以下の通りに記述しました。

コード:


void load()
{

	file_h = FileRead_open("maps/map1.txt");

	for(int i=0;i<48;i++)
	{
		for(int j=0;j<65;j++)
		{
		
			FileRead_gets(string[i], 64, file_h);
	
			switch(string[j][i])
			{
			case'0':
				maps[j][i] = 0;
				break ;

			case'1':
				maps[j][i] = 1;
				break ;

			case'2':
				maps[j][i] = 2;
				break ;

			default:
				//エラー処理
				break ;


			}

		}
	}

	

	FileRead_close(file_h);

	

}

このようにしました。

それで、描画の方のコードなんですが、

コード:


void paint()
{
	//背景を青で埋める
	DrawBox(0,0,640,480,blue,true);
	

	for(int i=0;i<48;i++)
	{
		for(int j=0;j<65;j++)
		{
			//load関数で読み込んだmapsの中に1があればブロックの描画
			if(maps[j][i] == 1)
			{

				DrawGraph(gro1_x[j],460,gro_1,true);

			}
			//2があれば別のブロックの描画
			if(maps[j][i] == 2)
			{
				DrawGraph(j*10,i*10,block_1,false);

			}
		}
	}

}

このようにして、表示したのは一番下に2個ブロックが表示しただけでした。

http://www1.axfc.net/uploader/File/so/81322
*問題の画像です。

キーワードは「ブロック」です


よろしくお願いします。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 18:10
by softya(ソフト屋)
プログラムの変数名のせいで混乱しているようです。
混乱しないように書くのもプログラミング・テクニックですので変数名に気を配って下さいね。

コード:

void load()
{
 
    file_h = FileRead_open("maps/map1.txt");
 
    for(int i=0;i<48;i++)
    {
        for(int j=0;j<65;j++)	←	読み込むのは48行だけです。なので、FileRead_getsの位置が変です。48x65回も読み込みません。
        {
        
            FileRead_gets(string[i], 64, file_h); ← 直mapsに変換するなら48行分を保存する必要はないですよ。一行分でOKです。
    
            switch(string[j][i])	iとjが逆です。ややこしいのでx,yにしてみましょう。つまりyはiでxはjです。その方が分りやすいはずです。
            {
            case'0':
                maps[j][i] = 0;		こっちのi,jは合っているみたいですね。混乱しないように気をつけて下さい。
                break ;
 
            case'1':
                maps[j][i] = 1;
                break ;
 
            case'2':
                maps[j][i] = 2;
                break ;
 
            default:
                //エラー処理
                break ;
 
 
            }
 
        }
    }
 
    
 
    FileRead_close(file_h);
 
    
 
}

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 18:30
by jyony
このような感じにコードを組んでみたのですが・・・


コード:



void load()
{

	file_h = FileRead_open("maps/map1.txt");

	for(int y=0;y<48;y++)
	{

		FileRead_gets(string[y], 64, file_h);

		for(int x=0;x<64;x++)
		{
	
			switch(string[y][x])
			{
			case'0':
				maps[x][y] = 0;
				break ;

			case'1':
				maps[x][y] = 1;
				break ;

			case'2':
				maps[x][y] = 2;
				break ;

			default:
				//エラー処理
				break ;


			}

			
		}
	}	

	FileRead_close(file_h);
}

やはり改善しないばかりです・・・どこか不適切な部分ありますでしょうか。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 18:41
by softya(ソフト屋)
FileRead_gets(string[y], 65, file_h);
では?

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 19:03
by jyony
長々と質問ばかりし続けてすみません。

画像が表示したのはいいのですが、何故か画像が2枚出てきてずれるんです。


それと、テキストファイルの中にある「0」と「1」との位置も変です。


http://www1.axfc.net/uploader/File/so/81324
キーワードは「位置」です。


アップロードした画像のような感じで、テキストファイルの「2」と画像のブロックの位置がおかしいです。


これはファイルの読み方がまずいのでしょうか?それとも画像のサイズの計算や座標計算がまずいのでしょうか??


よろしくお願いします。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 19:34
by softya(ソフト屋)
なんか前とx方向のサイズが変わっていませんか?
FileRead_gets(string[y], 64, file_h);
の横の読み込みサイズが必要以上にあることと
maps[x]のサイズのどれかがあっていないとバグになりますよ。
問題のあるソースコードとデータの両方をみせてください。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 21:56
by jyony
返信遅れてすみません。


ソースコードはこちらです。

コード:


void map_load()
{

	file_h = FileRead_open("maps/map1.txt");

	for(int y=0;y<48;y++)
	{

		FileRead_gets(string[y], 65, file_h);

		for(int x=0;x<64;x++)
		{
	
			switch(string[y][x])
			{
			case'0':
				maps[x][y] = 0;
				break ;

			case'1':
				maps[x][y] = 1;
				break ;

			case'2':
				maps[x][y] = 2;
				break ;

			default:
				//エラー処理
				break ;


			}

			
		}
	}	

	FileRead_close(file_h);

}

あの後、少し自分なりに弄ったので変なところがあるかもしれません。

画像描画関数です。

コード:


void paint()
{
	//背景を青で埋める
	DrawBox(0,0,640,480,blue,true);
	

	for(int i=0;i<48;i++)
	{
		for(int j=0;j<65;j++)
		{
			//load関数で読み込んだmapsの中に1があればブロックの描画
			if(maps[j][i] == 1)
			{

				DrawGraph(j*10,460,gro_1,true);

			}
			//2があれば別のブロックの描画
			if(maps[j][i] == 2)
			{
				DrawGraph(blk1_x[j],i*10,block_1,false);

			}
		}
	}

}

どこかバグの元があるのでしょうか・・・。

それと、mapsとstringの変数宣言の部分は、

コード:


int maps[65][48];

char string[48][65];

となっています。


あとすみません、データとはどのデータでしょうか?テキストファイルのことでしょうか?


よろしくお願いします。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 22:09
by softya(ソフト屋)
paint()で値が1と2の時で表示座標計算方法が違いますがズレの原因ではないですか?
DrawGraph(j*10,460,gro_1,true); ← 水平座標が固定です。
DrawGraph(blk1_x[j],i*10,block_1,false);の[j]番目の配列がちゃんとありますか?
それと65番目まで表示してますが64では無いでしょうか?

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 22:48
by jyony
画像のズレは直りました。

どうやら画像の座標配列のサイズが一致してなかったり、座標計算が間違ってたようですw。

ただ、テキストファイルの読み込みの仕方がおかしく、「0」や「1」の位置がおかしいです。
そこさえできれば、なんとかできるのですが・・・・。

コード:


void map_load()
{

	file_h = FileRead_open("maps/map1.txt");

	for(int y=0;y<48;y++)
	{

		FileRead_gets(string[y], 64, file_h);

		for(int x=0;x<64;x++)
		{
	
			switch(string[y][x])
			{
			case'0':
				maps[x][y] = 0;
				break ;

			case'1':
				maps[x][y] = 1;
				break ;

			case'2':
				maps[x][y] = 2;
				break ;

			default:
				//エラー処理
				break ;


			}

			
		}
	}	

}

やはりどこか間違えているのでしょうか・・・?


どうかよろしくお願いします。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 22:59
by softya(ソフト屋)
printfDXでmaps配列の格納値を確認してみて下さい。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 23:05
by jyony
確認してみました。

http://www1.axfc.net/uploader/File/so/81333

キーワードは「格納値」です。


やっぱり位置がずれてます・・・・。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 23:17
by softya(ソフト屋)
Load時のstring[y]もずれているのでしょうか?

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月15日(日) 23:44
by jyony
試しに画像の大きさを20×20から10×10に変更してみたところ、
多少ましになりました。



やはりサイズを考慮した上で座標計算する必要があるのでしょうか?

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月16日(月) 00:08
by softya(ソフト屋)
jyony さんが書きました:試しに画像の大きさを20×20から10×10に変更してみたところ、
多少ましになりました。

やはりサイズを考慮した上で座標計算する必要があるのでしょうか?
いえ、なにか根本的に間違っています。
表示の時もDrawGraph(j*10,i*10,gro_1,true);程度のシンプルなモノで良いはずです。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月16日(月) 01:17
by jyony
やっぱりファイルの読み方に間違いがありそうだと個人的に思うのですが・・・・。


横一列に読み込んだやつがちゃんとmapsに入っているか、あるいはへんな並び方になっていないか、とか。

mapsにはテキストファイルと同じ形で代入されるんですよね?

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月16日(月) 11:09
by softya(ソフト屋)
jyony さんが書きました:やっぱりファイルの読み方に間違いがありそうだと個人的に思うのですが・・・・。


横一列に読み込んだやつがちゃんとmapsに入っているか、あるいはへんな並び方になっていないか、とか。

mapsにはテキストファイルと同じ形で代入されるんですよね?
最新のマップデータを頂けませんか?
こちらで検証してみます。
プログラムは最後に掲載されたやつで良いですよね?

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月16日(月) 11:15
by jyony
すみません、うまくいきましたw。


やはりファイルの読み込みが甘かったようです。

コード:



void map_load()
{

	file_h = FileRead_open("maps/map1.txt");

	for(int y=0;y<48;y++)
	{

		FileRead_gets(string[y], 67, file_h);     //←第二引数を67にしたらうまくいった

		for(int x=0;x<64;x++)
		{
	
			switch(string[y][x])
			{
			case'0':
				maps[y][x] = 0;
				break ;

			case'1':
				maps[y][x] = 1;
				break ;

			case'2':
				maps[y][x] = 2;
				
				break ;

			default:
				//エラー処理
				//printfDx("%d",string[y][x]);
				break ;


			}

			
		}	
	}	

}

つまり、終端の文字のヌル文字も考慮すると、3文字分サイズを大きくしておかないといけなかったのでしょうか?


とにかくうまくいったので、ありがとうございました!!

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月16日(月) 11:24
by softya(ソフト屋)
そうなると、FileRead_gets()で改行コードを読み込んでるんでしょうね。
ナル文字をあわせて\r\n\0の3文字文です。
日頃FileRead_getsを使わないのでこちらも失礼しました。

バッファを余分なサイズ分を見込んで大きめにとっておくと良いと思います。100とか。
あとstringは1次元配列にできますので考えてみて下さい。

Re: DxLibで複数の行のファイル読み込み

Posted: 2012年7月16日(月) 12:08
by jyony
いえいえ、こちらこそ長々と質問ばかりですみませんでした。

また何かありましたらご質問させてもらいますね。

ありがとうございました!