ページ 11

rpgゲームのスクロールについて

Posted: 2014年2月28日(金) 20:23
by heyman
現在、rpgのゲームを作っているのですが、
マップのスクロールのやり方が分からなくて
困っています。どうすればよいかおしえていただけない
でしょうか?
マップはマップチップで作っています。
言語はcで、Dxライブラリを使用しています。
よろしくお願いします

Re: rpgゲームのスクロールについて

Posted: 2014年2月28日(金) 20:30
by softya(ソフト屋)
色々やり方があります。
私の書いたのもひとつの方法です。
「マイ 日記 • C言語交流フォーラム ~ mixC++ ~ RPG講座」
http://dixq.net/forum/blog.php?u=114&sd=a&c=2
2010年11月13日、 2010年11月14日辺りからマップ表示です。

私の方式はマップ上の主人公の位置からマップの表示の範囲を逆算します。

Re: rpgゲームのスクロールについて

Posted: 2014年2月28日(金) 21:18
by heyman
すいません俺にはちょっとわかりにくかったです。
まことに勝手ですが、質問を変えさせていただきます。
このプログラムでスクロールさせるには
何を付け加えたらいいでしょうか?

コード:

#include "DxLib.h"

#define MAP_SIZE    32          // マップチップ一つのドットサイズ
#define MAP_WIDTH   10          // マップの幅
#define MAP_HEIGHT  10          // マップの縦長さ

int Pls(); //プレイや-の初期化
int Mps(); //マップの初期化
int Chractermove(); //キャラの移動処理
int MapDraw(); //マップの画像
int mapc[MAP_HEIGHT][MAP_WIDTH]={1,1,1,1,1,1,1,1,1,1,
								 1,0,0,0,0,0,0,0,0,1,
						   	     1,0,0,0,1,1,0,0,0,1,
								 1,0,0,0,1,1,0,0,0,1,
	                             1,0,0,0,0,0,0,0,0,1,
	                             1,0,0,0,0,0,0,0,0,1,
	                             1,0,0,0,0,0,0,0,0,1,
	                             1,0,0,0,0,0,0,0,0,1,
	                             1,0,0,0,0,0,0,0,0,1,
	                             1,1,1,1,1,1,1,1,1,1,};
struct MAP
{
	int mhandle;
};

struct PLAYER
{
	int px,py; //キャラの座標
	int movex,movey; //移動した距離
	int dm; //ダメージ
	int hp; //主人公のライフ
	int mp; //マジックポイント
	int at; //攻撃力
	int df; //防御力
	int sp; //歩く速さ
	int mwalkx,mwalky; //歩く方向
	int xflag,yflag; //縦横のいどうのフラグ
	float xp; //経験値
	int lv; //レベル
	int mflag; //歩ける場所か?
	int kflag; //攻撃したか?
	int handle; //キャラの画像
	int state;//キャラの状態

};

PLAYER pl;
MAP mp;
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
	// ウインドウモードで起動
	ChangeWindowMode( TRUE ) ;
	// DXライブラリの初期化
    if( DxLib_Init() < 0 ) return -1;
	
	Pls();
	Mps();
	// 描画先を裏画面にする
	SetDrawScreen( DX_SCREEN_BACK ) ;
	
	while( ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0 )
    {
		ClearDrawScreen();

		switch( pl.state ){
		case 0: //移動できる
			MapDraw();
			Chractermove();
			break;

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


	 // DXライブラリの後始末
    DxLib_End();
	return 0;
}
int Pls()
{
	pl.px=50;
	pl.py=50;
	pl.hp=100;
	pl.lv=1;
	pl.at=1;
	pl.df=1;
	pl.sp=2;
	pl.handle=LoadGraph( "キャラ.png" ) ;
	return 0;
}
int Mps()
{
	mp.mhandle=LoadGraph( "マップチップ.png" ) ;
	return 0;
}
int MapDraw()
{        

	int i,j;
	
	for(i=0;i<MAP_WIDTH;i++)
	{
		for(j=0;j<MAP_HEIGHT;j++)
		{
			if(mapc[j][i]==0)DrawGraph(i*MAP_SIZE,j*MAP_SIZE,mp.mhandle,TRUE);
		}
	}
	return 0;
}

int Chractermove()
{
	int key;
	key=CheckHitKeyAll();
	pl.movex=pl.px;
	pl.movey=pl.py;

	
	if(CheckHitKey(KEY_INPUT_UP)==1)pl.mwalky=0,pl.yflag=1;//上に移動
	if(CheckHitKey(KEY_INPUT_DOWN)==1)pl.mwalky=1,pl.yflag=1;//下に移動
	if(CheckHitKey(KEY_INPUT_LEFT)==1)pl.mwalkx=0,pl.xflag=1;//左に移動
	if(CheckHitKey(KEY_INPUT_RIGHT)==1)pl.mwalkx=1,pl.xflag=1;//右に移動
	
	if( key != 0)
	{
		if(pl.yflag==1)
		{
			if(pl.mwalky==0)pl.movey-=pl.sp;//上に移動
			if(pl.mwalky==1)pl.movey+=pl.sp;//下に移動
			pl.yflag=0;
		}

		if(pl.xflag==1)
		{
			if(pl.mwalkx==0)pl.movex-=pl.sp;//左に移動
			if(pl.mwalkx==1)pl.movex+=pl.sp;//右に移動
			pl.xflag=0;
		}
	}
	if(mapc[(pl.movey)/32][(pl.movex)/32]==0 && mapc[(pl.movey+32-1)/32][(pl.movex)/32]==0 
								&& mapc[(pl.movey+32-1)/32][(pl.movex+25-1)/32]==0 && mapc[(pl.movey)/32][(pl.movex+25-1)/32]==0)
	{
	pl.px=pl.movex; //x座標の更新
	pl.py=pl.movey; //y座標の更新
	}
	DrawGraph(pl.px,pl.py,pl.handle,TRUE);
	return 0;
}
よろしくお願いします。

Re: rpgゲームのスクロールについて

Posted: 2014年2月28日(金) 21:35
by softya(ソフト屋)
大雑把に言うと、MapDraw()で自分が移動したらマップの左上の開始座標も移動すれば良いんです。
for(i=0;i<MAP_WIDTH;i++)
for(j=0;j<MAP_HEIGHT;j++)
ここを0から開始するのでは無く、主人公移動に合わせたマップ表示左上から開始します。
それとMAP_WIDTHやMAP_HEIGHTの個数ではなく、画面内に表示される個数だけ表示します。
ただし、配列添字外にアクセスしてしまうので、配列添字外の時はガードが必要です。

もう一つのキモは、マップの座標単位とキャラクタの座標単位が違うことなので、ここも工夫が必要です。

Re: rpgゲームのスクロールについて

Posted: 2014年2月28日(金) 21:44
by softya(ソフト屋)
ご本家のサンプルが参考になると思います。
「DXライブラリ置き場 サンプルプログラム」
http://homepage2.nifty.com/natupaji/DxL ... am.html#N4
ただ、ちゃんとRPGにするには、マップロードやらイベントやらキャラ配置やら色々しないと行けないことがありますので、最終的には私の書いたもののように複雑になります。

Re: rpgゲームのスクロールについて

Posted: 2014年3月01日(土) 01:07
by heyman
少し改良してこんな風になりました。

コード:

#include "DxLib.h"

#define MAP_SIZE    32          // マップチップ一つのドットサイズ
#define MAP_WIDTH   20          // マップの幅
#define MAP_HEIGHT  15          // マップの縦長さ

int Pls(); //プレイや-の初期化
int Mps(); //マップの初期化
int Chractermove(); //キャラの移動処理
int MapDraw(); //マップの画像
int mapc[MAP_HEIGHT][MAP_WIDTH]={1,1,1,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,1,
						   	     1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
								 1,0,0,0,1,1,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,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,0,0,0,1,
						   	     1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
								 1,0,0,0,1,1,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,0,0,0,0,0,0,0,0,0,1,1,1,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,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,0,0,0,1,
	                             1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
struct MAP
{
	int mhandle;
	int mscrx,mscry;
};

struct PLAYER
{
	int px,py; //キャラの座標
	int movex,movey; //移動した距離
	int dm; //ダメージ
	int hp; //主人公のライフ
	int mp; //マジックポイント
	int at; //攻撃力
	int df; //防御力
	int sp; //歩く速さ
	int mwalkx,mwalky; //歩く方向
	int xflag,yflag; //縦横のいどうのフラグ
	float xp; //経験値
	int lv; //レベル
	int mflag; //歩ける場所か?
	int kflag; //攻撃したか?
	int handle; //キャラの画像
	int state; //キャラの状態
	int scrx,scry; //スクロール
	int mscrx,mscry;
};

PLAYER pl;
MAP mp;
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
	// ウインドウモードで起動
	ChangeWindowMode( TRUE ) ;
	// DXライブラリの初期化
    if( DxLib_Init() < 0 ) return -1;
	
	Pls();
	Mps();
	// 描画先を裏画面にする
	SetDrawScreen( DX_SCREEN_BACK ) ;
	
	while( ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0 )
    {
		ClearDrawScreen();

		switch( pl.state ){
		case 0: //移動できる
			MapDraw();
			Chractermove();
			break;

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


	 // DXライブラリの後始末
    DxLib_End();
	return 0;
}
int Pls()
{
	pl.px=300;
	pl.py=150;
	pl.hp=100;
	pl.lv=1;
	pl.at=1;
	pl.df=1;
	pl.sp=2;
	pl.handle=LoadGraph( "キャラ.png" ) ;
	return 0;
}
int Mps()
{
	mp.mhandle=LoadGraph( "マップチップ.png" ) ;
	return 0;
}
int MapDraw()
{        

	int i,j;
	
	for(i=0;i<MAP_WIDTH;i++)
	{
		for(j=0;j<MAP_HEIGHT;j++)
		{
			if(mapc[j][i]==0)DrawGraph(pl.scrx+MAP_SIZE*i,pl.scry+MAP_SIZE*j,mp.mhandle,TRUE);
		}
	}
	return 0;
}

int Chractermove()
{
	int key;
	key=CheckHitKeyAll();
	pl.movex=pl.px;
	pl.movey=pl.py;
	pl.mscrx=pl.scrx;
	pl.mscry=pl.scry;

	if(CheckHitKey(KEY_INPUT_UP)==1)pl.mwalky=0,pl.yflag=1;//上に移動
	if(CheckHitKey(KEY_INPUT_DOWN)==1)pl.mwalky=1,pl.yflag=1;//下に移動
	if(CheckHitKey(KEY_INPUT_LEFT)==1)pl.mwalkx=0,pl.xflag=1;//左に移動
	if(CheckHitKey(KEY_INPUT_RIGHT)==1)pl.mwalkx=1,pl.xflag=1;//右に移動

	if( key != 0)
	{
		if(pl.yflag==1)
		{
			if(pl.mwalky==0)/*pl.movey-=pl.sp,*/pl.mscry += pl.sp;//上に移動
			if(pl.mwalky==1)/*pl.movey+=pl.sp,*/pl.mscry -= pl.sp;//下に移動
			pl.yflag=0;
		}

		if(pl.xflag==1)
		{
			if(pl.mwalkx==0)/*pl.movex-=pl.sp,*/pl.mscrx += pl.sp;//左に移動
			if(pl.mwalkx==1)/*pl.movex+=pl.sp,*/pl.mscrx -= pl.sp;//右に移動
			pl.xflag=0;
		}
	}

	if(mapc[(pl.movey-pl.mscry)/32][(pl.movex-pl.mscrx)/32]==0 && mapc[(pl.movey+32-1-pl.mscry)/32][(pl.movex-pl.mscrx)/32]==0 
					&& mapc[(pl.movey+32-1-pl.mscry)/32][(pl.movex+25-1-pl.mscrx)/32]==0 && mapc[(pl.movey-pl.mscry)/32][(pl.movex+25-1-pl.mscrx)/32]==0)
	{
	//pl.px=pl.movex; //x座標の更新
	//pl.py=pl.movey; //y座標の更新
	pl.scrx=pl.mscrx;
	pl.scry=pl.mscry;
	}

	DrawGraph(pl.px,pl.py,pl.handle,TRUE);
	return 0;
}
でもこれでいいかわからないので、もっとこうするべきとか、
ここがちがうなどあればお願いします

Re: rpgゲームのスクロールについて

Posted: 2014年3月01日(土) 09:17
by softya(ソフト屋)
ご自身の感触としては如何なのでしょうか?
見え方など仕様はご本人が決めることですので、バグが出ていなければこちらが特にコメントするものでもありません。
唯一気になるのは、無駄に画面外まで描画していることぐらいでしょうか。
※ あとローカル変数で良い物が構造体に含まれているのも気になりますかね。

今後の発展性とか具体的な方向性の質問であれば、それはお答えできます。
【補足】
このプログラムは本格的に組む前のプロトタイプと思っているんですが、違うんでしょうか?

Re: rpgゲームのスクロールについて

Posted: 2014年3月01日(土) 15:06
by heyman
softya(ソフト屋) さんが書きました:今後の発展性とか具体的な方向性の質問であれば、それはお答えできます。
今後は、このマップに敵(移動する)を配置しいたいのですが、敵のスクロールは何となくわからないでも
ないんですが、マップに組み込むのはどうしたらいいのでしょうか?
普通にmapcの配列に入れてもいいのでしょうか?
softya(ソフト屋) さんが書きました:このプログラムは本格的に組む前のプロトタイプと思っているんですが、違うんでしょうか?
そうですね。とりあえず画面のスクロールの練習みたいなものです。

Re: rpgゲームのスクロールについて

Posted: 2014年3月01日(土) 15:11
by softya(ソフト屋)
レイヤ構造を持たせる必要があるでしょう。
今後マップ自体も複雑になるでしょうし、それとは独立で敵を置きたいでしょうし、前景に成る家などのオブジェクトも置くでしょうし、イベントも必要でしょうし。
当然マップ・ツールで作らないと死にそうに成るでしょうからロードする仕組みも必要です。
と言うことで私のプログラムに近づいていきます。

【補足】
そうですね。
プロトタイプと言うことでmapcと同サイズのmapeとか作って敵だけを配置してみてはどうでしょうか。それがレイヤです。
【補足の補足】
mapeは発生情報として使うだけで、以後の管理はplayer構造体に準じて作ることになるでしょう。

Re: rpgゲームのスクロールについて

Posted: 2014年3月01日(土) 15:21
by heyman
なるほどすごく勉強になりました。ありがとうございました。