ページ 11

スクロールの考え方

Posted: 2011年9月23日(金) 12:47
by big
今スクロールゲームを作ろうと思っていますが、スクロールができなくて困ってます。
http://homepage2.nifty.com/natupaji/DxLib/ここのサイトを参考にいろいろやってみたのですがなかなかうまくいかずにできません。自分はVisual Studio 2010 Express を使っていてC言語でやっています。
以下のコードにスクロールを加えるにはどのようにしたらいいのですか?

コード:

#include "DxLib.h"

#define SCREEN_X	(640)
#define SCREEN_Y	(480)
#define MAPSIZE_X	(32*(20*2))								//横マップサイズの長さ
#define MAPSIZE_Y	(480)									//縦マップサイズの長さ
#define CHIPSIZE	(32)									//一つのブロックサイズ
#define MAP_WIDTH	(MAPSIZE_X/CHIPSIZE)					//横のブロックの数
#define MAP_HEIGHT	(MAPSIZE_Y/CHIPSIZE)					//縦のブロックの数

int mapdate[MAP_HEIGHT][MAP_WIDTH] = {
	{ 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
	{ 0,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, 1,1,1,1,1, 0,0,0,0,0 },
	{ 0,0,0,0,0, 0,0,0,0,0, 0,0,1,0,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
	{ 0,0,0,0,1, 1,0,0,0,0, 0,0,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
	{ 0,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, 1,1,1,1,1, 0,0,0,0,0 },

	{ 0,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, 1,1,1,1,1, 0,0,0,0,0 },
	{ 0,0,0,0,0, 0,0,0,1,1, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 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,0,0,0,0, 1,1,1,1,1, 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,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
	{ 0,0,0,0,1, 0,0,0,0,0, 0,0,0,0,1, 0,0,1,0,0, 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, 0,0,0,0,0, 0,0,1,1,1, 0,0,0,1,1, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
	{ 0,0,0,0,1, 0,0,1,1,0, 0,0,1,1,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
	{ 0,0,0,0,1, 0,0,1,1,0, 0,0,1,1,0, 0,1,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
	{ 1,1,0,0,0, 0,0,1,1,0, 0,0,1,1,0, 0,1,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
	{ 1,1,1,1,1, 1,1,1,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,1,1,1,1 },
};

int zikiX , zikiY ;								//自機の座標
int zikiGraph[7];								//自機のイメージ
bool muki = TRUE;								//自機の向き
int jumpP;										//ジャンプパワー
int jumpF;										//ジャンプフラグ
int chip;										//一つのブロックのイメージ
int haikei;										//背景
int i , j ;

//----------------------------------------------------------------------------------
int Key[256];
 
int GetHitKeyStateAll_2(int GetHitKeyStateAll_InputKey[]){
    char GetHitKeyStateAll_Key[256];
    GetHitKeyStateAll( GetHitKeyStateAll_Key );
    for(int i=0;i<256;i++){
        if(GetHitKeyStateAll_Key[i]==1) GetHitKeyStateAll_InputKey[i]++;
        else                            GetHitKeyStateAll_InputKey[i]=0;
    }
    return 0;
}//----------------------------------------------------------------------------------
 
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
    ChangeWindowMode(TRUE);//ウィンドウモード
    if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化

	//自機の保存と初期化
	LoadDivGraph("zikiA.png",7,7,1,32,32,zikiGraph);
	chip = LoadGraph("renga.png");
	haikei = LoadGraph("haikei.bmp");
	zikiX = 126;
	zikiY = 415;
	jumpP = 0;
	jumpF = 0;

    while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
          //↑メッセージ処理          ↑画面をクリア           ↑入力状態を保存       ↑ESCが押されていない
		//背景の描画
		DrawGraph(0,0,haikei, FALSE);

		//マップ描画
		for( i = 0 ; i < SCREEN_Y ; i++ ){
			for( j = 0 ; j < SCREEN_X ; j++ ){
				if(mapdate[i][j] == 1)
					DrawGraph( j*32 , i*32 , chip , FALSE);
			}
		}
		
		//ジャンプ中か否か
		if(mapdate[(zikiY+33)/32][(zikiX+8)/32] != 0
			||mapdate[(zikiY+33)/32][(zikiX+26)/32] != 0){
			jumpF = 0;
			jumpP = 0;
		}else{
			jumpF = 1;
		}
		
		//ジャンプの処理
		if( Key[KEY_INPUT_Z] == 1 && jumpF == 0 )jumpP = 17;

		//落下処理
			zikiY -= jumpP;
			jumpP -= 1;
			if(jumpP <= -10)jumpP = -10;

		//自機の操作
		if( Key[KEY_INPUT_RIGHT] != 0){//右キーを押して壁がなかったら座標を+5する
			if(mapdate[(zikiY+8)/32][(zikiX+32)/32] == 0
				||mapdate[(zikiY+26)/32][(zikiX+32)/32] == 0)
			zikiX += 5;
			muki = TRUE;
		}
		if( Key[KEY_INPUT_LEFT] != 0){//左キーを押して壁がなかったら座標を-5する
			if(mapdate[(zikiY+8)/32][zikiX/32] == 0
				||mapdate[(zikiY+26)/32][zikiX/32] == 0)
			zikiX -= 5;
			muki = FALSE;
		}
		
		//床の当たり判定
		if( jumpP <= -1 ){
			if(mapdate[(zikiY+33)/32][(zikiX+8)/32] != 0
				|| mapdate[(zikiY+33)/32][(zikiX+26)/32] != 0){
				zikiY = ((zikiY+33)/32)*32-33;
				jumpF = 0;
			}
		}
		//上(天井)の当たり判定
		if( jumpP >= 0 ){
			if(mapdate[(zikiY-1)/32][(zikiX+8)/32] != 0 
				|| mapdate[(zikiY-1)/32][(zikiX+26)/32] != 0){
				zikiY = (zikiY/32)*32+33-1;
				jumpP = 0;
			}
		}
		//左の壁の当たり判定
		if(mapdate[(zikiY+8)/32][zikiX/32] != 0
			|| mapdate[(zikiY+26)/32][zikiX/32] != 0){
				zikiX = ((zikiX)/32)*32+31;
		}
		//右の壁の当たり判定
		if(mapdate[(zikiY+8)/32][(zikiX+32)/32] != 0
			|| mapdate[(zikiY+26)/32][(zikiX+32)/32] != 0){
				zikiX = ((zikiX+33)/32)*32-32;
		}
		//落下中にめり込まないようにする
		if(jumpF == 1 && jumpP < 0){
			if(mapdate[(zikiY+33)/32][(zikiX+8)/32] != 0
				||mapdate[(zikiY+33)/32][(zikiX+26)/32] != 0){
				jumpP = 0;
				jumpF = 0;
			}
		}
		if(jumpF == 1)DrawString(0,0,"jumpF 1",GetColor(255,0,0));
		else DrawString(0,0,"jumpF 0",GetColor(255,0,0));
		//自機描画
		if(muki == FALSE){
			DrawTurnGraph(zikiX,zikiY,zikiGraph[0],TRUE);
		}else{
			if(muki == TRUE){
				DrawGraph(zikiX,zikiY,zikiGraph[0],TRUE);
			}
		}


        ScreenFlip();
    }
 
    DxLib_End();
    return 0;
}

Re: スクロールの考え方

Posted: 2011年9月23日(金) 14:03
by softya(ソフト屋)
ここは参考にされましたか?
「DXライブラリ置き場 サンプルプログラム」
http://homepage2.nifty.com/natupaji/DxL ... am.html#N4

Re: スクロールの考え方

Posted: 2011年9月23日(金) 19:51
by big
返事が遅れました。
以前サイトに書いてあるプログラムを真似してやってみたのですが、マップの描画ができなかったり自機が真ん中で移動しなくなってしまったりとしてわからなくなってしまいました。真似したコードを掲載します。

コード:

#include "DxLib.h"

#define SCREEN_X	(640)
#define SCREEN_Y	(480)
#define MAPSIZE_X	(32*(20*4))								//横マップサイズの長さ
#define MAPSIZE_Y	(480)									//縦マップサイズの長さ
#define CHIPSIZE	(32)									//一つのブロックサイズ
#define MAP_WIDTH	(MAPSIZE_X/CHIPSIZE)					//横のブロックの数
#define MAP_HEIGHT	(MAPSIZE_Y/CHIPSIZE)					//縦のブロックの数

int mapdate[MAP_HEIGHT][MAP_WIDTH] = {
	{ 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
	{ 0,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, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
	{ 0,0,0,0,0, 0,0,0,0,0, 0,0,1,0,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
	{ 0,0,0,0,1, 1,0,0,0,0, 0,0,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
	{ 0,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, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },

	{ 0,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, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
	{ 0,0,0,0,0, 0,0,0,1,1, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 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,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 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,0,0,0,0, 1,1,1,1,1, 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,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
	{ 0,0,0,0,1, 0,0,0,0,0, 0,0,0,0,1, 0,0,1,0,0, 0,0,0,0,0, 0,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, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },

	{ 0,0,0,0,1, 0,0,0,0,0, 0,0,1,1,1, 0,0,0,1,1, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,1,0,0,0 },
	{ 0,0,0,0,1, 0,0,1,1,0, 0,0,1,1,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 1,1,0,0,0 },
	{ 0,0,0,0,1, 0,0,1,1,0, 0,0,1,1,0, 0,1,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,1,0,0,0 },
	{ 1,1,0,0,0, 0,0,1,1,0, 0,0,1,1,0, 0,1,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,1,0,0,0 },
	{ 1,1,1,1,1, 1,1,1,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,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,0,0 },
};

int zikiX , zikiY ;								//自機の座標
int zikiGraph[7];								//自機のイメージ
bool muki = TRUE;								//自機の向き
int jumpP;										//ジャンプパワー
int jumpF;										//ジャンプフラグ
int chip;										//一つのブロックのイメージ
int haikei;										//背景
int i , j ;
void GraphDraw( void )
{
	int j , i ;
	int MapDrawPointX , MapDrawPointY ;		// 描画するマップ座標値
	int DrawMapChipNumX , DrawMapChipNumY ;	// 描画するマップチップの数
	
	// 描画するマップチップの数をセット
	DrawMapChipNumX = 640 / CHIPSIZE + 1 ;
	DrawMapChipNumY = 480 / CHIPSIZE + 1 ;

	// 画面左上に描画するマップ座標をセット
	MapDrawPointX = zikiX - DrawMapChipNumX / 2 ;
	MapDrawPointY = zikiY - DrawMapChipNumY / 2 ;

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

			// マップデータが0だったら四角を描画する
			if( mapdate[ i + MapDrawPointY ][ j + MapDrawPointX ] == 1 )
			{
				DrawGraph( j * CHIPSIZE , i * CHIPSIZE , chip , FALSE) ;
			}
		}
	}

	// プレイヤーの描画
	if(muki==TRUE)DrawGraph( ( zikiX - MapDrawPointX ) * CHIPSIZE , ( zikiY - MapDrawPointY ) * CHIPSIZE , zikiGraph[0], TRUE);
	if(muki==FALSE)DrawTurnGraph(( zikiX - MapDrawPointX ) * CHIPSIZE , ( zikiY - MapDrawPointY ) * CHIPSIZE , zikiGraph[0], TRUE);
}

//----------------------------------------------------------------------------------
int Key[256];
 
int GetHitKeyStateAll_2(int GetHitKeyStateAll_InputKey[]){
    char GetHitKeyStateAll_Key[256];
    GetHitKeyStateAll( GetHitKeyStateAll_Key );
    for(int i=0;i<256;i++){
        if(GetHitKeyStateAll_Key[i]==1) GetHitKeyStateAll_InputKey[i]++;
        else                            GetHitKeyStateAll_InputKey[i]=0;
    }
    return 0;
}//----------------------------------------------------------------------------------
 
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
    ChangeWindowMode(TRUE);//ウィンドウモード
    if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化

	//自機の保存と初期化
	LoadDivGraph("zikiA.png",7,7,1,32,32,zikiGraph);
	chip = LoadGraph("renga.png");
	haikei = LoadGraph("haikei.bmp");
	zikiX = 126;
	zikiY = 415;
	jumpP = 0;
	jumpF = 0;

    while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
          //↑メッセージ処理          ↑画面をクリア           ↑入力状態を保存       ↑ESCが押されていない
		//背景の描画
		DrawGraph(0,0,haikei, FALSE);

		
		//ジャンプ中か否か
		if(mapdate[(zikiY+33)/32][(zikiX+8)/32] != 0
			||mapdate[(zikiY+33)/32][(zikiX+26)/32] != 0){
			jumpF = 0;
			jumpP = 0;
		}else{
			jumpF = 1;
		}
		
		//ジャンプの処理
		if( Key[KEY_INPUT_Z] == 1 && jumpF == 0 )jumpP = 17;

		//落下処理
			zikiY -= jumpP;
			jumpP -= 1;
			if(jumpP <= -10)jumpP = -10;

		//自機の操作
		if( Key[KEY_INPUT_RIGHT] != 0){//右キーを押して壁がなかったら座標を+5する
			if(mapdate[(zikiY+8)/32][(zikiX+32)/32] == 0
				||mapdate[(zikiY+26)/32][(zikiX+32)/32] == 0)
			zikiX += 5;
			muki = TRUE;
		}
		if( Key[KEY_INPUT_LEFT] != 0){//左キーを押して壁がなかったら座標を-5する
			if(mapdate[(zikiY+8)/32][zikiX/32] == 0
				||mapdate[(zikiY+26)/32][zikiX/32] == 0)
			zikiX -= 5;
			muki = FALSE;
		}
		
		//床の当たり判定
		if( jumpP <= -1 ){
			if(mapdate[(zikiY+33)/32][(zikiX+8)/32] != 0
				|| mapdate[(zikiY+33)/32][(zikiX+26)/32] != 0){
				zikiY = ((zikiY+33)/32)*32-33;
				jumpF = 0;
			}
		}
		//上(天井)の当たり判定
		if( jumpP >= 0 ){
			if(mapdate[(zikiY-1)/32][(zikiX+8)/32] != 0 
				|| mapdate[(zikiY-1)/32][(zikiX+26)/32] != 0){
				zikiY = (zikiY/32)*32+33-1;
				jumpP = 0;
			}
		}
		//左の壁の当たり判定
		if(mapdate[(zikiY+8)/32][zikiX/32] != 0
			|| mapdate[(zikiY+26)/32][zikiX/32] != 0){
				zikiX = ((zikiX)/32)*32+31;
		}
		//右の壁の当たり判定
		if(mapdate[(zikiY+8)/32][(zikiX+32)/32] != 0
			|| mapdate[(zikiY+26)/32][(zikiX+32)/32] != 0){
				zikiX = ((zikiX+33)/32)*32-32;
		}
		//落下中にめり込まないようにする
		if(jumpF == 1 && jumpP < 0){
			if(mapdate[(zikiY+33)/32][(zikiX+8)/32] != 0
				||mapdate[(zikiY+33)/32][(zikiX+26)/32] != 0){
				jumpP = 0;
				jumpF = 0;
			}
		}
		if(jumpF == 1)DrawString(0,0,"jumpF 1",GetColor(255,0,0));
		else DrawString(0,0,"jumpF 0",GetColor(255,0,0));
		GraphDraw();


        ScreenFlip();
    }
 
    DxLib_End();
    return 0;
}

Re: スクロールの考え方

Posted: 2011年9月23日(金) 22:16
by softya(ソフト屋)
動作を確認したいので画像データもいただけると幸いです。
どこかのアップローダにアップしていただけないでしょうか?

Re: スクロールの考え方

Posted: 2011年9月24日(土) 13:34
by big
http://xfs.jp/Duxwrこれが自機の画像
http://xfs.jp/Lxm2Hこれがブロックの画像
http://xfs.jp/s50uzこれが背景の画像です。
絵がへたくそですがよろしくお願いします。

Re: スクロールの考え方

Posted: 2011年9月25日(日) 12:37
by softya(ソフト屋)
ここの計算式ですが、
MapDrawPointX = zikiX - DrawMapChipNumX / 2 ;
zikiX はピクセル単位ですが、MapDrawPointX とDrawMapChipNumX はマップチップサイズだと思いますので単位が混在しています。zikiX をマップチップサイズに変換しましょう。

それとデバッガやDrawFormatStringを駆使すれば、状態を確認できますので積極的に確認しましょう。
たとえば、
DrawFormatString( 0,16,GetColor(16,16,16),"MapDrawPoint(%d,%d)", MapDrawPointX,MapDrawPointY );
で MapDrawPointX,MapDrawPointY の値が確認できます。

これで完璧に直るわけではないですが、まずマップチップが表示できるところまで。

Re: スクロールの考え方

Posted: 2011年9月25日(日) 18:41
by big
softyaさんありがとうございます。マップ表示とスクロールはできたのですが、スクロールが少しおかしくて(マップ全体のサイズよりもスクロールしたり)あたり判定なども一マスずれてたりなどして、いろいろやってみたのですがなかなかうまくいかないです。
一応ソースを貼っておきます。

コード:

#include "DxLib.h"
 
#define SCREEN_X    (640)
#define SCREEN_Y    (480)
#define MAPSIZE_X   (32*(20*4))                             //横マップサイズの長さ
#define MAPSIZE_Y   (480)                                   //縦マップサイズの長さ
#define CHIPSIZE    (32)                                    //一つのブロックサイズ
#define MAP_WIDTH   (MAPSIZE_X/CHIPSIZE)                    //横のブロックの数
#define MAP_HEIGHT  (MAPSIZE_Y/CHIPSIZE)                    //縦のブロックの数
 
int mapdate[MAP_HEIGHT][MAP_WIDTH] = {
    { 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
    { 0,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, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
    { 0,0,0,0,0, 0,0,0,0,0, 0,0,1,0,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
    { 0,0,0,0,1, 1,0,0,0,0, 0,0,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
    { 0,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, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
 
    { 0,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, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
    { 0,0,0,0,0, 0,0,0,1,1, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 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,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 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,0,0,0,0, 1,1,1,1,1, 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,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
    { 0,0,0,0,1, 0,0,0,0,0, 0,0,0,0,1, 0,0,1,0,0, 0,0,0,0,0, 0,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, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0 },
 
    { 0,0,0,0,1, 0,0,0,0,0, 0,0,1,1,1, 0,0,0,1,1, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,1,0,0,0 },
    { 0,0,0,0,1, 0,0,1,1,0, 0,0,1,1,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 1,1,0,0,0 },
    { 0,0,0,0,1, 0,0,1,1,0, 0,0,1,1,0, 0,1,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,1,0,0,0 },
    { 1,1,0,0,0, 0,0,1,1,0, 0,0,1,1,0, 0,1,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,1,0,0,0 },
    { 1,1,1,1,1, 1,1,1,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,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,0,0 },
};
 
int zikiX , zikiY;                             //自機の座標
int zikiGraph[7];                               //自機のイメージ
bool muki = TRUE;                               //自機の向き
int jumpP;                                      //ジャンプパワー
int jumpF;                                      //ジャンプフラグ
int chip;                                       //一つのブロックのイメージ
int haikei;                                     //背景
int i , j ;
void GraphDraw( void )
{
    int j , i ;
    int MapDrawPointX , MapDrawPointY ;     // 描画するマップ座標値
    int DrawMapChipNumX , DrawMapChipNumY ; // 描画するマップチップの数
    
    // 描画するマップチップの数をセット
    DrawMapChipNumX = 640 / CHIPSIZE + 1 ;
    DrawMapChipNumY = 480 / CHIPSIZE + 1 ;
 
    // 画面左上に描画するマップ座標をセット
    MapDrawPointX = (zikiX/CHIPSIZE) - DrawMapChipNumX / 2 ;			//ここを変えてみました
    MapDrawPointY = (zikiY/CHIPSIZE) - DrawMapChipNumY / 2 ;
 
    // マップを描く
    for( i = 0 ; i < DrawMapChipNumY ; i ++ )
    {
        for( j = 0 ; j < DrawMapChipNumX ; j ++ )
        {
            // 画面からはみ出た位置なら描画しない
            if( j + MapDrawPointX < 0 || i + MapDrawPointY < 0 ||
                j + MapDrawPointX >= MAP_WIDTH || i + MapDrawPointY >= MAP_HEIGHT ) continue ;
 
            // マップデータが0だったら四角を描画する
            if( mapdate[ i + MapDrawPointY ][ j + MapDrawPointX ] == 1 )
            {
                DrawGraph( j * CHIPSIZE , i * CHIPSIZE , chip , FALSE) ;
            }
        }
    }
 
    // プレイヤーの描画			↓これの/32を消すと自機が表示されなくなります
    if(muki==TRUE)DrawGraph( ( (zikiX/32) - MapDrawPointX ) * CHIPSIZE , ( (zikiY/32) - MapDrawPointY ) * CHIPSIZE , zikiGraph[0], TRUE);
    if(muki==FALSE)DrawTurnGraph(( (zikiX/32) - MapDrawPointX ) * CHIPSIZE , ( (zikiY/32) - MapDrawPointY ) * CHIPSIZE , zikiGraph[0], TRUE);
}
 
//----------------------------------------------------------------------------------
int Key[256];
 
int GetHitKeyStateAll_2(int GetHitKeyStateAll_InputKey[]){
    char GetHitKeyStateAll_Key[256];
    GetHitKeyStateAll( GetHitKeyStateAll_Key );
    for(int i=0;i<256;i++){
        if(GetHitKeyStateAll_Key[i]==1) GetHitKeyStateAll_InputKey[i]++;
        else                            GetHitKeyStateAll_InputKey[i]=0;
    }
    return 0;
}//----------------------------------------------------------------------------------
 
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
    ChangeWindowMode(TRUE);//ウィンドウモード
    if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化
 
    //自機の保存と初期化
    LoadDivGraph("zikiA.png",7,7,1,32,32,zikiGraph);
    chip = LoadGraph("renga.png");
    haikei = LoadGraph("haikei.bmp");
    zikiX = 2;
    zikiY = 2;
    jumpP = 0;
    jumpF = 0;
 
    while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
          //↑メッセージ処理          ↑画面をクリア           ↑入力状態を保存       ↑ESCが押されていない
        //背景の描画
        DrawGraph(0,0,haikei, FALSE);
 
        
        //ジャンプ中か否か
        if(mapdate[(zikiY+33)/32][(zikiX+8)/32] != 0
            ||mapdate[(zikiY+33)/32][(zikiX+26)/32] != 0){
            jumpF = 0;
            jumpP = 0;
        }else{
            jumpF = 1;
        }
        
        //ジャンプの処理
        if( Key[KEY_INPUT_Z] == 1 && jumpF == 0 )jumpP = 17;
 
        //落下処理
            zikiY -= jumpP;
            jumpP -= 1;
            if(jumpP <= -10)jumpP = -10;
 
        //自機の操作
        if( Key[KEY_INPUT_RIGHT] != 0){//右キーを押して壁がなかったら座標を+5する
            if(mapdate[(zikiY+8)/32][(zikiX+32)/32] == 0
                ||mapdate[(zikiY+26)/32][(zikiX+32)/32] == 0)
            zikiX += 5;
            muki = TRUE;
        }
        if( Key[KEY_INPUT_LEFT] != 0){//左キーを押して壁がなかったら座標を-5する
            if(mapdate[(zikiY+8)/32][zikiX/32] == 0
                ||mapdate[(zikiY+26)/32][zikiX/32] == 0)
            zikiX -= 5;
            muki = FALSE;
        }
        
        //床の当たり判定
        if( jumpP <= -1 ){
            if(mapdate[(zikiY+33)/32][(zikiX+8)/32] != 0
                || mapdate[(zikiY+33)/32][(zikiX+26)/32] != 0){
                zikiY = ((zikiY+33)/32)*32-33;
                jumpF = 0;
            }
        }
        //上(天井)の当たり判定
        if( jumpP >= 0 ){
            if(mapdate[(zikiY-1)/32][(zikiX+8)/32] != 0 
                || mapdate[(zikiY-1)/32][(zikiX+26)/32] != 0){
                zikiY = (zikiY/32)*32+33-1;
                jumpP = 0;
            }
        }
        //左の壁の当たり判定
        if(mapdate[(zikiY+8)/32][zikiX/32] != 0
            || mapdate[(zikiY+26)/32][zikiX/32] != 0){
                zikiX = ((zikiX)/32)*32+31;
        }
        //右の壁の当たり判定
        if(mapdate[(zikiY+8)/32][(zikiX+32)/32] != 0
            || mapdate[(zikiY+26)/32][(zikiX+32)/32] != 0){
                zikiX = ((zikiX+33)/32)*32-32;
        }
        //落下中にめり込まないようにする
        if(jumpF == 1 && jumpP < 0){
            if(mapdate[(zikiY+33)/32][(zikiX+8)/32] != 0
                ||mapdate[(zikiY+33)/32][(zikiX+26)/32] != 0){
                jumpP = 0;
                jumpF = 0;
            }
        }
        if(jumpF == 1)DrawString(0,0,"jumpF 1",GetColor(255,0,0));
        else DrawString(0,0,"jumpF 0",GetColor(255,0,0));
        GraphDraw();
 
 
        ScreenFlip();
    }
 
    DxLib_End();
    return 0;
}

Re: スクロールの考え方

Posted: 2011年9月25日(日) 22:02
by softya(ソフト屋)
余りにも直値が多かったのとピクセル単位とマップパーツ単位の混在が見られるのたのでだいぶ直しました。
それと一度変数に格納することでプログラムがすっきりしてバグの原因を追求しやすくなります。参考にしてください。
今はデバッグ用にパーツの座標を表示させています。

残りのソースの部分ももっと直値がなくなればすっきりしますよ。

コード:

void GraphDraw( void )
{
    int j , i ;
    int MapDrawPointX , MapDrawPointY ;     // 描画するマップ座標値
    int DrawMapChipNumX , DrawMapChipNumY ; // 描画するマップチップの数
    
    // 描画するマップチップの数をセット
    DrawMapChipNumX = 640 / CHIPSIZE + 1 ;
    DrawMapChipNumY = 480 / CHIPSIZE + 1 ;
 
    // 画面左上に描画するマップ座標をセット
    int MapDrawPointPixelX = zikiX - DrawMapChipNumX/2*CHIPSIZE;
    int MapDrawPointPixelY = zikiY - DrawMapChipNumY/2*CHIPSIZE;
    MapDrawPointX = MapDrawPointPixelX / CHIPSIZE;
    MapDrawPointY = MapDrawPointPixelY / CHIPSIZE;
    int ofsx = MapDrawPointPixelX % CHIPSIZE;
    int ofsy = MapDrawPointPixelY % CHIPSIZE;

	//	フォントサイズを小さく。デバッグ用。
	int oldsize = GetFontSize();
	SetFontSize( 9 );
 
    // マップを描く
    for( i = 0 ; i < DrawMapChipNumY ; i ++ )
    {
		int mapy = i + MapDrawPointY;
		
        for( j = 0 ; j < DrawMapChipNumX ; j ++ )
        {
			int mapx = j + MapDrawPointX;
			
            // 画面からはみ出た位置なら描画しない
            if( mapx < 0 || mapy < 0 ||
                mapx >= MAP_WIDTH || mapy >= MAP_HEIGHT ) continue ;
 
            // マップデータが1だったらマップパーツを描画する
            int drawx = j * CHIPSIZE - ofsx;
            int drawy = i * CHIPSIZE - ofsy;
            if( mapdate[ mapy ][ mapx ] == 1 )
            {
                DrawGraph( drawx, drawy , chip , FALSE) ;
            } else {
				//	パーツのない空間はデバッグ用にパーツ座標を表示。
				DrawFormatString( drawx, drawy +CHIPSIZE/2 , GetColor(255,0,0), "(%d,%d)", mapx, mapy );
			}
        }
    }
	//	フォントサイズを戻す。デバッグ用。
	SetFontSize( oldsize );
 
    // プレイヤーの描画
    if(muki==TRUE)DrawGraph( ( zikiX - MapDrawPointPixelX ) , ( zikiY - MapDrawPointPixelY ) , zikiGraph[0], TRUE);
    if(muki==FALSE)DrawTurnGraph(( zikiX - MapDrawPointPixelX ) , ( zikiY - MapDrawPointPixelY ) , zikiGraph[0], TRUE);
}

Re: スクロールの考え方

Posted: 2011年9月25日(日) 22:55
by big
softyaさんありがとうございます!
ソースコードを見て勉強させていただきます。
変数に格納することを教えていただきありがとうございます。参考にさせてもらいます。