二次元配列でつくったMAPをスクロールさせたい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
EKISUKE
記事: 108
登録日時: 12年前

二次元配列でつくったMAPをスクロールさせたい

#1

投稿記事 by EKISUKE » 11年前

2次元配列でつくったMAPをプレイヤーの動きに連動させてスクロールさせたいです。
Visual stadio 2010
Openframeworksを使用して作っています。

MAPのコードです。

Map.h

コード:

#pragma once 

const int BLOCK_SIZE = 32;					//!< ブロック一つ分の大きさ
const int MAP_WIDTH	 = 3072 / BLOCK_SIZE;	//!< マップの横幅(ブロックで割った)	: 32
const int MAP_HEIGHT = 768  / BLOCK_SIZE;	//!< マップの縦幅(ブロックで割った)	: 24

//--------------------------------------------------------------
//!	@class マップクラス
//--------------------------------------------------------------
//@{
class Map{
public:
	static int MapData[MAP_HEIGHT][MAP_WIDTH];		//!< マップデータ
	ofImage image;									//!< 画像用
	Vector2 pos;									//!< 座標
	float	old_x;									//!< 今の座標保存
	int		right_x;								//!< 今の右端保存
	Map();											//!< コンストラクタ
	~Map();											//!< デストラクタ
	void MapMove();									//!< スクロール関数
	void setup();									//!< 初期化処理
	void update();									//!< 更新処理
	void draw();									//!< 描画処理
	
};
//@}
Map.cpp

コード:

#include "../../HeaderMain/HeaderMain.h"
//--------------------------------------------------------------
//	マップ概要
//	0: 通れるところ
//	1: 地面
//	2: ギミック
//--------------------------------------------------------------
// Bouei  bouei;      // 防衛クラス宣言
int Map::MapData[MAP_HEIGHT][MAP_WIDTH] = 
{	//	1画面目															2画面目															3画面目
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
	{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
	{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
	{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
	{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
	{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
};

//! @name コンストラクタ
Map::Map()
{
	image.loadImage("ground1.png");
	pos._x	= 0;
	pos._y	= 0;
	old_x	= 0;           // 今の座標を記録する
	right_x = 0;       // 右端の座標を記録
}
//! @name デストラクタ
Map::~Map()
{
}
//! @name 初期化
void Map::setup(){
	image.loadImage("ground1.png");
	pos._x = 0;
	pos._y = 0;
	old_x	= 0;
	right_x = 0;
}

void Map::MapMove()
{
#if 0
	pos._x -= bouei.mov._x;          // 防衛(プレイヤー)の移動スピードをMAPのポジションから引く
	if( old_x - pos._x == 32 )                       // old_x(=0)からpos._xを引いてその差が32(ブロック一つ分)だったら
	{
		right_x++;                                    // 右端の座標を増やす
	}
	old_x = pos._x;		//	今の座標を保存
#endif
}

//!	@name 更新
void Map::update(){
//	MapMove();
};

//!	@name 描画
void Map::draw(){

	for( int y=0; y<MAP_HEIGHT; y++ )
	{
		for( int x=0; x<MAP_WIDTH; x++ )
		{
			switch( MapData[y][x] ){
				case 0:			// 通れるところ
					break;
				case 1:			//	地面描画
					image.draw( x * BLOCK_SIZE, y * BLOCK_SIZE );          // BLOCK_SIZE = 32
					break;
				default:
					break;
			}
			right_x = 32;			// 今の右端を保存(今はとりあえず32を入れている)
			if(x == right_x) break;       // xと右端が同じになったらx方向の描画を飛ばす
		}
	}
	
}
一応マップの配列は3画面分つくったのですが、全部一気に描画するとマップが大きいほど、処理が重たくなると思ったので、
1画面より少し右にスクロールする分を描画させようと思い、right_x(右端を記録しておく変数)をつくりそことxを比較して処理を行おうとしましたが、
スクロールのほうができません。boueiの移動速度と連動させてこのマップをスクロールする方法はないでしょうか?
スクロールする方向は主に右から左です。

あと、マップについて調べているとマップエディタという言葉をよく見かけるのですが、マップエディタというのは見た目2次元配列のマップをビジュアル的に作れるだけで、
それを勝手に配列に戻してくれたりはしないのですか?

上手く質問がまとめれなくてすみません。
回答お願いします。
オフトピック
他のファイルでBoueiというクラスをつくっており、それを宣言したところ、なぜかアクセス違反が起きているのでboueiに関するところはコメントにしてあります。
おそらく、openframeworksの関数などが初期化される前に、Boueiクラスのインスタンス化を行うことでopenframeworksが初期化される前に
Boueiのコンストラクタが呼ばれたためなのでしょうが、ヘッダをまとめて書いてあるところでは一番最初にopenframeworksの関数等をつかえるように、
ofMain.hを一番初めにインクルードしていますが、エラーが起こります。

nil
記事: 428
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#2

投稿記事 by nil » 11年前

画像
酷い絵ではありますが、
画像内の黒枠内部をゲーム内の世界と見ます。
原点(0,0)は黒枠左上の角で、

赤い枠は画面に表示したい範囲です。
赤い枠の左上は表示する画面の原点とし、
ゲーム内の座標では(x1, y1)とすることにします。

今、適当なキャラクタがゲーム世界内にいて、
その座標を(x2, y2)と設定します。

現在(x1,y1)=(100,20)とし、
キャラクタの座標(x2,y2)=(150, 50)とします。

この時キャラクタは画面上では(x2-x1, y2-y1)の座標、つまり(50, 30)に描画されるはずです。
EKISUKE さんが書きました:あと、マップについて調べているとマップエディタという言葉をよく見かけるのですが、マップエディタというのは見た目2次元配列のマップをビジュアル的に作れるだけで、
それを勝手に配列に戻してくれたりはしないのですか?
通常、マップは配列で管理せずに外部ファイルから読みこみます。
その外部ファイルを作ってくれる(作る手伝いをしてくれる)のがマップエディタであり、
配列を作るものではありません。

ちなみに外部ファイルを読み込むほうが配列で管理するよりもはるかに効率がいいです。
マップエディタを使う利点は
1.グラフィカルで編集がしやすい。
2.プログラム内から読み込むので編集のたびにコンパイルを行う必要がない。
主なところではこんなかんじです。
Platinumというものがお勧めです。

クラスはグローバルで管理しないほうが良いです。
なぜならEKISUKEさんがおっしゃっているようにフレームワークが初期化される前にコンストラクタが呼ばれる、といった事態が起きるためです。

なので、インスタンスはローカルで生成するか、ポインタを使って動的確保を行ったほうが良いです。
最後に編集したユーザー nil on 2012年10月11日(木) 23:05 [ 編集 1 回目 ]

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#3

投稿記事 by EKISUKE » 11年前

涼雅 さんが書きました:ちなみに外部ファイルを読み込むほうが配列で管理するよりもはるかに効率がいいです。
マップエディタを使う利点は
1.グラフィカルで編集がしやすい。
2.プログラム内から読み込むので編集のたびにコンパイルを行う必要がない。
主なところではこんなかんじです。
Platinumというものがお勧めです。
他のサイトでもPlatinumがいいという記述があったのでDLはしてありました。
色々いじってますが、まだ使い方は基本的なものしかまだわからないです。
配列を使ってあたり判定をしようと思ったですが、配列を作らないということはあたり判定は配列では行わないのでしょうか?また別の方法で行う感じでしょうか?
後々は、防衛(プレイヤー)は自動で動くようにし、進んでいる方向(次のフレームで進むところ)の配列の中身を調べてその中の値によって次の行動をさせ、
AIのようなものを作りたいと思ってますが、マップエディタはそういう方法にも対応できますか?
涼雅 さんが書きました: 画像内の黒枠内部をゲーム内の世界と見ます。
原点(0,0)は黒枠左上の角で、

赤い枠は画面に表示したい範囲です。
赤い枠の左上は表示する画面の原点とし、
ゲーム内の座標では(x1, y1)とすることにします。

今、適当なキャラクタがゲーム世界内にいて、
その座標を(x2, y2)と設定します。

現在(x1,y1)=(100,20)とし、
キャラクタの座標(x2,y2)=(150, 50)とします。

この時キャラクタは画面上では(x2-x1, y2-y1)の座標、つまり(50, 30)に描画されるはずです。
回答有難うございます。
質問が多くて申し訳ないのですが、これはマップからキャラへの?相対座標というものでしょうか?
あと、スクロールはこのマップの座標を使って行うということですか?
涼雅 さんが書きました: クラスはグローバルで管理しないほうが良いです。
なぜならEKISUKEさんがおっしゃっているようにフレームワークが初期化される前にコンストラクタが呼ばれる、といった事態が起きるためです。

なので、インスタンスはローカルで生成するか、ポインタを使って動的確保を行ったほうが良いです。
それと、クラスをグローバルで管理というのはヘッダのことですか?クラスをほかのファイルで使う場合はそのファイルにだけインクルードするということですか?
インスタンスをローカルで生成するか、ポインタを使って動的確保を行うというのが理解ができないです。すみません。

nil
記事: 428
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#4

投稿記事 by nil » 11年前

EKISUKE さんが書きました: 配列を使ってあたり判定をしようと思ったですが、配列を作らないということはあたり判定は配列では行わないのでしょうか?また別の方法で行う感じでしょうか?
配列ではあるのですが、それにもやはり動的確保が絡んできます。
EKISUKE さんが書きました: 後々は、防衛(プレイヤー)は自動で動くようにし、進んでいる方向(次のフレームで進むところ)の配列の中身を調べてその中の値によって次の行動をさせ、
AIのようなものを作りたいと思ってますが、マップエディタはそういう方法にも対応できますか?
Plutinumにはありません。
プログラムで組むか他の外部ファイルを読み込んで処理する、もしくはそのような機能のついたマップエディタを自作する必要があります。
AIならばプログラムで組むのが良いでしょう。
EKISUKE さんが書きました:これはマップからキャラへの?相対座標というものでしょうか?
あと、スクロールはこのマップの座標を使って行うということですか?
おそらくそうです。
EKISUKE さんが書きました:クラスをグローバルで管理というのはヘッダのことですか?クラスをほかのファイルで使う場合はそのファイルにだけインクルードするということですか?
言葉足らずで申し訳ありませんでした。
僕の言ったグローバルとはグローバル変数を意味するグローバルです。
EKISUKE さんが書きました: インスタンスをローカルで生成するか、ポインタを使って動的確保を行うというのが理解ができないです。
このローカルもローカル変数という意味でのローカルです。

変数にはスコープ、寿命があり、
定義される箇所によってそれがことなります。
一度調べてみてはどうでしょう。

動的確保とはCではmalloc(),free()、C++ではnew, deleteにあたるものです。
http://www.kumei.ne.jp/c_lang/intro/no_33.htm
http://www.kumei.ne.jp/c_lang/cpp/cpp_15.htm

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#5

投稿記事 by EKISUKE » 11年前

回答有難うございます。
涼雅 さんが書きました:Plutinumにはありません。
プログラムで組むか他の外部ファイルを読み込んで処理する、もしくはそのような機能のついたマップエディタを自作する必要があります。
AIならばプログラムで組むのが良いでしょう。
プログラムで組むということは・・・すみませんどういうことでしょう。当たり判定の関数(配列と関係のない)を組むということでしょうか?
涼雅 さんが書きました:配列ではあるのですが、それにもやはり動的確保が絡んできます。
すみません。涼雅さんが貼ってくれたURLを見て勉強させていただいたのですが、どういう風に動的確保が絡んでくるのかわからないです。
エディタで作ったものを配列にnewで当てはめるというようなことですか?
涼雅 さんが書きました:言葉足らずで申し訳ありませんでした。
僕の言ったグローバルとはグローバル変数を意味するグローバルです。
こちらこそすみません。 ではBoueiのクラス宣言はMAPのクラスの中で行うということですね。ということであればわかりました。

えっと聞きたいこととしましては
マップエディタでできるものは配列ではあるけれど、配列のように扱えないということ?(newなどが必要?)
あたり判定などは配列と関係のない別の方法で行わないといけない?
ですかね。もしかすると後で、また質問が出るかもしれません。

何度もすみませんが、回答お願いします。

nil
記事: 428
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#6

投稿記事 by nil » 11年前

EKISUKE さんが書きました: プログラムで組むということは・・・すみませんどういうことでしょう。当たり判定の関数(配列と関係のない)を組むということでしょうか?
はい、マップエディタはあくまでマップを作るものですので、処理を行う関数なんかをプログラムで書いてやる必要があります。
EKISUKE さんが書きました: どういう風に動的確保が絡んでくるのかわからないです。
妙なことを口走ってしまったせいで混乱させてしまったようなのですが、
正直に言うと動的確保は必ずしも必要なものではありません。
ですが、静的に確保する配列(int array[ 15 ];などのように定義して確保する配列)では『決まった大きさ』のものしか定義できません。
例えば、「あのマップはサイズ20*15で作りたいけどこっちのマップはサイズ30*18で作りたい」といった時に動的確保を行えば好きなサイズのマップを読み込むことができる、というだけであって、
「このゲームの仕様でマップのサイズは80*15で固定だ!」という時には動的確保は必要ありません。

あと動的確保をした配列も普通の配列と同じように扱えます。

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#7

投稿記事 by EKISUKE » 11年前

Platinumでcsvファイルを作ったのですが、読み込み方がわからず調べたところfscanfを使うという方法がありました。
http://simd.jugem.jp/?eid=49/
ここのサイトを参考にして作ろうと読んでいたのですが、
fscanfだと文字列の1行文のデータを読むのに%dなどを横の列分すべて書かなければならないようなのですが、もう少し簡単な方法はありますか?

他の質問(http://dixq.net/forum/viewtopic.php?f=3&t=11219#p90377)を見たりしたのですが、fopenでファイルを開いてfgetsでファイルを読み込みwhile文で中の文字列を配列に格納?(ここで動的メモリ確保が役立つ?)
それ以降がわかりません。
あたり判定はレイヤをPlatinumの方で分けて当たり判定用のレイヤをつくりそこであたり判定のあるところに番号を割り振るようなのですが、プログラムの方ではレイヤごとに配列を作って判定という形ですか?一緒にはできないですか?

csvかfmfの読み込みかたのサンプルプログラムか、読み込みの流れを書いていただければありがたいです。

nil
記事: 428
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#8

投稿記事 by nil » 11年前

fmfファイルの読み込みはPlutinumのSamplesフォルダのSrcというフォルダの中にあります。
fmfファイルはバイナリですが、バイナリデータについてはわかりますか?

csvから読み込むときは龍神録のプログラムが参考になります。

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#9

投稿記事 by EKISUKE » 11年前

すみませんバイナリについてはわからないです。
あと、龍神録のプログラムはhttp://dixq.net/rp/index.htmlにのっているものですか?
エクセルのデータ管理のところでしょうか?
解説があまりないようなので、よくわからないですが、csvについてはここを参考にしてやればできますか?

nil
記事: 428
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#10

投稿記事 by nil » 11年前

はい、11章のところです。
その中身がどういうロジックで動いているのかを理解して改造すればいけるかと思います。

サンプルではDXライブラリのファイル入力関数が用いられていますが、そこはCの標準ファイル入出力に置き換えてください。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: 二次元配列でつくったMAPをスクロールさせたい

#11

投稿記事 by ISLe » 11年前

EKISUKE さんが書きました:fscanfだと文字列の1行文のデータを読むのに%dなどを横の列分すべて書かなければならないようなのですが、もう少し簡単な方法はありますか?
そんなことはありません。
改行も空白と同じ区切り文字のひとつでしかありませんから、%dでひとつずつ数字の固まりを読み取れます。

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#12

投稿記事 by EKISUKE » 11年前

http://dixq.net/rp/11.html
今11章の読み込みプログラムを読んでいて質問があるのですが、

コード:

char fname[32]={"../dat/csv/11章/storyH0.csv"};
int input[64];
char inputc[64];
これのそれぞれの役割はなんなのでしょうか?fnameはファイルデータの参照先をcharに入れているようなのですが、要素が32なのはなぜですか?
input と inputcについてはわからないです。

コード:

for(i=0;i<2;i++)//最初の2行読み飛ばす
       while(FileRead_getc(fp)!='\n');
ここはなぜ最初の2行を飛ばしているのですか?それと、for文のなかにwhile文を入れているのはなぜですか・・?
ISLe さんが書きました: そんなことはありません。
改行も空白と同じ区切り文字のひとつでしかありませんから、%dでひとつずつ数字の固まりを読み取れます。
返信有難うございます。
http://simd.jugem.jp/?eid=49/
ここのサイトでは%dなどを複数書いているのですが、それはなぜですか?これはまとめることはできるのですか?

赤鬼
記事: 58
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#13

投稿記事 by 赤鬼 » 11年前

EKISUKE さんが書きました:http://dixq.net/rp/11.html
今11章の読み込みプログラムを読んでいて質問があるのですが、

コード:

char fname[32]={"../dat/csv/11章/storyH0.csv"};
int input[64];
char inputc[64];
これのそれぞれの役割はなんなのでしょうか?fnameはファイルデータの参照先をcharに入れているようなのですが、要素が32なのはなぜですか?
input と inputcについてはわからないです。

コード:

for(i=0;i<2;i++)//最初の2行読み飛ばす
       while(FileRead_getc(fp)!='\n');
ここはなぜ最初の2行を飛ばしているのですか?それと、for文のなかにwhile文を入れているのはなぜですか・・?
32なのは単純に余裕を持ってだと思います。
inputとinputc二つ用意してる理由はdixqさんでは無いのでわかりません。
個人的に2バイト文字使ってない(FileRead_getcが読み込めない)からinputcだけで良いと思いますけどね
それで、inputcはcsvからのデータを受け取っています。
また、テキストデータで受け取っているので実際の整数とは異なります、なのでatoiという関数を使って文字列の数字を整数に変換しています。

cahr[4]=’100’;
charの中には
char[0]=49=0x31='1';
char[1]=48=0x30='0';
char[2]=48=0x30='0';
char[3]=0='\0';
が代入されています。
そして、int num=atoi(char);
とする事によって100という整数に変換されて。
num=100;
が入ります。

二行飛ばしている理由は、csvファイルにある説明用の”/”の行を読み込まない為です。
csvファイの構造はただ単にカンマを打っているだけのテキストファイルなので、下のセルのデータに移るには改行コードを見つけなければいけません。
なので改行コード’\n’が見つかるまでFileRead_getcで一文字ずつ読み続ければ良いのです。

それと、話題が変わるようなら、此方を解決して、別スレッドを立てた方が良いかと思われます。


追記
EKISUKE さんが書きました:
ISLe さんが書きました: そんなことはありません。
改行も空白と同じ区切り文字のひとつでしかありませんから、%dでひとつずつ数字の固まりを読み取れます。
返信有難うございます。
http://simd.jugem.jp/?eid=49/
ここのサイトでは%dなどを複数書いているのですが、それはなぜですか?これはまとめることはできるのですか?
何故といわれても困りますが、そう言う方法があるというだけです。
別に一文字一文字読み込まなくても、まとめる方法ありますよと言ってるだけだと思います。

それと、まとめるというのは11章の読み込みをという事でしょうか?
でしたら可能です。
かなり端折りますが

コード:

while( ( ret = fscanf( fp, "%d,%d,%d,%lf,%lf,%lf,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",&cnt, &pattern, &knd, &x, &y, &sp, &bltime, &blknd, &col,&hp,&blknd2,&wait,item_n[0],item[1],item[2],item[3],item[4],item[5] ) ) != EOF ){
		enemy_order[n].cnt			=cnt;
		enemy_order[n].pattern		=pattern;
		enemy_order[n].knd			=knd;
		enemy_order[n].x			=x;
		enemy_order[n].y 			=y;
		enemy_order[n].sp			=sp;
		enemy_order[n].bltime		=bltime;
		enemy_order[n].blknd		=blknd;
		enemy_order[n].col			=col;
		enemy_order[n].hp			=hp;
		enemy_order[n].blknd2		=blknd2;
		enemy_order[n].wait		=wait;
		for(int i=0;i<6;i++){
			enemy_order[n].item_n[i]	=item_n[i];
		}
		n++;
	}
たぶんこんな感じでしょうか。

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#14

投稿記事 by EKISUKE » 11年前

回答有難うございます。
赤鬼 さんが書きました: 32なのは単純に余裕を持ってだと思います。
inputとinputc二つ用意してる理由はdixqさんでは無いのでわかりません。
個人的に2バイト文字使ってない(FileRead_getcが読み込めない)からinputcだけで良いと思いますけどね
それで、inputcはcsvからのデータを受け取っています。
また、テキストデータで受け取っているので実際の整数とは異なります、なのでatoiという関数を使って文字列の数字を整数に変換しています。

cahr[4]=’100’;
charの中には
char[0]=49=0x31='1';
char[1]=48=0x30='0';
char[2]=48=0x30='0';
char[3]=0='\0';
が代入されています。
そして、int num=atoi(char);
とする事によって100という数字に変換されて。
num=100;
が入ります。
numの中にcharの中のデータがイント型に変換されて代入されるというわけですね。丁寧な解説有難うございます。
赤鬼 さんが書きました:二行飛ばしている理由は、csvファイルにある説明用の”/”の行を読み込まない為です。
csvファイの構造はただ単にカンマを打っているだけのテキストファイルなので、下のセルのデータに移るには改行コードを見つけなければいけません。
なので改行コード’\n’が見つかるまでFileRead_getcで一文字ずつ読み続ければ良いのです。
なるほどそのために二行飛ばしているんですね。
赤鬼 さんが書きました:それと、話題が変わるようなら、此方を解決して、別スレッドを立てた方が良いかと思われます。
すみません。そうですね。
マップをスクロールさせたいのですが、マップエディタをつかってcsvファイルを作りそれを使ってマップ表示がまだできていないので、段階を踏んでいこうと思っていましたが、
ここまで変わると別スレッドを立てた方がいいですね。
赤鬼 さんが書きました:何故といわれても困りますが、そう言う方法があるというだけです。
別に一文字一文字読み込まなくても、まとめる方法ありますよと言ってるだけだと思います。

それと、まとめるというのは11章の読み込みをという事でしょうか?
すみません。fscanfのあとの%dと何回も読んでいるのを一回だけfscanf(fp,"%d",(一つにまとめる方法))という形で全部読み込めることだと勘違いしていました。
ISLeさんの "そんなことはありません。" を "%dはを何回も書かなくてはならないことはない" と勘違いしてしましました。
fscanfを使う方法として配列の横の列を読み込むものだと思っており、その配列の横の要素文だけ%dなどを書かないといけないと思っていました。

それと、質問が多くて申し訳ないのですが、
赤鬼 さんが書きました:

コード:

while( ( ret = fscanf( fp, "%d,%d,%d,%lf,%lf,%lf,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",&cnt, &pattern, &knd, &x, &y, &sp, &bltime, &blknd, &col,&hp,&blknd2,&wait,item_n[0],item[1],item[2],item[3],item[4],item[5] ) ) != EOF ){
        enemy_order[n].cnt          =cnt;
        enemy_order[n].pattern      =pattern;
        enemy_order[n].knd          =knd;
        enemy_order[n].x            =x;
        enemy_order[n].y            =y;
        enemy_order[n].sp           =sp;
        enemy_order[n].bltime       =bltime;
        enemy_order[n].blknd        =blknd;
        enemy_order[n].col          =col;
        enemy_order[n].hp           =hp;
        enemy_order[n].blknd2       =blknd2;
        enemy_order[n].wait       =wait;
        for(int i=0;i<6;i++){
            enemy_order[n].item_n[i]    =item_n[i];
        }
        n++;
    }
このコードは11章のswitch文のところでしょうか?
だとすれば、atoiを使わなくてよくなったのはなぜでしょうか?
それとも、別のところでしょうか?
まだ11章の読み込みがどこなのかよくわかっておらず、すみません。
もしかして、この11章全体が↑のコードでまとめれるということですか?

赤鬼
記事: 58
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#15

投稿記事 by 赤鬼 » 11年前

EKISUKE さんが書きました: このコードは11章のswitch文のところでしょうか?
だとすれば、atoiを使わなくてよくなったのはなぜでしょうか?
それとも、別のところでしょうか?
まだ11章の読み込みがどこなのかよくわかっておらず、すみません。
もしかして、この11章全体が↑のコードでまとめれるということですか?
まずatoiを使う理由を良く考えて下さい。
char型の文字数字をint型に直す為の関数です。そして%dは文字列を10進数、整数型で出力します。
要するにint型で出てきます。つまり、もともと直す必要が無いのです。

11章全体はまとめられません。ファイルのオープンなど敵の処理やらをすっ飛ばしてますから。
しかし、読み込み部分だけならまとめられるのでは。
個人的に見辛いし、何より数を数えるだけで嫌になるので使いませんが。

11章のファイル読み込みはvoid load_story()の関数ですよ。
上のコードはその中の情報の格納だけです。ファイルオープン、クローズなども足して下さい
また、読み込んだ情報を登録する処理もあります。

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#16

投稿記事 by EKISUKE » 11年前

11章のを見ながらいろいろ変えていったのですが、どうもcsvのパスがおかしいのかうまくファイルが開けないようです。

load.cpp

コード:

void Load::Load_csv( char* name, int** Matrix, MATRIX mode )
{
	int n = 0;
	int num = 0;
	int i;	// for文で使う変数宣言
	FILE* fp;		// ファイルを格納
	int input[64];
	char inputc[64];// ファイルの中の値を格納

	fp = fopen( name, "r" );// ファイルを開く
	if(fp == NULL)			// もしファイルが開けなかったら
	{
		printf("%sファイルが開けません\n",name);
		return;				// これ以降の処理を行わない
	}
	for( i=0; i<2; i++)		// 最初の2行を読み飛ばす(csvのコメント部分を読み込まないため)
		while(fgetc(fp)!='\n');	// 1文字づつ読み取り\nが出てくるまで読み飛ばす

	while(1){
		for( i=0; i<64; i++ ){
			inputc[i] = input[i] = fgetc(fp);	// 1文字取得
			if(inputc[i]=='/'){// スラッシュがあったら
				while(fgetc(fp)!='\n');	//改行までループ
				i=-1;	// カウンタを最初に戻して
				continue;
			}
			if(input[i]==',' || input[i]=='\n'){// カンマか改行なら
				inputc[i]='\0';// そこまでを文字列とし
				break;
			}
			if(input[i]==EOF){// ファイルの終わりなら
				goto EXFILE;// 終了
			}
		}

		switch(num){
		case 0:
			break;
		}
		num++;
		if(num==18){
			num=0;
			n++;
		}
	}
EXFILE:
	fclose(fp); // ファイルを閉じる
}
char* nameのところにファイルまでのパスを
int** Matrixのところに2次元配列を渡してもらいその中にデータを入れようかと思っています。
MATRIX modeは1次元配列か2次元配列かをswitch文などで区別して処理しようかと思っていますが、
fopenのところでとめるとfpに渡された値が???で式が評価できないようです。
fopenに渡すパスは11章のプログラムを見るとslnからのパスのようなのですが、↓のようにしてもダメです。

Map.cpp

コード:

load.Load_csv("MapData.csv",MapData, ONE_MATRIX);        // MapData.csvはslnと同じ階層に保存してある。Map.cppからのパスにしてもダメだった
fp 0xcccccccc {_ptr=??? _cnt=??? _base=??? ...} _iobuf *
_ptr CXX0030: エラーです: 式を評価できません
fp = fopen( name, "r");のところで止めるとこう出ます。
_ptr以外にもずらずらと式を評価できないというのが出ています。

nameのところをLoad_csv内にfnameをつくりパスを入れ
ファイルを開こうとしても開けないようです。(MapData.csvはslnと同じ階層です。)

コード:

char fname[32]={"MapData.csv"};
fp = fopen( fname, "r" );// ファイルを開く
これはcsvファイルが開けないのか、パスがあっていないのかどちらでしょうか・・・?
csvファイルは
添付ファイル
MapData.zip
これが今開こうとしているcsvファイルです
(235 バイト) ダウンロード数: 114 回

赤鬼
記事: 58
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#17

投稿記事 by 赤鬼 » 11年前

EKISUKE さんが書きました:11章のを見ながらいろいろ変えていったのですが、どうもcsvのパスがおかしいのかうまくファイルが開けないようです。

load.cpp

コード:

void Load::Load_csv( char* name, int** Matrix, MATRIX mode )
{
	int n = 0;
	int num = 0;
	int i;	// for文で使う変数宣言
	FILE* fp;		// ファイルを格納
	int input[64];
	char inputc[64];// ファイルの中の値を格納

	fp = fopen( name, "r" );// ファイルを開く
	if(fp == NULL)			// もしファイルが開けなかったら
	{
		printf("%sファイルが開けません\n",name);
		return;				// これ以降の処理を行わない
	}
	for( i=0; i<2; i++)		// 最初の2行を読み飛ばす(csvのコメント部分を読み込まないため)
		while(fgetc(fp)!='\n');	// 1文字づつ読み取り\nが出てくるまで読み飛ばす

	while(1){
		for( i=0; i<64; i++ ){
			inputc[i] = input[i] = fgetc(fp);	// 1文字取得
			if(inputc[i]=='/'){// スラッシュがあったら
				while(fgetc(fp)!='\n');	//改行までループ
				i=-1;	// カウンタを最初に戻して
				continue;
			}
			if(input[i]==',' || input[i]=='\n'){// カンマか改行なら
				inputc[i]='\0';// そこまでを文字列とし
				break;
			}
			if(input[i]==EOF){// ファイルの終わりなら
				goto EXFILE;// 終了
			}
		}

		switch(num){
		case 0:
			break;
		}
		num++;
		if(num==18){
			num=0;
			n++;
		}
	}
EXFILE:
	fclose(fp); // ファイルを閉じる
}
char* nameのところにファイルまでのパスを
int** Matrixのところに2次元配列を渡してもらいその中にデータを入れようかと思っています。
MATRIX modeは1次元配列か2次元配列かをswitch文などで区別して処理しようかと思っていますが、
fopenのところでとめるとfpに渡された値が???で式が評価できないようです。
fopenに渡すパスは11章のプログラムを見るとslnからのパスのようなのですが、↓のようにしてもダメです。
Map.cpp

コード:

load.Load_csv("MapData.csv",MapData, ONE_MATRIX);        // MapData.csvはslnと同じ階層に保存してある。Map.cppからのパスにしてもダメだった
fp 0xcccccccc {_ptr=??? _cnt=??? _base=??? ...} _iobuf *
_ptr CXX0030: エラーです: 式を評価できません
fp = fopen( name, "r");のところで止めるとこう出ます。
_ptr以外にもずらずらと式を評価できないというのが出ています。

nameのところをLoad_csv内にfnameをつくりパスを入れ
ファイルを開こうとしても開けないようです。(MapData.csvはslnと同じ階層です。)

コード:

char fname[32]={"MapData.csv"};
fp = fopen( fname, "r" );// ファイルを開く
これはcsvファイルが開けないのか、パスがあっていないのかどちらでしょうか・・・?
csvファイルは
まず、fpの所で止めてしまっては関数が動作する直前で止まっています。
0xccccccccということは初期化すらされていません。
つまりまだファイルが開いていません。
それと、ptr_とかは性質上読み取るまでは値は入りませんよ。(fgetcなどをしないと)
それに付いて詳しく説明する必要があるならします(理解できる自身が有るなら)。
それと、ファイルが開けていない場合はNULLが返ります。

まず、何が駄目なのか説明して下さい。どんなエラーで、何がおかしいのか。
今の情報だけでは自分には判断出来ません。

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#18

投稿記事 by EKISUKE » 11年前

赤鬼 さんが書きました:まず、fpの所で止めてしまっては関数が動作する直前で止まっています。
0xccccccccということは初期化すらされていません。
つまりまだファイルが開いていません。
それと、ptr_とかは性質上読み取るまでは値は入りませんよ。(fgetcなどをしないと)
それに付いて詳しく説明する必要があるならします(理解できる自身が有るなら)。
それと、ファイルが開けていない場合はNULLが返ります。

まず、何が駄目なのか説明して下さい。どんなエラーで、何がおかしいのか。
今の情報だけでは自分には判断出来ません。
説明不足ですみません。
ファイルの正しいパスを渡しているはずなのにファイルが開けないときの処理が行われるのです(コマンドプロンプトに「ファイルが開けません」)。
なので、その処理のところまで実行したら、fpにカーソルを合わせると???がptr_などに入っており、式が評価できないとエラーが出ていました。
そこで、csvへのパスが正しくなかったのかと思いパスを変えたり、slnと同じ階層に保存して開けるかどうか試したのですが、
それでも「ファイルが開けません」とでるので、なぜなのかと思い質問しました。

質問したいこと以外のことを書いてしまい混乱させてすみません。ほかのプログラムも影響してるのかと思い書きました。

赤鬼
記事: 58
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#19

投稿記事 by 赤鬼 » 11年前

EKISUKE さんが書きました: 説明不足ですみません。
ファイルの正しいパスを渡しているはずなのにファイルが開けないときの処理が行われるのです(コマンドプロンプトに「ファイルが開けません」)。
なので、その処理のところまで実行したら、fpにカーソルを合わせると???がptr_などに入っており、式が評価できないとエラーが出ていました。
そこで、csvへのパスが正しくなかったのかと思いパスを変えたり、slnと同じ階層に保存して開けるかどうか試したのですが、
それでも「ファイルが開けません」とでるので、なぜなのかと思い質問しました。

質問したいこと以外のことを書いてしまい混乱させてすみません。ほかのプログラムも影響してるのかと思い書きました。
なるほど。
答えはslnがあるフォルダではありません。
設定によりますが多分ソリューション名のフォルダの中です。

違うのであれば
プロジェクトのプロパティ

デバッグ
その項目の中の作業ディレクトリの項目がどうなってるか確認して下さい
$(ProjectDir)になっていなければ別のフォルダが指定されています。

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#20

投稿記事 by EKISUKE » 11年前

赤鬼 さんが書きました:違うのであれば
プロジェクトのプロパティ

デバッグ
その項目の中の作業ディレクトリの項目がどうなってるか確認して下さい
$(ProjectDir)になっていなければ別のフォルダが指定されています。
調べたところ$(ProjectDir)/binでした。
ここからのパスにしたところ無事ファイルは開けたようです。では読み込みの方の作業を進めたいと思います。
一つ一つ丁寧に答えていただきありがとうございました。

トントン
記事: 100
登録日時: 13年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#21

投稿記事 by トントン » 11年前

EKISUKE さんが書きました:
赤鬼 さんが書きました:違うのであれば
プロジェクトのプロパティ

デバッグ
その項目の中の作業ディレクトリの項目がどうなってるか確認して下さい
$(ProjectDir)になっていなければ別のフォルダが指定されています。
調べたところ$(ProjectDir)/binでした。
ということはここからcsvへのパスで書かないといけないということでしょうか?
さっと目を通す場所としてはここを。

で、作業ディレクトリが$(ProjectDir)/binということは

コード:

char fname[32]={"MapData.csv"};
fp = fopen( fname, "r" );// ファイルを開く
$(ProjectDir)/bin/MapData.csv内を参照しているということです。
作業ディレクトリを変更するか
open関数でファイル名を指定する際、パスを設定しましょう。
絶対パスよりも相対パスが便利です。

# 前回の質問の「スタート、結果画面、ボタンを作りたいです。」の最後の質問、見逃していましたね。申し訳ないです。

追記
おっと、読み込みの解決できてたんですね。

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#22

投稿記事 by EKISUKE » 11年前

トントン さんが書きました:# 前回の質問の「スタート、結果画面、ボタンを作りたいです。」の最後の質問、見逃していましたね。申し訳ないです。

追記
おっと、読み込みの解決できてたんですね。
いえいえ解説有難うございます。
読み込みですが、できたと思ったのですが、どうも関数の中では値が正しく入っているようなのですが、関数から帰ってくると0が入っています。

読み込み関数

コード:

void Load::Load_csv( char* name, int** (&Matrix), MATRIX mode )            // 値がちゃんと反映されるように参照で渡してますが、これが問題かもしれません。
{
	const int MAP_SIZE = 24*96;                            // マップの最大サイズ
	int n = 0;
	int i;	// for文で使う変数宣言
	FILE* fp;		// ファイルを格納
	int input[MAP_SIZE];
	char inputc[MAP_SIZE];// ファイルの中の値を格納

	fp = fopen( name, "r" );// ファイルを開く
	if(fp == NULL)			// もしファイルが開けなかったら
	{
		printf("%sファイルが開けません\n",name);
		return;				// これ以降の処理を行わない
	}
	for( i=0; i<2; i++)		// 最初の2行を読み飛ばす(csvのコメント部分を読み込まないため)
		while(fgetc(fp)!='\n');	// 1文字づつ読み取り\nが出てくるまで読み飛ばす

	while(1){
		for( i=0; i<MAP_SIZE; i++ ){
			inputc[i] = input[i] = fgetc(fp);	// 1文字取得
			if(inputc[i]=='/'){// スラッシュがあったら
				while(fgetc(fp)!='\n');	//改行までループ
				i=-1;	// カウンタを最初に戻して
				continue;
			}
			if(input[i]=='\n'){// 改行なら
				inputc[i]='\0';// そこまでを文字列とし
				break;
			}
			if(input[i]==EOF){// ファイルの終わりなら
				goto EXFILE;// 終了
			}
		}

		switch(mode){
		case ONE_MATRIX:				// 1次元配列の場合
			break;
		case TWO_MATRIX:				// 2次元配列の場合
			for(int y=0; y<24; y++){
				for( int x=0; x<96; x++){
					Matrix[y][x] = atoi(inputc);     // これで配列の中をいじれているはずなのですが、これもまずいのかもしれないですが、わからないです。
				}
			}
			break;
		}
	}
EXFILE:
	fclose(fp); // ファイルを閉じる
}
呼び出し部分

コード:

load.Load_csv("dat/csv/MapData.csv",MapData, TWO_MATRIX);
ブレークポイントでとめてみてみると、最初はMapDataに不定値が入っておりそこからF11でとんで処理をみると
Matrix[y][x] = atoi(inputc);ここの部分ではMatrix[y][x]のところにちゃんと255と入っているのですが、関数からぬけたあとMapDataには0が入ってるみたいです。

描画部分

コード:

for( int y=0; y<MAP_HEIGHT; y++ )
	{
		for( int x=0; x<MAP_WIDTH; x++ )
		{
			switch( MapData[y][x] ){
				case 0:			// 通れるところ
					break;
				case 1:			//	地面描画
					//image.draw( x * BLOCK_SIZE, y * BLOCK_SIZE );
					break;
				case 255:        // とりあえず255が関数で入ってたので描画されるかどうか試すため
					image.draw( x * BLOCK_SIZE, y * BLOCK_SIZE );
					break;
				default:
					break;
			}
		}
	}
そのあと描画部分をみたところ、MapData[y][x]には0がはいっているようです。
やはり読み込み部分の設計がおかしいでしょうか?

追記
どうもEXFILEのところにいったときMatrix[y][x]には0が入るようです。
もしかして、この設計だと、最後に入れられた値で配列の値が初期化されてしまいますか?
たぶんEXFILEがatoiで変換できなくて0が返りそれがMatrix[y][x]にはいり何らかの形で0ですべて初期化されていると思います。(原因はわからないですが、全部初期化の)
最後に編集したユーザー EKISUKE on 2012年10月14日(日) 23:44 [ 編集 1 回目 ]

アバター
へにっくす
記事: 634
登録日時: 12年前
住所: 東京都

Re: 二次元配列でつくったMAPをスクロールさせたい

#23

投稿記事 by へにっくす » 11年前

コード:

void Load::Load_csv( char* name, int** (&Matrix), MATRIX mode )
に渡している第2引数が、

コード:

int Map::MapData[MAP_HEIGHT][MAP_WIDTH];
なのでしたら、型が違うというエラーになると思いますがどうなんでしょう?
オフトピック
VS2005でやってみたら

コード:

error C2664: ’Load::Load_csv’ : 2 番目の引数を ’int [24][96]’ から ’int **&’ に変換できません。
こんなエラー出ましたけど。
そもそもMapDataはintの2次元配列であって、int**と等価ではありません。
int *の配列のポインタとして渡すことになってしまいます。
MapDataは2次元配列だけど、yごとにポインタを持っているわけではなく、先頭のポインタしかないので、

コード:

void Load::Load_csv( char* name, int* Matrix, MATRIX mode );
のようにしないといけないと思います。
もちろんそのLoad_csvの中も、
Matrix[y][x]ではなくMatrix[y * 96 + x]というような形にしないといけません。
※渡された方(関数の中)は、2次元配列とは認識できないから

あと、CSVの読み方についてもおかしい点がありますが、まずは上記を意識してからですかね
written by へにっくす

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#24

投稿記事 by EKISUKE » 11年前

回答有難うございます。
MapDataは次のような形で作っています。

コード:

  // ポインタのポインタに配列を入れる
	MapData = new int* [MAP_HEIGHT];
	//	それに列の分だけ配列を入れて2次元配列をつくる
	for(int i=0; i<MAP_HEIGHT; i++){
		MapData[i] = new int[MAP_WIDTH];
	}
これだとエラーはでないのですが、2次元配列を引数としては渡せないのでしょうか?

先ほど書いてくださったように直してみました。
でも、まだ0で全部値が直されているということは読み込みに問題があるんですね。
goto EXFILEのところに言った瞬間値がMatrix[y*96+x]の値が0になっているようなのですが、どうしてでしょうか?

追記
色々試したところ、どうもif(input==EOF)にはいらず、for文を抜けてまたMatrix[y*96+x]への代入操作を行ったときに値が255から変更されているようです。
なのでcsvのデータの最後に-1を加え、1文字の読み込み回数を増やしたのですが、EOFに引っかからないようです。

赤鬼
記事: 58
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#25

投稿記事 by 赤鬼 » 11年前

EKISUKE さんが書きました:回答有難うございます。
MapDataは次のような形で作っています。

コード:

  // ポインタのポインタに配列を入れる
	MapData = new int* [MAP_HEIGHT];
	//	それに列の分だけ配列を入れて2次元配列をつくる
	for(int i=0; i<MAP_HEIGHT; i++){
		MapData[i] = new int[MAP_WIDTH];
	}
これだとエラーはでないのですが、2次元配列を引数としては渡せないのでしょうか?

先ほど書いてくださったように直してみました。
でも、まだ0で全部値が直されているということは読み込みに問題があるんですね。
goto EXFILEのところに言った瞬間値がMatrix[y*96+x]の値が0になっているようなのですが、どうしてでしょうか?

追記
色々試したところ、どうもif(input==EOF)にはいらず、for文を抜けてまたMatrix[y*96+x]への代入操作を行ったときに値が255から変更されているようです。
なのでcsvのデータの最後に-1を加え、1文字の読み込み回数を増やしたのですが、EOFに引っかからないようです。


うお、二重で動的か・・・・C++ならstd::vector使った方が良いと思うのですが。
それと直したなら直したコードを乗せないと分からないと思います。

追記
良く見たらforで二重ループしてる・・・・・・。
最後の数で全部の値が埋められますね。

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

Re: 二次元配列でつくったMAPをスクロールさせたい

#26

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

途中を全く読んでいませんが、マップ配列で2次元配列とかポインタのポインタってのはまず使いません。
理由は面倒臭い、可変長は引数渡し困難、ポインタのポインタじゃバグの元になるなどです。
Matrix[y * 96 + x]としてアクセスしたほうが容易ですし、なんならMatrixってクラスを作ってしまったほうが管理がしやすいです。
あえて面倒な仕組みを作る必要はないと思いますが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#27

投稿記事 by EKISUKE » 11年前

回答有難うございます。
赤鬼 さんが書きました:うお、二重で動的か・・・・C++ならstd::vector使った方が良いと思うのですが。
それと直したなら直したコードを乗せないと分からないと思います。
すみません。
今の状態です

load.cpp

コード:

//==============================================================
//! @file	load.cpp
//! @brief	csvファイルのロード
//! @author YukiIshigaki
//==============================================================
#include "../../HeaderMain/HeaderMain.h"
#include<stdio.h>

//--------------------------------------------------------------
//!	@name ファイル読み込み
//!	@param [in] name ファイルのパス
//!	@param [in] Matrix マップデータを保存する配列
//!	@param [in]	mode  1次元か2次元配列かを判別
//--------------------------------------------------------------
void Load::Load_csv( char* name, int* Matrix, MATRIX mode )
{
	const int MAP_SIZE = 24*96;  // マップの最大の大きさ
	int i;						 // for文で使う変数宣言
	FILE* fp;					 // ファイルを格納
	int input[MAP_SIZE];		 // ファイルの中を比較用に格納されている
	char inputc[MAP_SIZE];		 // ファイルの中の値を格納

	fp = fopen( name, "r" );	 // ファイルを開く
	if(fp == NULL)				 // もしファイルが開けなかったら
	{
		printf("%sファイルが開けません\n",name);
		return;					 // これ以降の処理を行わない
	}
	for( i=0; i<2; i++)			 // 最初の2行を読み飛ばす(csvのコメント部分を読み込まないため)
		while(fgetc(fp)!='\n');	 // 1文字づつ読み取り\nが出てくるまで読み飛ばす

	while(1){
		for( i=0; i<MAP_SIZE; i++ ){
			inputc[i] = input[i] = fgetc(fp);	// 1文字取得
			if(inputc[i]=='/'){		// スラッシュがあったら
				while(fgetc(fp)!='\n');	//改行までループ
				i=-1;		// カウンタを最初に戻して
				continue;
			}
			if(input[i]=='\n'){// 改行なら
				inputc[i]='\0';// そこまでを文字列とし
				break;
			}
			if(input[i]==EOF){// ファイルの終わりなら
				goto EXFILE;// 終了
			}
		}

		switch(mode){
		case ONE_MATRIX:				// 1次元配列の場合
			break;
		case TWO_MATRIX:				// 2次元配列の場合
			for(int y=0; y<24; y++){
				for( int x=0; x<96; x++){
					Matrix[y*96+x] = atoi(inputc);	// 2次元配列とは認識されないので1次元でいれていく
				}
			}
			break;
		}
	}
EXFILE:
	fclose(fp); // ファイルを閉じる
}
//=============================================================
//	END OF FILE
//=============================================================
赤鬼 さんが書きました: 追記
良く見たらforで二重ループしてる・・・・・・。
最後の数で全部の値が埋められますね。
すみません。いまいち理解できませんでした。
for文のループ回数などを小さくして(csvの中身も少なくしました。)プログラムの流れをみたのですが、
その流れで自分はif(input==EOF)に引っかからずにfor文の回数が終わったため、
また代入のループにはいっておかしな値を全部の配列の中にいれたというような理解なのですが、違うのでしょうか?

softya(ソフト屋) さんが書きました:途中を全く読んでいませんが、マップ配列で2次元配列とかポインタのポインタってのはまず使いません。
理由は面倒臭い、可変長は引数渡し困難、ポインタのポインタじゃバグの元になるなどです。
Matrix[y * 96 + x]としてアクセスしたほうが容易ですし、なんならMatrixってクラスを作ってしまったほうが管理がしやすいです。
あえて面倒な仕組みを作る必要はないと思いますが。


そうなんですか…マップで2次元配列は使わないんですか。
2次元配列のポインタを渡して2次元配列の中にcsvファイルの中の値を入れ、
マップの描画はその配列の中の値によって描画しようと思っていたのですが、これではだめということですか?

Matirxクラスには配列の大きさを格納する変数やそれに応じて配列を作る関数を入れておくのでしょうか?

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

Re: 二次元配列でつくったMAPをスクロールさせたい

#28

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

EKISUKE さんが書きました:そうなんですか…マップで2次元配列は使わないんですか。
2次元配列のポインタを渡して2次元配列の中にcsvファイルの中の値を入れ、
マップの描画はその配列の中の値によって描画しようと思っていたのですが、これではだめということですか?
2次元配列は引数渡しが面倒なのは避けれません。
ポインタのポインタであることもバグの原因となりやすいので敢えて危険を犯すメリットが感じられません。
EKISUKE さんが書きました: Matirxクラスには配列の大きさを格納する変数やそれに応じて配列を作る関数を入れておくのでしょうか?
Matirxクラスを作るとして配列自体は動的に管理できるvectorで管理すれば楽ですよね。
縦横サイズはprivateで管理して引数x,yで配列要素を得るメソッドを作れば良いと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

赤鬼
記事: 58
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#29

投稿記事 by 赤鬼 » 11年前

EKISUKE さんが書きました: load.cpp

コード:

//==============================================================
//! @file	load.cpp
//! @brief	csvファイルのロード
//! @author YukiIshigaki
//==============================================================
#include "../../HeaderMain/HeaderMain.h"
#include<stdio.h>

//--------------------------------------------------------------
//!	@name ファイル読み込み
//!	@param [in] name ファイルのパス
//!	@param [in] Matrix マップデータを保存する配列
//!	@param [in]	mode  1次元か2次元配列かを判別
//--------------------------------------------------------------
void Load::Load_csv( char* name, int* Matrix, MATRIX mode )
{
	const int MAP_SIZE = 24*96;  // マップの最大の大きさ
	int i;						 // for文で使う変数宣言
	FILE* fp;					 // ファイルを格納
	int input[MAP_SIZE];		 // ファイルの中を比較用に格納されている
	char inputc[MAP_SIZE];		 // ファイルの中の値を格納

	fp = fopen( name, "r" );	 // ファイルを開く
	if(fp == NULL)				 // もしファイルが開けなかったら
	{
		printf("%sファイルが開けません\n",name);
		return;					 // これ以降の処理を行わない
	}
	for( i=0; i<2; i++)			 // 最初の2行を読み飛ばす(csvのコメント部分を読み込まないため)
		while(fgetc(fp)!='\n');	 // 1文字づつ読み取り\nが出てくるまで読み飛ばす

	while(1){
		for( i=0; i<MAP_SIZE; i++ ){
			inputc[i] = input[i] = fgetc(fp);	// 1文字取得
			if(inputc[i]=='/'){		// スラッシュがあったら
				while(fgetc(fp)!='\n');	//改行までループ
				i=-1;		// カウンタを最初に戻して
				continue;
			}
			if(input[i]=='\n'){// 改行なら
				inputc[i]='\0';// そこまでを文字列とし
				break;
			}
			if(input[i]==EOF){// ファイルの終わりなら
				goto EXFILE;// 終了
			}
		}

		switch(mode){
		case ONE_MATRIX:				// 1次元配列の場合
			break;
		case TWO_MATRIX:				// 2次元配列の場合
			for(int y=0; y<24; y++){
				for( int x=0; x<96; x++){
					Matrix[y*96+x] = atoi(inputc);	// 2次元配列とは認識されないので1次元でいれていく
				}
			}
			break;
		}
	}
EXFILE:
	fclose(fp); // ファイルを閉じる
}
//=============================================================
//	END OF FILE
//=============================================================
赤鬼 さんが書きました: 追記
良く見たらforで二重ループしてる・・・・・・。
最後の数で全部の値が埋められますね。
すみません。いまいち理解できませんでした。
for文のループ回数などを小さくして(csvの中身も少なくしました。)プログラムの流れをみたのですが、
その流れで自分はif(input==EOF)に引っかからずにfor文の回数が終わったため、
また代入のループにはいっておかしな値を全部の配列の中にいれたというような理解なのですが、違うのでしょうか?

コード:

            for(int y=0; y<24; y++){
                for( int x=0; x<96; x++){
                    Matrix[y*96+x] = atoi(inputc);  // 2次元配列とは認識されないので1次元でいれていく
                }
            }
            break;
この部分inputcで全部置きかえられてしまうと思うんですけど?
つまりinputcに0が入ってたら0で統一されると思いますが。

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#30

投稿記事 by EKISUKE » 11年前

回答有難うございます。
softya(ソフト屋) さんが書きました:Matirxクラスを作るとして配列自体は動的に管理できるvectorで管理すれば楽ですよね。
縦横サイズはprivateで管理して引数x,yで配列要素を得るメソッドを作れば良いと思います。
色々とごちゃごちゃしていたので別プロジェクトで作り直しました。

load.h

コード:

#pragma once
enum MATRIX	
{
	ONE_MATRIX = 1,	//!< 1次元配列
	TWO_MATRIX = 2	//!< 2次元配列
};
class Load
{
public:
	
	void Load_csv(char* name, Matrix data, MATRIX mode);	//!< 渡されたcsvファイルを読み込む
};
load.cpp

コード:

#include "HeaderMain.h"
using namespace std;

//--------------------------------------------------------------
//!	@name ファイル読み込み
//!	@param [in] name ファイルのパス
//!	@param [in] data マップデータを保存する配列
//!	@param [in]	mode  1次元か2次元配列かを判別
//--------------------------------------------------------------
void Load::Load_csv( char* name, Matrix* data, MATRIX mode )           // Matrix* Matrixだとわかりずらいのでdataに変えました。
                                                        // ↑でカーソルを合わせるとvoid Load::Load_csv(char*name, <error-type>,MATRIX mode)と
                            //   load.hに書いてある宣言と互換性がありません。というようなエラーが出ます
{
	const int MAP_SIZE = 24*96;  // マップの最大の大きさ
	int i;						 // for文で使う変数宣言
	FILE* fp;					 // ファイルを格納
	int input[MAP_SIZE];		 // ファイルの中を比較用に格納されている
	char inputc[MAP_SIZE];		 // ファイルの中の値を格納

	fp = fopen( name, "r" );	 // ファイルを開く
	if(fp == NULL)				 // もしファイルが開けなかったら
	{
		printf("%sファイルが開けません\n",name);
		return;					 // これ以降の処理を行わない
	}
	for( i=0; i<2; i++)			 // 最初の2行を読み飛ばす(csvのコメント部分を読み込まないため)
		while(fgetc(fp)!='\n');	 // 1文字づつ読み取り\nが出てくるまで読み飛ばす

	while(1){
		for( i=0; i<MAP_SIZE; i++ ){
			inputc[i] = input[i] = fgetc(fp);	// 1文字取得
			if(inputc[i]=='/'){		// スラッシュがあったら
				while(fgetc(fp)!='\n');	//改行までループ
				i=-1;		// カウンタを最初に戻して
				continue;
			}
			if(input[i]=='\n'){// 改行なら
				inputc[i]='\0';// そこまでを文字列とし
				break;
			}
			if(input[i]==EOF){// ファイルの終わりなら
				goto EXFILE;// 終了
			}
		}

		switch(mode){
		case ONE_MATRIX:				// 1次元配列の場合
			break;
		case TWO_MATRIX:				// 2次元配列の場合
			for(int y=0; y<24; y++){
				for( int x=0; x<96; x++){
					data[y*96+x] = atoi(inputc);	// 2次元配列とは認識されないので1次元でいれていく
					cout << data[y*96+x]<<",";
				}
				cout<<endl;
			}
			break;
		}
	}
EXFILE:
	fclose(fp); // ファイルを閉じる
}
Matrix.h

コード:

#pragma once

class Matrix
{
private:
	int WIDTH;		// 配列の横幅
	int HEGITH;		// 配列の縦幅
public:
	Matrix();
	~Matrix();
	void get_Matrix(int _x,int _y);
	void Create();
};
Matrix.cpp

コード:

#include"HeaderMain.h"
using namespace std;
Matrix::Matrix()
{
}

Matrix::~Matrix()
{
}

// もらった引数を横幅縦幅にいれる
void Matrix::get_Matrix(int _x, int _y)
{
	WIDTH  = _x;
	HEGITH = _y;
}

void Matrix::Create()
{
	vector<std::vector<int> > array(WIDTH,std::vector<int>(HEGITH));	// 2次元配列の作成	
}
main.h (呼び出し)

コード:

#include "HeaderMain.h"
int main()
{
	Load load; // ロードクラス宣言
	Matrix MapData;
	MapData.get_Matrix(96,24);
	MapData.Create();
	load.Load_csv("MapData.csv", *MapData,TWO_MATRIX);       // これらのオペランドと一致する演算子"*"はありません。と出ます。

	/*for(int y=0; y<24; y++){
		for(int x=0; x<96; x++){
			cout<<MapData[y][x]<<",";
		}
		cout<<endl;
	}*/
}
ソースが長くてすみません。
Matixクラスをつくるとはこういうことであっているでしょうか?
今の状態だと、エラーが出ます。
main.cpp
d:\oca_back_up\jisyu\test\csv_test\load.h(20): error C2061: 構文エラー : 識別子 'Matrix'
d:\oca_back_up\jisyu\test\csv_test\main.cpp(11): error C2100: 間接指定演算子 (*) の使い方が正しくありません。
d:\oca_back_up\jisyu\test\csv_test\main.cpp(11): error C2660: 'Load::Load_csv' : 関数に 3 個の引数を指定できません。
load.cpp
d:\oca_back_up\jisyu\test\csv_test\load.h(20): error C2061: 構文エラー : 識別子 'Matrix'
d:\oca_back_up\jisyu\test\csv_test\load.cpp(16): error C2511: 'void Load::Load_csv(char *,Matrix *,MATRIX)' : オーバーロードされたメンバー関数が 'Load' にありません。
d:\oca_back_up\jisyu\test\csv_test\load.h(17) : 'Load' の宣言を確認してください。
Matrix.cpp
d:\oca_back_up\jisyu\test\csv_test\load.h(20): error C2061: 構文エラー : 識別子 'Matrix'


赤鬼 さんが書きました:この部分inputcで全部置きかえられてしまうと思うんですけど?
つまりinputcに0が入ってたら0で統一されると思いますが。
ということは

コード:

int x = 0;
int y = 0;
while(1){
        for( i=0; i<MAP_SIZE; i++ ){
            inputc[i] = input[i] = fgetc(fp);   // 1文字取得
            if(inputc[i]=='/'){     // スラッシュがあったら
                while(fgetc(fp)!='\n'); //改行までループ
                i=-1;       // カウンタを最初に戻して
                continue;
            }
            if(input[i]=='\n'){// 改行なら
                inputc[i]='\0';// そこまでを文字列とし
                break;
            }
            if(input[i]==EOF){// ファイルの終わりなら
                goto EXFILE;// 終了
            }
        }
       switch(mode){
            case ONE_MATRIX:                // 1次元配列の場合
                 break;
            case TWO_MATRIX:                // 2次元配列の場合
                 Matrix[y*96+x] = atoi(inputc);  // 2次元配列とは認識されないので1次元でいれていく
                 break;
       }
      x++;
      if( x == 96)
      {
        x = 0;
        y++;
      }
   }
EXFILE:
      fclose(fp);
}
こういうことですか?

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

Re: 二次元配列でつくったMAPをスクロールさせたい

#31

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

class Matrixがロードを内包しないとカプセル化としてマズイでしょうね。
あとこのclass Matrixにはvector配列を保持する仕組み、マップの指定座標の値を取り出す仕組みもありません。
class自体を書きなれていませんか?無理してクラス化するぐらいならC言語でモジュール化したほうが良いでしょう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#32

投稿記事 by EKISUKE » 11年前

softya(ソフト屋) さんが書きました:class Matrixがロードを内包しないとカプセル化としてマズイでしょうね。
あとこのclass Matrixにはvector配列を保持する仕組み、マップの指定座標の値を取り出す仕組みもありません。
class自体を書きなれていませんか?無理してクラス化するぐらいならC言語でモジュール化したほうが良いでしょう。
vector自体まだよくわかっておらず、それを使ってクラスを作るのがあまりイメージできていません。クラスも書き馴れてないのかもしれないです。

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

Re: 二次元配列でつくったMAPをスクロールさせたい

#33

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

EKISUKE さんが書きました:
softya(ソフト屋) さんが書きました:class Matrixがロードを内包しないとカプセル化としてマズイでしょうね。
あとこのclass Matrixにはvector配列を保持する仕組み、マップの指定座標の値を取り出す仕組みもありません。
class自体を書きなれていませんか?無理してクラス化するぐらいならC言語でモジュール化したほうが良いでしょう。
vector自体まだよくわかっておらず、それを使ってクラスを作るのがあまりイメージできていません。クラスも書き馴れてないのかもしれないです。
クラスは手続きをもった変数(構造体変数)の様なものです。vectorもクラスですから変数と同じ寿命があります。
クラスのインスタンスの寿命は変数と同じで、関数内で定義したものはローカル変数と同じく関数を抜けると消滅します。
これで分かりますでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

nil
記事: 428
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#34

投稿記事 by nil » 11年前

コード:

load.Load_csv("MapData.csv", *MapData,TWO_MATRIX);       // これらのオペランドと一致する演算子"*"はありません。と出ます。
先頭アドレスの取得は&演算子です。
あとget_Matrixという関数名をお使いになっていますが、

オブジェクト指向において、プログラマ->クラスの情報の設定はset,クラス->プログラマの情報の受け渡しはgetを使うのが一般的です。
なので、get_Matrixという関数名は違和感を覚えます。

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#35

投稿記事 by EKISUKE » 11年前

softya(ソフト屋) さんが書きました: クラスは手続きをもった変数(構造体変数)の様なものです。vectorもクラスですから変数と同じ寿命があります。
クラスのインスタンスの寿命は変数と同じで、関数内で定義したものはローカル変数と同じく関数を抜けると消滅します。
これで分かりますでしょうか?
なるほど、今まで自分はクラスは型だと思っていたのですが、変数のようなものなのですね。
でも、コードがうまくイメージができないです。
涼雅 さんが書きました: あとget_Matrixという関数名をお使いになっていますが、
オブジェクト指向において、プログラマ->クラスの情報の設定はset,クラス->プログラマの情報の受け渡しはgetを使うのが一般的です。
なので、get_Matrixという関数名は違和感を覚えます。
すみません。以後関数名に気を付けます。
最後に編集したユーザー EKISUKE on 2012年10月15日(月) 19:12 [ 編集 1 回目 ]

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

Re: 二次元配列でつくったMAPをスクロールさせたい

#36

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

EKISUKE さんが書きました:
softya(ソフト屋) さんが書きました: クラスは手続きをもった変数(構造体変数)の様なものです。vectorもクラスですから変数と同じ寿命があります。
クラスのインスタンスの寿命は変数と同じで、関数内で定義したものはローカル変数と同じく関数を抜けると消滅します。
これで分かりますでしょうか?
なるほど、今まで自分はクラスは型だと思っていたのですが、変数のようなものなのですね。
でも、コードがうまくイメージができないです。
型ですよ。structで作るのが型であるように。
インスタンスは変数ですけどね。この差がわかりますか?

【補足】
型はメモリ上に実体を持ちません。型には変数名を付けて実体を宣言しなければいけません。
クラスの場合は、これがインスタンスです。
構造体などの場合は単に変数と呼びます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

nil
記事: 428
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#37

投稿記事 by nil » 11年前

汎用性を求めないのならば、
width*heightの要素数を持った配列は

コード:

int* pArray = new int[ width*height ];
とすることで出来ます。

y列目x番目の要素の取り出しは

コード:

pArray[ y*width + x ]
です。

通常マップデータの管理はこのように1次元配列を動的確保するのが一般的です。

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

Re: 二次元配列でつくったMAPをスクロールさせたい

#38

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

マップの管理の方法とクラスで作る事自体は分けて勉強したほうがよさそうです。
一緒にやっても混乱するだけでしょうから止めたほうが良いと思います。
もし、クラス化も勉強するって事であれば2段階を踏んではどうでしょう。
1.マップ管理をC言語的にファイル・モジュールで作成する。
2.1.で完成したモジュールをクラス化する。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#39

投稿記事 by EKISUKE » 11年前

softya(ソフト屋) さんが書きました:型ですよ。structで作るのが型であるように。
インスタンスは変数ですけどね。この差がわかりますか?

【補足】
型はメモリ上に実体を持ちません。型には変数名を付けて実体を宣言しなければいけません。
クラスの場合は、これがインスタンスです。
構造体などの場合は単に変数と呼びます。
Class class;これがインスタンス化であり、classは変数だから寿命が普通の変数と同じということですよね。
涼雅 さんが書きました:汎用性を求めないのならば、
width*heightの要素数を持った配列は

コード:

int* pArray = new int[ width*height ];
y列目x番目の要素の取り出しは

コード:

pArray[ y*width + x ]
です。
通常マップデータの管理はこのように1次元配列を動的確保するのが一般的です。
とすることで出来ます。
なるほど、後々はマップの描画をマップ全体を描画してせず、画面の右端から一つ分だけ多めに描画してスクロールしたいのですが、
1次元配列でその実装の仕方がわからないのです。1次元でも2次元でも実装の仕方はあまり変わらないのでしょうか?
softya(ソフト屋) さんが書きました:マップの管理の方法とクラスで作る事自体は分けて勉強したほうがよさそうです。
一緒にやっても混乱するだけでしょうから止めたほうが良いと思います。
もし、クラス化も勉強するって事であれば2段階を踏んではどうでしょう。
1.マップ管理をC言語的にファイル・モジュールで作成する。
2.1.で完成したモジュールをクラス化する。
そうしようと思います。今いろいろと頭の中でこんがらがってよくわからないので、
とりあえずcsvファイルを読み込んでマップを描画し、スクロールさせてからクラス化していきたいです。

せっかく答えてくださっているのにわがまま言って申し訳ないです。

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

Re: 二次元配列でつくったMAPをスクロールさせたい

#40

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

>1次元配列でその実装の仕方がわからないのです。1次元でも2次元でも実装の仕方はあまり変わらないのでしょうか?
1次元配列でも余り変わりません。

例えばですね物事を単純化するためマップが縦幅のない1次元だったとします。
これを画面幅分だけキャラクタの横位置に合わせてスクロールして表示したいとします。
どうですか、プログラムが組めますか?
ここが分かっていないと2次元、1次元以前にスクロールが分かっていないことになります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#41

投稿記事 by EKISUKE » 11年前

マップの座標の描画位置をプレイヤーの速度と反対方向にずらしていくということだと思ってます。
今作っているゲームの背景はプレイヤーの速度で背景の座標を引いてスクロールさせています。
ですが、配列の座標はどの位置を基準にずらすのかがわかっていないです。
おそらく配列数分だけ計算するんじゃないかと思います。
最後に編集したユーザー EKISUKE on 2012年10月15日(月) 19:45 [ 編集 1 回目 ]

赤鬼
記事: 58
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#42

投稿記事 by 赤鬼 » 11年前

EKISUKE さんが書きました: ということは

コード:

int x = 0;
int y = 0;
while(1){
        for( i=0; i<MAP_SIZE; i++ ){
            inputc[i] = input[i] = fgetc(fp);   // 1文字取得
            if(inputc[i]=='/'){     // スラッシュがあったら
                while(fgetc(fp)!='\n'); //改行までループ
                i=-1;       // カウンタを最初に戻して
                continue;
            }
            if(input[i]=='\n'){// 改行なら
                inputc[i]='\0';// そこまでを文字列とし
                break;
            }
            if(input[i]==EOF){// ファイルの終わりなら
                goto EXFILE;// 終了
            }
        }
       switch(mode){
            case ONE_MATRIX:                // 1次元配列の場合
                 break;
            case TWO_MATRIX:                // 2次元配列の場合
                 Matrix[y*96+x] = atoi(inputc);  // 2次元配列とは認識されないので1次元でいれていく
                 break;
       }
      x++;
      if( x == 96)
      {
        x = 0;
        y++;
      }
   }
EXFILE:
      fclose(fp);
}
こういうことですか?
そうです。
それで読み込めませんでしたか?

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

Re: 二次元配列でつくったMAPをスクロールさせたい

#43

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

EKISUKE さんが書きました:マップの座標の描画位置をプレイヤーの速度と反対方向にずらしていくということだと思ってます。
今作っているゲームの背景はプレイヤーの速度で背景の座標を引いてスクロールさせています。
それなら要するに配列から指定されたx,y座標(マップ座標系)のマップデータを得られば良いことは分かりますよね?
それが涼雅 さんなどが書いている配列のアクセス方法なんですが。
pArray[y][x]をpArray[ y*width + x ]と置き換えるだけです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#44

投稿記事 by EKISUKE » 11年前

赤鬼 さんが書きました:
EKISUKE さんが書きました: ということは

コード:

int x = 0;
int y = 0;
while(1){
        for( i=0; i<MAP_SIZE; i++ ){
            inputc[i] = input[i] = fgetc(fp);   // 1文字取得
            if(inputc[i]=='/'){     // スラッシュがあったら
                while(fgetc(fp)!='\n'); //改行までループ
                i=-1;       // カウンタを最初に戻して
                continue;
            }
            if(input[i]=='\n'){// 改行なら
                inputc[i]='\0';// そこまでを文字列とし
                break;
            }
            if(input[i]==EOF){// ファイルの終わりなら
                goto EXFILE;// 終了
            }
        }
       switch(mode){
            case ONE_MATRIX:                // 1次元配列の場合
                 break;
            case TWO_MATRIX:                // 2次元配列の場合
                 Matrix[y*96+x] = atoi(inputc);  // 2次元配列とは認識されないので1次元でいれていく
                 break;
       }
      x++;
      if( x == 96)
      {
        x = 0;
        y++;
      }
   }
EXFILE:
      fclose(fp);
}
こういうことですか?
そうです。
それで読み込めませんでしたか?
ブレークポイントで追うと、途中まではうまく読み込まれるみたいですが、最終的(おそらくgoto EXFILEに行ったとき)に不定値が配列に入れられているみたいです。
goto EXFILEの判定の中にブレークポイントを置いて試すとgoto EXFILEにいった瞬間配列の中のデータが不定値に切り替わっているようです。

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#45

投稿記事 by EKISUKE » 11年前

softya(ソフト屋) さんが書きました: それなら要するに配列から指定されたx,y座標(マップ座標系)のマップデータを得られば良いことは分かりますよね?
それが涼雅 さんなどが書いている配列のアクセス方法なんですが。
pArray[y][x]をpArray[ y*width + x ]と置き換えるだけです。
2列目のx番目が見たいときは1次元配列だとx番目に2列分の配列数を足すということですよね

赤鬼
記事: 58
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#46

投稿記事 by 赤鬼 » 11年前

EKISUKE さんが書きました: ブレークポイントで追うと、途中まではうまく読み込まれるみたいですが、最終的(おそらくgoto EXFILEに行ったとき)に不定値が配列に入れられているみたいです。
goto EXFILEの判定の中にブレークポイントを置いて試すとgoto EXFILEにいった瞬間配列の中のデータが不定値に切り替わっているようです。

コード:

            if(input[i]=='\n'){// 改行なら
                inputc[i]='\0';// そこまでを文字列とし
                break;
            }

コード:

            if(input[i]=='\n'||inputc[i]==','){// 改行とカンマなら
                inputc[i]='\0';// そこまでを文字列とし
                break;
            }
他にも間違いがありますね。
上のだとカンマが混じると思うのですが。
atoiは数字以外は全部0を返しますよ。
全く持ってEXFILE:は関係無いです。

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#47

投稿記事 by EKISUKE » 11年前

赤鬼 さんが書きました: 他にも間違いがありますね。
上のだとカンマが混じると思うのですが。
atoiは数字以外は全部0を返しますよ。
全く持ってEXFILE:は関係無いです。
有難うございます。おかげで読み込むことができました。
最初二重ループを使っていたとき、読み込みの流れを完全に理解していなかったため、
カンマの条件のところのせいで正しく読み込まれていないものと勘違いして消してしまってたのがダメだったんですね。
赤鬼さんのおかげでやっと理解できたと思います。有難うございます。
csvファイルからは正しく読み込まれ、描画の方もうまくできていました。読み込みは下のようになりました。

コード:

#include "../../HeaderMain/HeaderMain.h"
#include<stdio.h>

//--------------------------------------------------------------
//!	@name ファイル読み込み
//!	@param [in] name ファイルのパス
//!	@param [in] Matrix マップデータを保存する配列
//!	@param [in]	mode  1次元か2次元配列かを判別
//--------------------------------------------------------------
void Load::Load_csv( char* name, int* Matrix, MATRIX mode )
{
	const int MAP_SIZE = 24*96;  // マップの最大の大きさ
	int i;						 // for文で使う変数宣言
	int x=0;
	int y=0;
	FILE* fp;					 // ファイルを格納
	int input[MAP_SIZE];		 // ファイルの中を比較用に格納されている
	char inputc[MAP_SIZE];		 // ファイルの中の値を格納

	fp = fopen( name, "r" );	 // ファイルを開く
	if(fp == NULL)				 // もしファイルが開けなかったら
	{
		printf("%sファイルが開けません\n",name);
		return;					 // これ以降の処理を行わない
	}
	for( i=0; i<2; i++)			 // 最初の2行を読み飛ばす(csvのコメント部分を読み込まないため)
		while(fgetc(fp)!='\n');	 // 1文字づつ読み取り\nが出てくるまで読み飛ばす

	while(1){
		for( i=0; i<MAP_SIZE; i++ ){
			inputc[i] = input[i] = fgetc(fp);	// 1文字取得
			if(inputc[i]=='/'){		// スラッシュがあったら
				while(fgetc(fp)!='\n');	//改行までループ
				i=-1;		// カウンタを最初に戻して
				continue;
			}
			if(input[i]=='\n'|| input[i]==','){// 改行かカンマなら
				inputc[i]='\0';// そこまでを文字列とし
				break;
			}
			if(input[i]==EOF){// ファイルの終わりなら
				goto EXFILE;// 終了
			}
		}

		switch(mode){
		case ONE_MATRIX:				// 1次元配列の場合
			break;
		case TWO_MATRIX:				// 2次元配列の場合			
			Matrix[y*96+x] = atoi(inputc);	// 2次元配列とは認識されないので1次元でいれていく
			break;
		}
		x++;
		if(x==96)
		{
			x=0;
			y++;
		}
	}
EXFILE:
	fclose(fp); // ファイルを閉じる
}
スクロールも以下のようにしました。(pos._xはあとで名前を変更します)

コード:

void Map::MapMove()
{
#if 1
	bouei.update();                   // bouei.mov_xはほかのところでも使うので後々Gloabalクラスなどを作りその中にScroll_Speedに入れようと思っています。
	pos._x -= bouei.mov._x;      // bouei.mov_xがプレイヤーの速度に当たります
	
#endif
}

//!	@name 更新
void Map::update(){
	MapMove();
};
//!	@name 描画
void Map::draw(){

	for( int y=0; y<MAP_HEIGHT; y++ )
	{
		for( int x=0; x<MAP_WIDTH; x++ )
		{
			switch( MapData[y*MAP_WIDTH + x] ){
				case 0:			// 通れるところ
					break;
				case 1:			//	地面描画
					break;
				case 255:		//とりあえず描画
					image.draw( x * BLOCK_SIZE+pos._x, y * BLOCK_SIZE );
					break;
				default:
					break;
			}
		}
	}
}
色々と付き合っていただきありがとうございました。
今回の質問でいろいろと勉強になり大変感謝しています。
この質問の目的である「2次元配列を使ってマップをスクロールさせたい」はできたので解決とさせていただきます。
マップのスクロールだけでなく、マップエディタの使い方からcsvの読み込み方、2次元配列から1次元配列への移行の仕方など、
一つ一つ丁寧に答えていただきありがとうございました。
また、躓くことがあるかもしれないので、その時はまたこの掲示板を使わせていただきます。
クラス化については新しくスレッドを立てさせていただきそこで勉強をさせていただきたいと思います。
長い間お付き合いいただき本当にありがとうございました。
まだ、↑のソースコードで問題がありましたら、ご指摘お願いします。

といってすぐに申し訳ないのですが、
csvファイルの読み込みで最初の2行の読みこみを飛ばす処理をマスクしたところマップの描画のところでアクセス違反が発生しました。
最初の2行読み飛ばしの処理をマスクした理由はcsvファイルをテキストエディタで開くとコメント部分がなかったため飛ばしたのですが、
読み飛ばし部分

コード:

 for( i=0; i<2; i++)          // 最初の2行を読み飛ばす(csvのコメント部分を読み込まないため)
        while(fgetc(fp)!='\n');  // 1文字づつ読み取り\nが出てくるまで読み飛ばす
描画の部分

コード:

switch( MapData[y*MAP_WIDTH + x] ){
				case 0:			// 通れるところ
					break;
				case 1:			//	地面描画
					break;
				case 255:		//とりあえず描画
					image.draw( x * BLOCK_SIZE+pos._x, y * BLOCK_SIZE );
					break;
				default:
					break;
			}
ここのcase255のimage.drawのところでアクセス違反が発生しているようです。
x,yともに0の時にアクセス違反を起こしているようです。
最初の2行を読み飛ばしたときはこのようなことは起こらないのに読み飛ばし処理を飛ばすとアクセス違反が起こる関係性がわかりません。
MapData[y*MAP_WIDTH + x]には正しく値が入っています。
アクセス違反が起こるのはなぜでしょうか?
最後まで質問ばかりですみません。

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#48

投稿記事 by EKISUKE » 11年前

コード:

 while(1){
        for( i=0; i<MAP_SIZE; i++ ){
            inputc[i] = input[i] = fgetc(fp);   // 1文字取得
            if(inputc[i]=='/'){     // スラッシュがあったら
                while(fgetc(fp)!='\n'); //改行までループ
                i=-1;       // カウンタを最初に戻して
                continue;
            }
            if(input[i]=='\n'|| input[i]==','){// 改行かカンマなら
                inputc[i]='\0';// そこまでを文字列とし
                break;
            }
            if(input[i]==EOF){// ファイルの終わりなら
                goto EXFILE;// 終了
            }
        }
 
        switch(mode){
        case ONE_MATRIX:                // 1次元配列の場合
            break;
        case TWO_MATRIX:                // 2次元配列の場合           
            Matrix[y*96+x] = atoi(inputc);  // 2次元配列とは認識されないので1次元でいれていく
            break;
        }
        x++;
        if(x==96)
        {
            x=0;
            y++;
        }
        if(y==24)
        {
            goto  EXFILE;
        }
    }
EXFILE:
    fclose(fp); // ファイルを閉じる
これで一応解決したのですが、なぜかいまいちわかっていません。
おそらく24行目まで読み込もうとして入れ子の配列を越えてしまったのでしょうが、描画が終わった後にアクセス違反が起こるのが納得がいかないです。
なにか、たまたま解決しただけで根本的な解決になっていなような気がするので、質問しました。
解決方法はこれであっているでしょうか・・・・

赤鬼
記事: 58
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#49

投稿記事 by 赤鬼 » 11年前

EKISUKE さんが書きました: これで一応解決したのですが、なぜかいまいちわかっていません。
おそらく24行目まで読み込もうとして入れ子の配列を越えてしまったのでしょうが、描画が終わった後にアクセス違反が起こるのが納得がいかないです。
なにか、たまたま解決しただけで根本的な解決になっていなような気がするので、質問しました。
解決方法はこれであっているでしょうか・・・・
すみません見間違えました。

追記
多分大丈夫だと思います。
先ほどまでのコードは配列溢れの対策が全くなっていなかったので。

EKISUKE
記事: 108
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#50

投稿記事 by EKISUKE » 11年前

2行飛ばしたときには正常に動いたのは初期化が配列があふれるまで行われなかったということでしょうか・・・?
2行読み飛ばす処理の

コード:

 for( i=0; i<2; i++)          // 最初の2行を読み飛ばす(csvのコメント部分を読み込まないため)
        while(fgetc(fp)!='\n');  // 1文字づつ読み取り\nが出てくるまで読み飛ばす
 
これが行われたとき
読み込み処理である

コード:

while(1){
        for( i=0; i<MAP_SIZE; i++ ){
            inputc[i] = input[i] = fgetc(fp);   // 1文字取得
            if(inputc[i]=='/'){     // スラッシュがあったら
                while(fgetc(fp)!='\n'); //改行までループ
                i=-1;       // カウンタを最初に戻して
                continue;
            }
            if(input[i]=='\n'|| input[i]==','){// 改行かカンマなら
                inputc[i]='\0';// そこまでを文字列とし
                break;
            }
            if(input[i]==EOF){// ファイルの終わりなら
                goto EXFILE;// 終了
            }
        }
 
        switch(mode){
        case ONE_MATRIX:                // 1次元配列の場合
            break;
        case TWO_MATRIX:                // 2次元配列の場合           
            Matrix[y*96+x] = atoi(inputc);  // 2次元配列とは認識されないので1次元でいれていく
            break;
        }
        x++;
        if(x==96)
        {
            x=0;
            y++;
        }
    }
EXFILE:
    fclose(fp); // ファイルを閉じる
ここの中の動きがどう変わるのかがまだ理解できていないです。

赤鬼
記事: 58
登録日時: 12年前

Re: 二次元配列でつくったMAPをスクロールさせたい

#51

投稿記事 by 赤鬼 » 11年前

EKISUKE さんが書きました:2行飛ばしたときには正常に動いたのは初期化が配列があふれるまで行われなかったということでしょうか・・・?
試していないので憶測ですがそうだと思います。
もしくは、ただエラーが起きなかっただけかもしれません。
配列溢れで気づかないところでバグなんて気をつけないとしょっちゅう起こってしまうかと。
EKISUKE さんが書きました:ここの中の動きがどう変わるのかがまだ理解できていないです。
見てトレースが難しいのなら、デバッガで一つ一つ追いかけて行くしか無いかと思います。

閉鎖

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