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

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

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

#1

投稿記事 by atci98 » 8年前

表示画面とキャラの移動を同時に動かす方法が分かりません。
http://homepage2.nifty.com/natupaji/DxL ... ogram.html
ここのサイトを参考にしたのですが、自分のプログラムではマップチップではなく一枚絵のマップを使いたいのく、マップは毎回For文で四角を描画するんだなと分かりましたが、プレイヤーの描画場所は?で、いまいち応用の仕方が理解できませんでした。
色々検索をかけてみて、今度はSetDrawArea()という関数を見つけたので試してみたところ、
表示画面は動かずにキャラとマップだけがどこかに行ってしまいました。

そこで、一枚絵の場合、どのように動かせばいいのか教えていただけませんでしょうか?
マップチップに変えるべきでしょうか?
もしくは、先ほどはったURL先のマップスクロール内でのプログラムにつきまして、プレイヤーである白い四角が真ん中に来るようになるとあるのですが、その方法を詳しく教えてくださいませんでしょうか?

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

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

#2

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

一枚絵を上下左右に動かすことが出来るのなら何の問題もなく出来ると思います。
キャラクタは画面上の固定位置で良いんですよね?
ただ、地形との当たり判定や前後関係は面倒かもしれません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

atci98
記事: 17
登録日時: 8年前

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

#3

投稿記事 by atci98 » 8年前

どうにかキャラを画面中央のままにして、例えるなら、画面は640×480で、表示画面の左上座標はキャラX-320,キャラY-240で、
右下の座標が、キャラX+320,キャラY+240・・・という感じかなぁ?と思っています。

DrawGraphだと、上の座標を入力しても、その座標から画像を張るので、移動している感じにはならないだろうなぁ~と考えているのですが。

一体どんな関数使えば出来そうですか?

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

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

#4

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

どういう想定をしているかよく分かりませんが、DrawGraphで座標を変更すれば良いだけです。
なぜ、キャラクタからマップへの相対座標が固定である必要があるのでしょうか?
1.実験したりしてますか?
2.頭のなかだけで考えてませんか?

そもそもスクロールするマップ画像なら、画面サイズ640x480よりも遥かに大きいはずでよね?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

atci98
記事: 17
登録日時: 8年前

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

#5

投稿記事 by atci98 » 8年前

キャラが中心だからこうなのかなと思いました。
自分のプログラムは

コード:

int MapDrawPointX ,MapDrawPointY;
	MapDrawPointX = x - 320;
	MapDrawPointY = y - 240;
		if(MapDrawPointX < 0 && MapDrawPointY < 0){
			DrawGraph(0,0,img_board[1],TRUE);
		}	else if	(MapDrawPointX < 0){
			DrawGraph(0,y-240,img_board[1],TRUE);
		}	else if (MapDrawPointY < 0){
			DrawGraph(40,0,img_board[1],TRUE);
		}	else if (MapDrawPointX >= 40){
			DrawGraph(40,y-240,img_board[1],TRUE);
		}	else if (MapDrawPointY >= 370){
			DrawGraph(x-320,370,img_board[1],TRUE);
		}	else if (MapDrawPointX >= 40 && MapDrawPointY >= 370){
			DrawGraph(40,370,img_board[1],TRUE);
		}	else {
			DrawGraph(x-320,y-240,img_board[1],TRUE);
		}
が思いつくマッププログラム・・・なのですが。
さっき言ったようにその座標から、マップの一番左上が新しく表示され、640×480の画面は動かなくて、キャラと画像だけがどこかに行ってしまいます。
全くわからないもので・・・どうすればいいでしょうか。

アバター
usao
記事: 1887
登録日時: 11年前

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

#6

投稿記事 by usao » 8年前

ダイレクトにごちゃごちゃと式を書かずに,
・"広大なマップ"の左上を原点(0,0)とする「マップ座標系」
・"表示域(ウィンドウのクライアント領域かな)"の左上を原点(0,0)とする「表示座標系」
みたいなのを考えて,
その間の変換を関数にでもしたらすっきりしませんか.

例えば,表示域に現在表示すべきマップの範囲を得たい場合には
表示座標系での(0,0)と(639,479)を,マップ座標系に変換すればいいですよね.

キャラクタの描画位置についても,キャラクタの現在位置がマップ座標系での値として保持されているならば
それを表示座標系に変換すれば,どこに描画すればよいのかが得られますよね.

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

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

#7

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

図に書くと分かりやすいんですんけどね。
適当すぎる絵なんで、自分になりに工夫してください。
てきとう.png
てきとう.png (17.34 KiB) 閲覧数: 5035 回
数学と呼べるほどのものじゃないんですが。
マップ画像上の主人公の座標(x,y)があるとして、主人公の画面左上からの相対座標(x2,y2)が固定であるなら、マップ画像の左上の座標は、簡単な式で計算できますね。書き出してみてください。

【補足】マップ端とかで主人公が画面真ん中で無くなる処理は、主人公が画面真ん中でスクロール出来る基本的なことが出来たら考えていください。時期尚早です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

atci98
記事: 17
登録日時: 8年前

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

#8

投稿記事 by atci98 » 8年前

うーん・・・・・・。
考え方は分かるのですが、プログラムの描き方が分かりません。
今から乗せるのは一番最初に張ったURL先のマップスクロールのサンプルプログラムなのですが、

コード:

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

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

#define MAP_WIDTH	20			// マップの幅
#define MAP_HEIGHT	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 } ,
} ;

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

// マップとプレイヤーの描画関数
void GraphDraw( void )
{
	int j , i ;
	int MapDrawPointX , MapDrawPointY ;		// 描画するマップ座標値
	int DrawMapChipNumX , DrawMapChipNumY ;	// 描画するマップチップの数
	
	// 描画するマップチップの数をセット
	DrawMapChipNumX = 640 / MAP_SIZE + 1 ;
	DrawMapChipNumY = 480 / MAP_SIZE + 1 ;

	// 画面左上に描画するマップ座標をセット
	MapDrawPointX = PlayerX - DrawMapChipNumX / 2 ;
	MapDrawPointY = PlayerY - 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( MapData[ i + MapDrawPointY ][ j + MapDrawPointX ] == 0 )
			{
				DrawBox( j * MAP_SIZE , i * MAP_SIZE ,
					j * MAP_SIZE + MAP_SIZE , i * MAP_SIZE + MAP_SIZE ,
							GetColor( 255 , 0 , 0 ) , TRUE ) ;
			}
		}
	}

	// プレイヤーの描画
	DrawBox( ( PlayerX - MapDrawPointX ) * MAP_SIZE , ( PlayerY - MapDrawPointY ) * MAP_SIZE ,
		 ( PlayerX - MapDrawPointX + 1 ) * MAP_SIZE , ( PlayerY - MapDrawPointY + 1 ) * MAP_SIZE ,
			 GetColor( 255 , 255 , 255 ) , TRUE ) ;
}

// WinMain関数
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
						 LPSTR lpCmdLine, int nCmdShow )
{
	int Key ;
	int OldX , OldY ;	// 移動する前のプレイヤーの位置を保存する変数

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

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

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

	// ループ
	while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 )
	{
		// 画面を初期化
		ClearDrawScreen() ;

		// キー入力を得る
		Key = GetJoypadInputState( DX_INPUT_KEY_PAD1 ) ;

		// 移動する前のプレイヤーの位置を保存
		OldX = PlayerX ; 
		OldY = PlayerY ;

		// キー入力に応じてプレイヤーの座標を移動
		if( Key & PAD_INPUT_LEFT ) PlayerX -= 1 ;
		if( Key & PAD_INPUT_RIGHT ) PlayerX += 1 ;
		if( Key & PAD_INPUT_UP ) PlayerY -= 1 ;
		if( Key & PAD_INPUT_DOWN ) PlayerY += 1 ;

		// 進入不可能なマップだった場合は移動できない
		if( MapData[ PlayerY ][ PlayerX ] == 0 )
		{
			PlayerX = OldX ;
			PlayerY = OldY ;
		}

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

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

		// ウエイト
		WaitTimer( 100 ) ;
	}

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

	return 0 ;					// ソフトの終了
}
このどこがプレイヤーを真ん中に描画する部分なのでしょうか?
そしてプレイヤーの座標を決めたは良いものの、表示画面は止まったままプレイヤーを追わないんじゃないんですか?
一体どうやって表示画面の左上の座標を決めることが出来て動くんです?

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

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

#9

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

分かっているなら数式は書けますよね? 私の問いかけに答えてもらっていないです。
プログラムに落としこむ前に仕様をちゃんと出来ないといけないので、分かっているつもりが一番危険です。
紙でシミュレート出来る問題なので、そこを手を抜かないで。

それとプログラムコードが理解できないのは別の問題なので、別の質問として質問をお願いします。
この質問では、ある程度理解出来たものとして回答しています。
最後の質問を見る限り、大事なことは理解されていないと思われます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
usao
記事: 1887
登録日時: 11年前

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

#10

投稿記事 by usao » 8年前

>表示画面は止まったままプレイヤーを追わないんじゃないんですか?

それが「スクロールのサンプル」なのであれば,きっと「スクロール」するのでは?
動かしてみればわかることでは?


>一体どうやって表示画面の左上の座標を決めることが出来て動くんです?

その「どうやって」の答えというのは,貼られたソースコードそのものだと思うのですが…


#動かさない&解読しない のであれば,わざわざどこかのサンプルプログラムとやらを引っ張り出してくる意味とは…?

閉鎖

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