【Dxlib】でマップのスクロールについて

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

【Dxlib】でマップのスクロールについて

#1

投稿記事 by ラキア » 12年前

初めまして、いきなりですが教えて欲しいです。

http://dixq.net/forum/viewtopic.php?f=3&t=7765
こちらの「DXライブラリの横スクロールについてお聞きしたいのですが...」とサンプルを参考に制作してて
マップのスクロール判定はできたのですが、この状態から敵なるものを増やして、自分に向かってくるというプログラムを組み込んだのですが、うまくいきません。

このview_charx , view_charyの値が固定になるので、本来のプレイヤーの座標(Pl.plx , Pl.ply)のほうに敵が向かって行ってしまい、おかしいことになってしまいます。
色々といじってみたりしてみたのですが、うまくいきませんでした。
何かアドバイスを頂けますと助かります。

自分の考えでは、ここからだとMapDrowPointx(画面左上に描画するマップ座標をセット)をPl.plxにあわせて移動させてみるだと思ってたのですが、
その場合だと、表示している画面がPl.plxの速度に追いつかず、画面外にすぐ出てしまいます。

文章が拙いですが伝われば幸いです・・・

初心者ですのでソースの書き方もめちゃめちゃかもしれませんが、一度見ていただけますでしょうか?
関数で分けたりしてますので・・・関数部分を抜いてここに書いてます。
こちらだけではわからない等があったら言ってください。

コード:


void map_graph()
{
	float MapDrowPointx , MapDrowPointy ;		//マップ座標値
	int i , j ;		//カウンタ用 

	//画面左上に描画するマップ座標をセット
	MapDrowPointx = Pl.plx - SCREEN_WIDTH / 2 ;
	MapDrowPointy = Pl.ply - SCREEN_HEIGHT / 2 ;

	//左右の補正
	if(MapDrowPointx < 0){MapDrowPointx = 0 ;}
	if(MapDrowPointy < 0){MapDrowPointy = 0 ;}

	if(MapDrowPointx >= (MAX_MAP_WIDTH - SCREEN_WIDTH)){MapDrowPointx = MAX_MAP_WIDTH - SCREEN_WIDTH ;}
	if(MapDrowPointy >= (MAX_MAP_HEIGHT - SCREEN_HEIGHT)){MapDrowPointy = MAX_MAP_HEIGHT - SCREEN_HEIGHT ;}
	
	//画面内の位置を求める
	view_charx = Pl.plx - MapDrowPointx ;
	view_chary = Pl.ply - MapDrowPointy ;

	//マップ描画
		for(i = 0 ; i < MAP_HEIGHT ; i++)
		{
			for(j = 0 ; j < MAX_MAP_WIDTH ; j++)
			{
				//マップデータが1だったら四角を描画
				if(map_date[i][j] == 1)
				{
					DrawBox(j * CHIP_SIZE - (int)MapDrowPointx , i * CHIP_SIZE - (int)MapDrowPointy,
						j * CHIP_SIZE + CHIP_SIZE - (int)MapDrowPointx, i * CHIP_SIZE + CHIP_SIZE - (int)MapDrowPointy,
						GetColor(0,0,255) , TRUE) ;
				}

			}
			
		
		}

}

void graph_drow()
{
	//キャラクタの描画
	DrawBox( (int)(view_charx - CHAR_SIZE * 0.5),     (int)(view_chary - CHAR_SIZE * 0.5),
		(int)(view_charx + CHAR_SIZE * 0.5) + 1, (int)(view_chary + CHAR_SIZE * 0.5) + 1,
			 GetColor(255, 0, 0), TRUE) ;
	return ;
}
//エネミー描画
void enemy_graph_drow()
{
	int i ;		//カウンタ用

	for(i = 0 ; i < ENEMY ; i++)
	{
		//キャラクタの描画
		DrawBox( (int)(En[i].enx - CHAR_SIZE * 0.5),     (int)(En[i].eny - CHAR_SIZE * 0.5),
				 (int)(En[i].enx + CHAR_SIZE * 0.5) - 1, (int)(En[i].eny + CHAR_SIZE * 0.5) - 1,
				 GetColor(0, 255, 0), TRUE) ;
	}
	return ;
}

//エネミー移動処理
int enemy_char_move(float enemy_x , float enemy_y ,float *emovex , float *emovey)
{
	float ep , epx , epy , px , py , ex , ey ;
	int i ;

	//プレイヤー座標
	px = Pl.plx + CHAR_SIZE * 0.5 ;
	py = Pl.ply + CHAR_SIZE * 0.5 ;

	//プレイヤーに向かうための距離計算、代入
	//エネミー座標
	ex = enemy_x + CHAR_SIZE * 0.5 ;
	ey = enemy_y + CHAR_SIZE * 0.5 ;

	//プレイヤーとエネミーの距離を直線で見るときに使う
	epx = px - ex ;
	epy = py - ey ;

	//平方根を求めるのに標準関数のsqrtを使う
	ep = sqrt(epx * epx + epy * epy) ;

	//1フレームあたり3ドット移動するようにする
	*emovex = epx / ep * 3 ;
	*emovey = epy / ep * 3 ;
	
	return 0 ;
}
あと、最後にメイン部分です。

コード:

void act_game()
{
	float movex , movey ;	//プレイヤーの移動処理用
	float emovex[ENEMY] , emovey[ENEMY] ;		//エネミーの移動処理用
	int i ; //カウンタ用
	int scr_flg_x = 0 , scr_flg_y = 0 ;

	

	// 描画先を裏画面にセット
	SetDrawScreen( DX_SCREEN_BACK ) ;

	// 垂直同期信号を待たない
	SetWaitVSyncFlag( FALSE ) ;

	// 入力状態の初期化
	input = 0 ;
	edgeinput = 0 ;

	// 60FPS固定用、時間保存用変数を現在のカウント値にセット
	FrameStartTime = GetNowCount() ;

	while(ProcessMessage()==0 && g_sequence == S_ACT_GAME && gpUpdateKey() == 0 ){

			//画面のクリア
			ClsDrawScreen();

			//1/60秒たつまで待つ
			while(GetNowCount() - FrameStartTime < 1000 / 60){}

			//現在のカウント値を保存
			FrameStartTime = GetNowCount() ;

			/*移動処理*/
				movex = 0.0 ;
				movey = 0.0 ;

				//プレイヤー移動処理
				if((input & PAD_INPUT_LEFT) != 0)		//左
				{
					movex -= SPEED ;
				}
				if((input & PAD_INPUT_RIGHT) != 0)
				{
					movex += SPEED ;
				}
				if((input & PAD_INPUT_UP) != 0){movey -= SPEED ;}		//上
				if((input & PAD_INPUT_DOWN) != 0){movey += SPEED ;}		//下

				//当たり判定をみながら移動量に基づいて移動
				char_move(&Pl.plx , &Pl.ply , movex , movey , CHAR_SIZE) ;

				//エネミー移動処理
				for(i = 0 ; i < ENEMY ; i++)
				{
					//プレイヤー間を計算して移動
					enemy_char_move(En[i].enx , En[i].eny , &emovex[i] , &emovey[i]) ;
					
					//移動量加算
					En[i].enx += emovex[i] ;
					En[i].eny += emovey[i] ;

					//if(En[i].enx < 0 || En[i].enx > MAX_MAP_WIDTH ||
						//En[i].eny < 0 || En[i].eny > MAX_MAP_WIDTH){}
				}

			/**/

			
			/*グラフィック表示*/
				map_graph() ;			//マップ
				graph_drow() ;			//自機		
				enemy_graph_drow() ;	//敵
			/**/
				if((input & PAD_INPUT_10) != 0)
				{
					g_sequence = S_TITLE ;
				}

		//画面の更新
		ScreenFlip() ;
	}
	//終了
	return ;
}
よければ、アドバイスお願いします。

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

Re: 【Dxlib】でマップのスクロールについて

#2

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

プレイヤーと同様に敵も表示座標とマップ座標が必要ですが分かれていないのが原因だと思います。

【追記】
こういうのは絵に書いてみると分かりやすいです。
scroll.png
scroll.png (5.13 KiB) 閲覧数: 4291 回
マップ全体の絶対座標と画面の相対座標を混同するとうまくは行きません。
この絵だとEnemy1は画面に対してはyがマイナスの座標にいる事になり表示されません。
Enemy2は画面内なので表示されます。
つまり、マップ全体から画面の相対座標に変換しないと画面での表示位置は確定できないのです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ラキア

Re: 【Dxlib】でマップのスクロールについて

#3

投稿記事 by ラキア » 12年前

早い返信ありがとうございました!
おかげさまでできました!

一度その方法を考えて、プログラムに書き込んでみたのですがうまくいかず、
ですが今回はうまくいきましたので、多分書き方がおかしかったんだろうなぁ・・・と思いました。

またつまるところが必ず出てくると思いますので、わからなかったら質問させていただきます。

ありがとうございました!

閉鎖

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