ページ 11

二次元配列を渡す方法

Posted: 2012年9月19日(水) 14:29
by のく
C++で、ドラクエライクなゲームを作っています。
マップデータをマップ描写関数に渡そうと思うのですが、うまくいきません。

コード:

int MapData[ 16 ][ 20 ] =
{
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ,
	{ 0, 1, 1, 0, 0, 0, 0, 0, 0, 0 ,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 ,  1, 0, 0, 0, 0, 0, 0, 0, 1, 0 } ,
	{ 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 ,  1, 1, 1, 1, 1, 1, 0, 0, 1, 0 } ,
	{ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0 ,  0, 0, 0, 0, 0, 1, 0, 0, 1, 0 } ,
	{ 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 ,  0, 0, 1, 1, 1, 1, 1, 0, 1, 0 } ,
	{ 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 ,  0, 0, 1, 0, 0, 1, 1, 0, 1, 0 } ,
	{ 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 ,  0, 0, 1, 0, 0, 1, 1, 0, 1, 0 } ,

	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 ,  0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
	{ 0, 0, 0, 0, 1, 0, 0, 1, 0, 0 ,  0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
	{ 0, 0, 0, 0, 1, 0, 0, 1, 0, 0 ,  0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
	{ 0, 0, 0, 1, 1, 0, 0, 1, 0, 0 ,  0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 0, 0, 1, 1, 1 ,  1, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 1, 0 } ,
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ,
} ;

	GraphDraw(PlayerX,PlayerY,MapData);
}

void GraphDraw( int PlayerX, int PlayerY, int MapData )
{

マップの2次元配列をグローバル変数にしてしまえば楽なのは分かりますが
グローバル変数を使わない方法があるなら、その方法を使いたいです。
よろしくおねがいします。

Re: 二次元配列を渡す方法

Posted: 2012年9月19日(水) 14:33
by のく
あああ~ごめんなさい、正しくはこれです。
関数に配列を渡したいです

コード:

void Ch1(){
int PlayerX , PlayerY ;
int MapData[ 16 ][ 20 ] =
	{
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ,
		{ 0, 1, 1, 0, 0, 0, 0, 0, 0, 0 ,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
		{ 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 ,  1, 0, 0, 0, 0, 0, 0, 0, 1, 0 } ,
		{ 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 ,  1, 1, 1, 1, 1, 1, 0, 0, 1, 0 } ,
		{ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0 ,  0, 0, 0, 0, 0, 1, 0, 0, 1, 0 } ,
		{ 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 ,  0, 0, 1, 1, 1, 1, 1, 0, 1, 0 } ,
		{ 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 ,  0, 0, 1, 0, 0, 1, 1, 0, 1, 0 } ,
		{ 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 ,  0, 0, 1, 0, 0, 1, 1, 0, 1, 0 } ,

		{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 ,  0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
		{ 0, 0, 0, 0, 1, 0, 0, 1, 0, 0 ,  0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
		{ 0, 0, 0, 0, 1, 0, 0, 1, 0, 0 ,  0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
		{ 0, 0, 0, 1, 1, 0, 0, 1, 0, 0 ,  0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
		{ 0, 1, 1, 1, 1, 0, 0, 1, 1, 1 ,  1, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
		{ 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 1, 0 } ,
		{ 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 1, 0 } ,
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ,
	} ;
	GraphDraw(PlayerX,PlayerY,MapData);
}

void GraphDraw( int PlayerX, int PlayerY, int MapData )
{

Re: 二次元配列を渡す方法

Posted: 2012年9月19日(水) 14:44
by box
のく さんが書きました: マップデータをマップ描写関数に渡そうと思うのですが、うまくいきません。
とりあえず思うことは、「どんな風に」うまくいかないかを詳しく書いてほしいなぁ、ということです。
例えば、エラーメッセージを提示するなどして。

おそらく、ここを見ている多くのかたがたは「あ~なるほどね」と、原因や対策がおわかりであろうとは
思いますが、それにしたところで、まずは質問者さんご自身から起きていることの具体的な説明が
あるのが望ましいな、と思ったりするわけです。

Re: 二次元配列を渡す方法

Posted: 2012年9月19日(水) 14:48
by beatle
boxさんの仰ることはまさにその通りですね.
「うまくいかない」から質問しているわけなので,「うまくいかない」というのはほとんど何の情報もないわけです.
このことはフォーラムルールの回答者が困る質問例にも載っていますので,是非御覧ください.

さて,勝手に起こっている問題を推測して回答します.

コード:

void GraphDraw( int PlayerX, int PlayerY, int MapData )

コード:

void GraphDraw( int PlayerX, int PlayerY, int MapData[16][20] )
と変更したらいかがでしょう.

Re: 二次元配列を渡す方法

Posted: 2012年9月19日(水) 15:01
by のく
失礼しました・・・
色々工夫してもできなかったのでつい書いてしまいました。
具体的にどうしたいかというと
二次元配列をまるまるGraphDraw関数に与えたい訳です
beatle さんが書きました:

コード:

void GraphDraw( int PlayerX, int PlayerY, int MapData[16][20] )
と変更したらいかがでしょう.
例えばMapData[30][50]などになった場合に対応できるように書きたいです
先頭アドレスを渡す方法があったけれど、二次元配列のまま渡せるのが理想的なのですが…

Re: 二次元配列を渡す方法

Posted: 2012年9月19日(水) 15:12
by softya(ソフト屋)
こういう可変長のマップなどは2次元配列にしない方が良いでしょう。
1次元配列で同時にマップのサイズも渡します。

【補足】
それとマップエディタの利用も視野に入れたほうが良いです。
「プログラミング/初心者向け/チュートリアル/段階的学習/補講:マップエディタ - game-develop.com wiki」
http://wiki.game-develop.com/index.php? ... 5%A3%A5%BF

Re: 二次元配列を渡す方法

Posted: 2012年9月19日(水) 16:10
by のく
softya(ソフト屋) さんが書きました:こういう可変長のマップなどは2次元配列にしない方が良いでしょう。
1次元配列で同時にマップのサイズも渡します。

コード:


void Ch1(){
int PlayerX , PlayerY ;
int x = 16,y = 20;
int MapData[ x * y ] =
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0  ,
          0, 1, 1, 0, 0, 0, 0, 0, 0, 0 ,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0  ,
          0, 0, 1, 1, 1, 0, 0, 0, 0, 0 ,  1, 0, 0, 0, 0, 0, 0, 0, 1, 0  ,
          0, 0, 1, 0, 1, 0, 0, 0, 0, 0 ,  1, 1, 1, 1, 1, 1, 0, 0, 1, 0  ,
          0, 1, 1, 0, 1, 0, 0, 1, 1, 0 ,  0, 0, 0, 0, 0, 1, 0, 0, 1, 0  ,
          0, 1, 0, 0, 1, 0, 0, 1, 1, 0 ,  0, 0, 1, 1, 1, 1, 1, 0, 1, 0  ,
          0, 1, 0, 0, 1, 0, 0, 1, 1, 0 ,  0, 0, 1, 0, 0, 1, 1, 0, 1, 0  ,
          0, 1, 0, 0, 1, 0, 0, 1, 1, 0 ,  0, 0, 1, 0, 0, 1, 1, 0, 1, 0  ,
 
          0, 1, 1, 1, 1, 1, 1, 1, 1, 0 ,  0, 1, 1, 0, 0, 1, 1, 0, 1, 0  ,
          0, 0, 0, 0, 1, 0, 0, 1, 0, 0 ,  0, 1, 1, 0, 0, 1, 1, 0, 1, 0  ,
          0, 0, 0, 0, 1, 0, 0, 1, 0, 0 ,  0, 1, 1, 0, 0, 1, 1, 0, 1, 0  ,
          0, 0, 0, 1, 1, 0, 0, 1, 0, 0 ,  0, 1, 1, 0, 0, 1, 1, 0, 1, 0  ,
          0, 1, 1, 1, 1, 0, 0, 1, 1, 1 ,  1, 1, 1, 0, 0, 1, 1, 0, 1, 0  ,
          0, 1, 1, 1, 1, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 1, 0  ,
          0, 1, 1, 1, 1, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 1, 0  ,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0  ,
    } ;
    GraphDraw(PlayerX,PlayerY,MapData);
}
 
void GraphDraw( int PlayerX, int PlayerY,int x ,int y , int MapData[] )
{

こういうことですね?
確かにこの方がすっきりしていいかもしれませんね!この方法を使うことにします~

でも、なぜ可変長のマップなどは2次元配列にしない方が良いのですか?

補足読んでおきます。

Re: 二次元配列を渡す方法

Posted: 2012年9月19日(水) 16:20
by beatle
2次元配列を関数に渡すときには,どうしても1次元目のサイズを指定しなければならないのです.
実際に(x, y)の位置にある要素のアドレスを計算するのは
先頭アドレス + y * 横幅 + x
という式ですので,「横幅」の情報を引数に指定してやらなければならない.それが

コード:

void GraphDraw( int PlayerX, int PlayerY, int MapData[16][20] )
の20の部分なのです.縦幅を渡す必要はないので,正確には

コード:

void GraphDraw( int PlayerX, int PlayerY, int MapData[][20] )
で足ります.(しかし不便ですね)

2次元配列を関数に渡すのはすごく不便なので,softyaさんは1次元配列を提案しているわけです.
2次元のデータを1次元配列で渡すには,「横幅」を手動で渡します.(これもsoftyaさんの仰るとおり)

Re: 二次元配列を渡す方法

Posted: 2012年9月19日(水) 16:41
by softya(ソフト屋)
>でも、なぜ可変長のマップなどは2次元配列にしない方が良いのですか?

まぁ単に出来ないからです。
全部を最小公倍数サイズで統一する方法もありますが無駄ですし、今後のファイル読み込みを考えるならしないほうが良いでしょうね。

私の書いたRPG(ドラクエタイプ)講座があるので良かったら参考にしてください。マップエディタのPlatinumを使っています。
「マイ 日記 • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/blog.php?u=114&sd=a&c=2

Re: 二次元配列を渡す方法

Posted: 2012年9月19日(水) 18:25
by のく
softya(ソフト屋) さんが書きました:>でも、なぜ可変長のマップなどは2次元配列にしない方が良いのですか?

まぁ単に出来ないからです。
全部を最小公倍数サイズで統一する方法もありますが無駄ですし、今後のファイル読み込みを考えるならしないほうが良いでしょうね。
なるほど、一次元配列に慣れなければいけませんね…
「マイ 日記 • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/blog.php?u=114&sd=a&c=2
は、これから読んでみます。

みなさん本当にありがとうございました