二次元配列を渡す方法

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

二次元配列を渡す方法

#1

投稿記事 by のく » 13年前

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: 二次元配列を渡す方法

#2

投稿記事 by のく » 13年前

あああ~ごめんなさい、正しくはこれです。
関数に配列を渡したいです

コード:

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 )
{

box
記事: 2002
登録日時: 15年前

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

#3

投稿記事 by box » 13年前

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

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

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

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

#4

投稿記事 by beatle » 13年前

boxさんの仰ることはまさにその通りですね.
「うまくいかない」から質問しているわけなので,「うまくいかない」というのはほとんど何の情報もないわけです.
このことはフォーラムルールの回答者が困る質問例にも載っていますので,是非御覧ください.

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

コード:

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

コード:

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

のく

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

#5

投稿記事 by のく » 13年前

失礼しました・・・
色々工夫してもできなかったのでつい書いてしまいました。
具体的にどうしたいかというと
二次元配列をまるまるGraphDraw関数に与えたい訳です
beatle さんが書きました:

コード:

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

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

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

#6

投稿記事 by softya(ソフト屋) » 13年前

こういう可変長のマップなどは2次元配列にしない方が良いでしょう。
1次元配列で同時にマップのサイズも渡します。

【補足】
それとマップエディタの利用も視野に入れたほうが良いです。
「プログラミング/初心者向け/チュートリアル/段階的学習/補講:マップエディタ - game-develop.com wiki」
http://wiki.game-develop.com/index.php? ... 5%A3%A5%BF
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

のく

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

#7

投稿記事 by のく » 13年前

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次元配列にしない方が良いのですか?

補足読んでおきます。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

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

#8

投稿記事 by beatle » 13年前

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さんの仰るとおり)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

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

#9

投稿記事 by softya(ソフト屋) » 13年前

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

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

私の書いたRPG(ドラクエタイプ)講座があるので良かったら参考にしてください。マップエディタのPlatinumを使っています。
「マイ 日記 • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/blog.php?u=114&sd=a&c=2
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

のく

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

#10

投稿記事 by のく » 13年前

softya(ソフト屋) さんが書きました:>でも、なぜ可変長のマップなどは2次元配列にしない方が良いのですか?

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

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

閉鎖

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