ページ 11

画像がデバッグ途中で消えてしまう

Posted: 2012年4月30日(月) 16:34
by シラス
こんにちは。
今作っているものについて、どうにもわからないことが出てきてしまったので
トピックを立てさせていただきます。
当方は初心者です。

DxLibのリファレンスを参考に簡単な不思議のダンジョン風マップを作っているんですが、
デバッグ開始して少し経つと画像が消えてしまいます。
デバッグのログには「グラフィックハンドルの数が限界数に達していて新たなハンドルを作成できません」とあるので、どこかで画像の読み込みが変なループになってるのかな?とは想像できるのですが、
どこを弄ればよいのか見当がつきません。。。
ご教授よろしくお願いします。

それと、もしお手すきでしたら、もっとスッキリする方法を教えてくださると助かります。
リファレンスのソースに思うままに追加していったら、よくわからないものになってしまったので。。。

コード:

// マップスクロール基本
#include "DxLib.h"

#define MAP_SIZE	40			// マップチップ一つのドットサイズ
#define MAP_WIDTH	20			// マップの幅
#define MAP_HEIGHT	20			// マップの縦長さ
#define MOVE_FRAME	16			// 移動にかけるフレーム数
#define INPUT_DOUJI_TIME			10		// 同時押しの範囲となる時間

typedef struct{
	int img,muki;
}ch_t;

// マップのデータ
int MapData[ MAP_HEIGHT ][ MAP_WIDTH ] =
{
	{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,2,2,0,0,0,0,0,1,1,1,1,1,1,0 },
	{0,1,1,1,1,1,2,2,0,0,0,0,0,1,3,1,3,1,1,0 }, 
	{0,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,0 },
	{0,1,1,1,1,1,1,1,5,5,5,0,0,1,3,1,3,1,1,0 },
	{0,1,3,3,1,1,1,1,0,0,5,5,5,1,1,1,1,1,1,0 },
	{0,4,1,1,1,1,1,4,0,0,0,0,0,1,1,1,1,1,1,0 },
	{0,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,0 },
	{0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0 },
	{0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0 },
	{0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0 },
	{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 },
	{0,1,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0 },
	{0,1,2,6,6,6,6,6,6,6,2,1,1,1,1,1,1,1,1,0 },
	{0,1,2,6,6,6,6,6,6,6,2,1,1,1,1,1,1,1,1,0 },
	{0,1,2,6,6,6,6,6,6,6,2,1,1,1,1,1,1,1,1,0 },
	{0,1,2,6,6,6,6,6,6,6,2,1,1,1,1,1,1,1,1,0 },
	{0,1,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0 },
	{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 },
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
};

// プレイヤーの位置
int PlayerX , PlayerY ;

// 移動しているかどうかのフラグ( 0:停止中  1:移動中 )
int Move ;

// 各方向に移動する量
int MoveX, MoveY ;

// 移動し始めてから何フレーム経過したかを保持する変数
int MoveCounter ;

//イメージ配列
int image[32],imagemap[16];

//初期位置に使うランダム
int Random[1];

//時間データ
DATEDATA Date; 

ch_t ch;

// マップとプレイヤーの描画関数
void GraphDraw( int ScrollX, int ScrollY ){

	int j , i ;
	int MapDrawPointX , MapDrawPointY ;		// 描画するマップ座標値
	int DrawMapChipNumX , DrawMapChipNumY ;	// 描画するマップチップの数

	// 描画するマップチップの数をセット
	DrawMapChipNumX = 400 / MAP_SIZE + 2 ;
	DrawMapChipNumY = 400 / MAP_SIZE + 2 ;

	// 画面左上に描画するマップ座標をセット
	MapDrawPointX = PlayerX - ( DrawMapChipNumX / 2 - 1 ) ;
	MapDrawPointY = PlayerY - ( DrawMapChipNumY / 2 - 1 ) ;

	LoadDivGraph( "chmap.png" , 32 , 4 , 8 , 40 , 40 , image ) ;//キャラ画像チップ
	LoadDivGraph( "mapchip.png" , 16 , 4 , 4 , 40 , 40 , imagemap ) ;//マップチップ

	// マップを描く
	for( i = -1 ; i < DrawMapChipNumY ; i ++ )
	{
		for( j = -1 ; j < DrawMapChipNumX ; j ++ )
		{
			// 画面からはみ出た位置なら描画しない
			if( j + MapDrawPointX < 0 || i + MapDrawPointY < 0 ||
				j + MapDrawPointX >= MAP_WIDTH || i + MapDrawPointY >= MAP_HEIGHT ) continue ;

			// マップデータが0だったら四角を描画する
			if( MapData[ i + MapDrawPointY ][ j + MapDrawPointX ] == 0 )//カベ
			{
				DrawGraph(j * MAP_SIZE + ScrollX,	i * MAP_SIZE + ScrollY,
					imagemap[0],TRUE);
			}
			if( MapData[ i + MapDrawPointY ][ j + MapDrawPointX ] == 1 )//床
			{
				DrawGraph(j * MAP_SIZE + ScrollX,	i * MAP_SIZE + ScrollY,
					imagemap[1],TRUE);
			}
			if( MapData[ i + MapDrawPointY ][ j + MapDrawPointX ] == 2 )//水路
			{
				DrawGraph(j * MAP_SIZE + ScrollX,	i * MAP_SIZE + ScrollY,
					imagemap[2],TRUE);
			}
			if( MapData[ i + MapDrawPointY ][ j + MapDrawPointX ] == 3 )//ワナ
			{
				DrawGraph(j * MAP_SIZE + ScrollX,	i * MAP_SIZE + ScrollY,
					imagemap[3],TRUE);
			}
			if( MapData[ i + MapDrawPointY ][ j + MapDrawPointX ] == 4 )//道具
			{
				DrawGraph(j * MAP_SIZE + ScrollX,	i * MAP_SIZE + ScrollY,
					imagemap[4],TRUE);
			}
			if( MapData[ i + MapDrawPointY ][ j + MapDrawPointX ] == 5 )//通路
			{
				DrawGraph(j * MAP_SIZE + ScrollX,	i * MAP_SIZE + ScrollY,
					imagemap[1],TRUE);
			}
			if( MapData[ i + MapDrawPointY ][ j + MapDrawPointX ] == 6 )//水路に囲まれた床
			{
				DrawGraph(j * MAP_SIZE + ScrollX,	i * MAP_SIZE + ScrollY,
					imagemap[1],TRUE);
			}
		}
	}

	//キャラの向き
	ch.img=image[(PlayerX%2+PlayerY%2)+ch.muki*4];

	DrawGraph( ( PlayerX - MapDrawPointX ) * MAP_SIZE , ( PlayerY - MapDrawPointY ) * MAP_SIZE  ,ch.img , TRUE ) ;

}//void GraphDraw( int ScrollX, int ScrollY )


int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )// WinMain関数
{

	SetGraphMode( 400 , 400 , 32 ) ;

	int Key ;
	int ScrollX, ScrollY ;

	//斜め移動
	int Direct;

	if( DxLib_Init() == -1 )	// DXライブラリ初期化処理
	{
		return -1;				// エラーが起きたら直ちに終了
	}

	SetDrawScreen( DX_SCREEN_BACK ) ;//描画先を裏画面に設定

	//向き初期値
	ch.muki=0;

	//斜め固定初期値
	Direct = 0;

	// 最初は停止中(0)にしておく
	Move = 0 ;

	//while( MapData[ PlayerY ][ PlayerX ] != 1 ){

	//	GetDateTime( &Date ) ;
	//	SRand(Date.Sec);//秒をランダムの初期値に

	//	Random[0] = GetRand( 20 );

	//	// プレイヤーの初期位置をセット
	//	PlayerX = Random[0];
	//	PlayerY = Random[0];

	//}

	PlayerX = 2;
	PlayerY = 2;

	// ループ
	while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 && ClearDrawScreen() == 0)
	{

		// 移動中ではない場合キー入力を受け付ける
		if( Move == 0 )
		{
			// キー入力ゲット
			Key = GetJoypadInputState( DX_INPUT_KEY_PAD1 ) ;

			//Z(D)押した時は斜め固定
			if ( Key & PAD_INPUT_Z)
			{
				Direct = 1;
			}

			// キー入力に応じてプレイヤーの座標を移動
			if (( Key & PAD_INPUT_UP) && Direct== 0)//上
			{
				Move = 1 ;
				MoveX = 0 ;
				MoveY = -1 ;
				ch.muki = 0;
			}

			if(( Key & PAD_INPUT_LEFT) && Direct== 0)//左
			{
				Move = 1 ;
				MoveX = -1 ;
				MoveY = 0 ;
				ch.muki = 1;
			}
			if(( Key & PAD_INPUT_DOWN) && Direct== 0)//下
			{
				Move = 1 ;
				MoveX = 0 ;
				MoveY = 1 ;
				ch.muki = 2;
			}

			if(( Key & PAD_INPUT_RIGHT) && Direct== 0)//右
			{
				Move = 1 ;
				MoveX = 1 ;
				MoveY = 0 ;
				ch.muki = 3;
			}
			//●ななめ
			if( Key & PAD_INPUT_LEFT && Key & PAD_INPUT_UP)//左上
			{
				Move = 1 ;
				MoveX = -1 ;
				MoveY = -1 ;
				ch.muki = 4;
			}
			if( Key & PAD_INPUT_LEFT && Key & PAD_INPUT_DOWN)//左下
			{
				Move = 1 ;
				MoveX = -1 ;
				MoveY = 1 ;
				ch.muki = 5;
			}
			if( Key & PAD_INPUT_RIGHT && Key & PAD_INPUT_UP)//右上
			{
				Move = 1 ;
				MoveX = 1 ;
				MoveY = -1 ;
				ch.muki = 6;
			}
			if( Key & PAD_INPUT_RIGHT && Key & PAD_INPUT_DOWN)//右下
			{
				Move = 1 ;
				MoveX = 1 ;
				MoveY = 1 ;
				ch.muki = 7;
			}
	//斜め固定解除
			Direct = 0;

			// 進入不可能なマップだった場合は移動できない
			if( Move == 1 ){
				if( MapData[ PlayerY + MoveY ][ PlayerX + MoveX ] == 0 )//カベ
				{
					Move = 0 ;
				}
				else
				{
					MoveCounter = 0 ;
				}
			}

			if( Move == 1 )
			{
				if( MapData[ PlayerY + MoveY ][ PlayerX + MoveX ] == 2 )//水路

				{
					Move = 0 ;
				}
				else
				{
					MoveCounter = 0 ;
				}
			}


			if( Move == 1 )
			{
				if( MapData[ PlayerY + MoveY ][ PlayerX + MoveX ] == 3 )//わな
				{

					printfDx("わな");
				}
				else
				{
					MoveCounter = 0 ;
				}
			}

			if( Move == 1 )
			{
				if( MapData[ PlayerY + MoveY ][ PlayerX + MoveX ] == 4 )//アイテム
				{
					printfDx("アイテム");
				}
				else
				{
					MoveCounter = 0 ;
				}
			}

			// 停止中は画面のスクロールは行わない
			ScrollX = 0 ;
			ScrollY = 0 ;

		}


		// 移動中の場合は移動処理を行う
		if( Move == 1 )
		{
			MoveCounter ++ ;

			// 移動処理が終了したら停止中にする
			if( MoveCounter == MOVE_FRAME )
			{
				Move = 0 ;

				// プレイヤーの位置を変更する
				PlayerX += MoveX ;
				PlayerY += MoveY ;

				// 停止中は画面のスクロールは行わない
				ScrollX = 0 ;
				ScrollY = 0 ;
			}
			else
			{
				// 経過時間からスクロール量を算出する
				ScrollX = -( MoveX * MAP_SIZE * MoveCounter / MOVE_FRAME ) ;
				ScrollY = -( MoveY * MAP_SIZE * MoveCounter / MOVE_FRAME ) ;
			}
		}

		// マップとプレイヤーを描画
		GraphDraw( ScrollX, ScrollY ) ;

		// 裏画面の内容を表画面に映す
		ScreenFlip() ;

	}//while( Process...

	DxLib_End() ;				// DXライブラリ使用の終了処理

	return 0 ;					// ソフトの終了

}//int WINAPI...


Re: 画像がデバッグ途中で消えてしまう

Posted: 2012年4月30日(月) 16:44
by みけCAT
GraphDraw関数内で毎回LoadDivGraphを使用して画像を読み込んでいるのが原因です。
image変数とimagemap変数はグローバルなので、
WinMain関数内の、DxLib_Init関数の呼び出しより後、ループに入る前に1度だけ読み込んでください。

Re: 画像がデバッグ途中で消えてしまう

Posted: 2012年4月30日(月) 16:54
by だんごさん
LoadDivGraphを関数の外に出しましょう。
そしてDxLib_Init(初期化)のあとにそれを張り付けましょう。
Loadはグラフィックデータをメモリに移す作業です。
つまりそれをwhile文で繰り返していると、メモリが足りなくなるというか
限界値になってしまって強制終了になるのです。

・・・私もそれで質問させてもらってたので・・・

Re: 画像がデバッグ途中で消えてしまう

Posted: 2012年4月30日(月) 20:58
by シラス
LoadDivGraphを外に出したところ、
終わらずに動いてくれました。
わかってしまえば、なんてあっけない…

お答えいただき、ありがとうございました。