マップスクロールについて

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

マップスクロールについて

#1

投稿記事 by ゆうたろう » 13年前

マップスクロールなんですが
これ→http://homepage2.nifty.com/natupaji/DxL ... am.html#N4
とこれ→http://dixq.net/g/26.html
を組み合わせただけのコードなんですが歩かせるとキャラの向きがおかしくなります
ご教授願います。。。

コード:

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

#define MAP_SIZE	32			// マップチップ一つのドットサイズ

#define MAP_WIDTH	20			// マップの幅
#define MAP_HEIGHT	16			// マップの縦長さ

#define MOVE_FRAME	16			// 移動にかけるフレーム数

// マップのデータ
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, 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 } ,
} ;
typedef struct{
        int x,y,img,muki,walking_flag;
}ch_t;
     ch_t ch;
// プレイヤーの位置
int PlayerX , PlayerY ;

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

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

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

// マップとプレイヤーの描画関数
void GraphDraw( int ScrollX, int ScrollY )
{
	int j , i ;
	int MapDrawPointX , MapDrawPointY ;		// 描画するマップ座標値
	int DrawMapChipNumX , DrawMapChipNumY ;	// 描画するマップチップの数

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

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

	// マップを描く
	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 )
			{
				DrawBox(j * MAP_SIZE + ScrollX,			i * MAP_SIZE + ScrollY,
					j * MAP_SIZE + MAP_SIZE + ScrollX,	i * MAP_SIZE + MAP_SIZE + ScrollY,
					GetColor( 255 , 0 , 0 ) , TRUE ) ;
			}
		}
	}

	// プレイヤーの描画

DrawGraph( ( PlayerX - MapDrawPointX ) * MAP_SIZE , ( PlayerY - MapDrawPointY ) * MAP_SIZE , ch.img , TRUE ) ;//画像を描画


}

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

	int image[16],i,j;
    char Key2[256];


    ch.x    =320;
    ch.y    =160;
    ch.walking_flag=0;
    ch.muki=3;

 

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

	// 描画先画面を裏画面にする
	SetDrawScreen( DX_SCREEN_BACK ) ;

	// プレイヤーの初期位置をセット
	PlayerX = 2 ;
	PlayerY = 2 ;

	// 最初は停止中(0)にしておく
	Move = 0 ;
    LoadDivGraph( "char.png" , 16 , 4 , 4 , 32 , 32 , image ) ;//画像を分割してimage配列に保存
	// ループ
	while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 )
	{
		// 画面を初期化
		ClearDrawScreen() ;

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

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

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

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

		// 移動中の場合は移動処理を行う
		if( Move == 1 )
		{
			MoveCounter ++ ;
   if     (ch.muki==0)        //上向きならch.y座標を減らす
                    ch.y--;
            else if(ch.muki==1)        //左向きならch.x座標を減らす
                    ch.x--;
            else if(ch.muki==2)        //下向きならch.y座標を増やす
                    ch.y++;
            else if(ch.muki==3)        //右向きならch.x座標を増やす
                    ch.x++;
			// 移動処理が終了したら停止中にする
			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 ) ;
			}
		}
     ch.img=image[(ch.x%32+ch.y%32)/8 + ch.muki*4];            //画像をセット
		// マップとプレイヤーを描画
		GraphDraw( ScrollX, ScrollY ) ;

       DrawFormatString( 0, 0, GetColor(255,255,255), "%d",(ch.x%32+ch.y%32)/8 + ch.muki*4 );
		// 裏画面の内容を表画面に映す
		ScreenFlip() ;
	}

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

	return 0 ;					// ソフトの終了
}

ゆうたろう

Re: マップスクロールについて

#2

投稿記事 by ゆうたろう » 13年前

すいません
#define MOVE_FRAME 32 としたらできました

ゆうたろう

Re: マップスクロールについて

#3

投稿記事 by ゆうたろう » 13年前

何度も申し訳ないですが
移動速度が遅くて気になるため
#define MOVE_FRAME 16 でちゃんとした向きになる方法を教えてください
よろしくお願いします

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

Re: マップスクロールについて

#4

投稿記事 by nil » 13年前

実際にこのコードで試したわけだはありませんし、
どのように不具合が発生するのかもわからないのですが、
このコードを見る限り、

位置フレームあたりの移動量を
1ではなくマップチップの大きさ/移動時間にする必要がありそうです。

ゆうたろう

Re: マップスクロールについて

#5

投稿記事 by ゆうたろう » 13年前

返答ありがとうございます
早歩き感はあるけど ch.img=image[(ch.x%16+ch.y%16)/4 + ch.muki*4]; とすればうまくできました
一応コード貼っときます

コード:

 

// マップスクロール基本
#include "DxLib.h"
 
#define MAP_SIZE    32          // マップチップ一つのドットサイズ
 
#define MAP_WIDTH   20          // マップの幅
#define MAP_HEIGHT  16          // マップの縦長さ
 
#define MOVE_FRAME  16          // 移動にかけるフレーム数
 
// マップのデータ
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, 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 } ,
} ;
typedef struct{
        int x,y,img,muki,walking_flag;
}ch_t;
     ch_t ch;
// プレイヤーの位置
int PlayerX , PlayerY ;
 
// 移動しているかどうかのフラグ( 0:停止中  1:移動中 )
int Move ;
 
// 各方向に移動する量
int MoveX, MoveY ;
 
// 移動し始めてから何フレーム経過したかを保持する変数
int MoveCounter ;
 
// マップとプレイヤーの描画関数
void GraphDraw( int ScrollX, int ScrollY )
{
    int j , i ;
    int MapDrawPointX , MapDrawPointY ;     // 描画するマップ座標値
    int DrawMapChipNumX , DrawMapChipNumY ; // 描画するマップチップの数
 
    // 描画するマップチップの数をセット
    DrawMapChipNumX = 640 / MAP_SIZE + 2 ;
    DrawMapChipNumY = 480 / MAP_SIZE + 2 ;
 
    // 画面左上に描画するマップ座標をセット
    MapDrawPointX = PlayerX - ( DrawMapChipNumX / 2 - 1 ) ;
    MapDrawPointY = PlayerY - ( DrawMapChipNumY / 2 - 1 ) ;
 
    // マップを描く
    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 )
            {
                DrawBox(j * MAP_SIZE + ScrollX,         i * MAP_SIZE + ScrollY,
                    j * MAP_SIZE + MAP_SIZE + ScrollX,  i * MAP_SIZE + MAP_SIZE + ScrollY,
                    GetColor( 255 , 0 , 0 ) , TRUE ) ;
            }
        }
    }
 
    // プレイヤーの描画
 
DrawGraph( ( PlayerX - MapDrawPointX ) * MAP_SIZE , ( PlayerY - MapDrawPointY ) * MAP_SIZE , ch.img , TRUE ) ;//画像を描画
 
 
}
 
// WinMain関数
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                         LPSTR lpCmdLine, int nCmdShow )
{
    int Key ;
    int ScrollX, ScrollY ;
 
    int image[16],i,j;
    char Key2[256];
 
 
    ch.x    =320;
    ch.y    =160;
    ch.walking_flag=0;
    ch.muki=3;
 
 
 
    SetGraphMode( 640 , 480 , 16 ) ;
    if( DxLib_Init() == -1 )    // DXライブラリ初期化処理
    {
         return -1;             // エラーが起きたら直ちに終了
    }
 
    // 描画先画面を裏画面にする
    SetDrawScreen( DX_SCREEN_BACK ) ;
 
    // プレイヤーの初期位置をセット
    PlayerX = 2 ;
    PlayerY = 2 ;
 
    // 最初は停止中(0)にしておく
    Move = 0 ;
    LoadDivGraph( "char.png" , 16 , 4 , 4 , 32 , 32 , image ) ;//画像を分割してimage配列に保存
    // ループ
    while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 )
    {
        // 画面を初期化
        ClearDrawScreen() ;
 
        // 移動中ではない場合キー入力を受け付ける
        if( Move == 0 )
        {
            // キー入力を得る
            Key = GetJoypadInputState( DX_INPUT_KEY_PAD1 ) ;
 
            // キー入力に応じてプレイヤーの座標を移動
            if( Key & PAD_INPUT_LEFT )
            {
                Move = 1 ;
                MoveX = -1 ;
                MoveY = 0 ; ch.muki=1;
            }
            if( Key & PAD_INPUT_RIGHT )
            {
                Move = 1 ;
                MoveX = 1 ;
                MoveY = 0 ;ch.muki=3; 
            }
            if( Key & PAD_INPUT_UP )
            {
                Move = 1 ;
                MoveX = 0 ;
                MoveY = -1 ;ch.muki=0;
            }
            if( Key & PAD_INPUT_DOWN )
            {
                Move = 1 ;
                MoveX = 0 ;
                MoveY = 1 ;ch.muki=2; 
            }
 
            // 進入不可能なマップだった場合は移動できない
            if( Move == 1 )
            {
                if( MapData[ PlayerY + MoveY ][ PlayerX + MoveX ] == 0 )
                {
                    Move = 0 ;
                }
                else
                {
                    MoveCounter = 0 ;
                }
            }
 
            // 停止中は画面のスクロールは行わない
            ScrollX = 0 ;
            ScrollY = 0 ;
        }
 
        // 移動中の場合は移動処理を行う
        if( Move == 1 )
        {
            MoveCounter ++ ;
   if     (ch.muki==0)        //上向きならch.y座標を減らす
                    ch.y--;
            else if(ch.muki==1)        //左向きならch.x座標を減らす
                    ch.x--;
            else if(ch.muki==2)        //下向きならch.y座標を増やす
                    ch.y++;
            else if(ch.muki==3)        //右向きならch.x座標を増やす
                    ch.x++;
            // 移動処理が終了したら停止中にする
            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 ) ;
            }
        }
     ch.img=image[(ch.x%16+ch.y%16)/4 + ch.muki*4];            //画像をセット
        // マップとプレイヤーを描画
        GraphDraw( ScrollX, ScrollY ) ;
 		DrawFormatString( 0, 0, GetColor(0,0,255), "%d",(ch.x%16+ch.y%16)/4+ ch.muki*4 );
        DrawFormatString( 0, 20, GetColor(0,0,255), "ch.x%d",ch.x);
        DrawFormatString( 0, 40, GetColor(0,0,255), "(ch.x%32)%d",ch.x%32);   

 
        // 裏画面の内容を表画面に映す
        ScreenFlip() ;
    }
 
    DxLib_End() ;               // DXライブラリ使用の終了処理
 
    return 0 ;                  // ソフトの終了
}

 

閉鎖

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