トップビューとクォータービュー

アバター
MNS
記事: 35
登録日時: 15年前

トップビューとクォータービュー

投稿記事 by MNS » 14年前

久しぶりの日記ですね。2Dの話です。

トップビューとは、真上からの視点のことで、
向きと位置が空間的に分かりやすいというか、
そのまま(関数の)グラフに当てはめられるので、
私としては最も作りやすいと思う視点です。

ですが、ゲームとしての見栄えは良くなく、
せいぜいターン制戦略SLGに使われるくらいでしょうか、
ゲームとして使われるのは稀です。

では、見栄えのよい視点とは何かと言えば、
おそらく、クォータービューではないでしょうか。

クォータービューとは、斜め上方から見た視点です。
ですから、ある意味見た目は3Dと似ています。

いまは大体が3Dで作られているゲームなので、
視点など特に造作もなく変えられると思いますが、
2Dの場合は中々大変なものです。

なんにせよ、クォータービューの視点を前提に、
座標やベクトルを管理するのは難しいのです。

ですから、管理・更新はトップビューを前提にしたもので行い、
描画の際だけ、クォータービューのそれに変換するのが良いんじゃないか、
というのが、まあ、私が突発的に考えた方法です。

長い説明になりましたが、結局のところ、
中身のデータをトップビューで管理して、
描画の際だけクォータービューに変換するような
プログラムを書いたよ、というのが今回の趣旨です。

CODE:

#include 
#include "DxLib.h"


const int	WIDTH	= 200;
const int	HEIGHT	= 200;

struct	Vec
{
	double	x,y;
	Vec():x(0.0),y(0.0){}
	Vec(double x_, double y_)
		:x(x_),y(y_){}
};

//ベクトルの内積・実数倍・減算
double	Dot(Vec A, Vec B){ return A.x*B.x+A.y*B.y; }
Vec	VecMul(Vec V, double D){ return Vec(V.x*D, V.y*D); }
Vec VecSub(Vec T, Vec S){ return Vec(T.x-S.x,T.y-S.y); }
Vec VecSum(Vec T, Vec S){ return Vec(T.x+S.x,T.y+S.y); }


struct	MovingBall
{
	MovingBall()
	{
		Pos		= Vec(
				(double)GetRand(WIDTH),
				(double)GetRand(HEIGHT)
					 );
		double angle
			= GetRand(314*2)/100.0;
		Velocity = 
			Vec( cos(angle)*4,
				 sin(angle)*4 );
	}

	//		位置
	Vec		Pos;

	//		速度
	Vec		Velocity;

	//		位置の更新
	void	Moving();

	//		各種方式で描画
	void	Render_In_TopView();
	void	Render_In_QuarterView();
};


//トップビュー視点での座標・ベクトルを
//クォータービュー視点でのそれに変換
Vec	ConvertVec_TopView_into_QuarterView
	(Vec Tvec)
{
	//  一次変換

	const double ang = 45.0/180.0*PHI;

	//回転行列
	const	double	a1=cos(ang),	a2=-sin(ang)
	,				a3=sin(ang),	a4=cos(ang)	;
	//拡大縮小行列
	const	double	s1=1.0,		s2=0.0
	,				s3=0.0,		s4=0.5	;

	Vec Qvec;
	Vec Bvec = Tvec;

	Qvec.x = a1*Bvec.x + a2*Bvec.y;
	Qvec.y = a3*Bvec.x + a4*Bvec.y;
	
	Bvec = Qvec;
	
	Qvec.x = s1*Bvec.x + s2*Bvec.y;
	Qvec.y = s3*Bvec.x + s4*Bvec.y;

	//最後に平行移動
	Qvec = VecSum(Qvec, Vec(WIDTH*cos(ang),0));

	return Qvec;
}

//上の逆
Vec	ConvertVec_QuarterView_into_TopView
	(Vec Qvec)
{
	return Vec();
}

void	MovingBall::Moving()
{
	//---壁との衝突
	if(	Pos.x  WIDTH )
	{
		//右端の法線
		Vec vN(-1.0,0.0);
		Velocity = VecSub(Velocity, VecMul(vN, 2*Dot(vN,Velocity)));
	}
	if(	Pos.y  HEIGHT )
	{
		//下端の法線
		Vec vN(0.0,-1.0);
		Velocity = VecSub(Velocity, VecMul(vN, 2*Dot(vN,Velocity)));
	}
	//---
	Pos.x += Velocity.x;
	Pos.y += Velocity.y;
}


void	MovingBall::Render_In_TopView()
{
	DrawCircle( (int)Pos.x,
				(int)Pos.y,
				4,
				GetColor(255,0,0) );
}


void	MovingBall::Render_In_QuarterView()
{
	Vec Ren_Pos = ConvertVec_TopView_into_QuarterView(Pos);
	//描画に際して位置をずらす(+200,+50)
	DrawOval( (int)Ren_Pos.x + 200,
			  (int)Ren_Pos.y + 50,
			  4,
			  2,
			  GetColor(255,0,0),
			  1 );
}



int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	ChangeWindowMode(true);

	DxLib_Init();

	SetDrawScreen(DX_SCREEN_BACK);

	SetDrawMode( DX_DRAWMODE_BILINEAR ) ;


	//4つのボールが動きまわる
	const int NUM = 4;
	MovingBall	Balls[NUM];


	while(ProcessMessage() == 0 && !CheckHitKey(KEY_INPUT_ESCAPE))
	{
		ClsDrawScreen();

		//各枠を描画
		DrawBox(0,0,WIDTH,HEIGHT,GetColor(255,255,255),false);
		Vec A(0,0), B(200,0), C(0, 200), D(200, 200);
		A=ConvertVec_TopView_into_QuarterView(A);
		B=ConvertVec_TopView_into_QuarterView(B);
		C=ConvertVec_TopView_into_QuarterView(C);
		D=ConvertVec_TopView_into_QuarterView(D);
		DrawLine(A.x+WIDTH,A.y+50,B.x+WIDTH,B.y+50,65535);
		DrawLine(A.x+WIDTH,A.y+50,C.x+WIDTH,C.y+50,65535);
		DrawLine(B.x+WIDTH,B.y+50,D.x+WIDTH,D.y+50,65535);
		DrawLine(C.x+WIDTH,C.y+50,D.x+WIDTH,D.y+50,65535);

		for(int i = 0; i < NUM; ++i)
		{
			Balls[i].Moving();
			Balls[i].Render_In_TopView();
			Balls[i].Render_In_QuarterView();
		}

		ScreenFlip();
	}

	DxLib_End();

};
4つのボールがある領域を動きまわり、
その様子をトップビューとクォータービューで描画します。
見た目はこんな感じです。
TandQview.png
TandQview.png (23.48 KiB) 閲覧数: 176 回
動きのあるプログラムって、
本当にSSの見栄えは最悪ですね…。
一応プログラムも添付しておきます。

[拡張子 zip は無効化されているため、表示できません]

貼っておいて何ですが、
こんなべらぼうにアップロードしてしまって大丈夫なんでしょうか…

編集1 : インデント修正
編集2 : 出来ていませんでしたので再び…
編集3 : code を code=c に変更
最後に編集したユーザー MNS on 2010年11月23日(火) 11:01 [ 編集 3 回目 ]

アバター
釣り師
記事: 33
登録日時: 15年前

Re: トップビューとクォータービュー

投稿記事 by 釣り師 » 14年前

こんなコードををすらりと書けてしまうのは凄いですね

アバター
MNS
記事: 35
登録日時: 15年前

Re: トップビューとクォータービュー

投稿記事 by MNS » 14年前

どうも、コメントありがとうございます。
すんなり書けるようになりたいものですが、
特に数学の知識を要するところ、
この場合は玉の反射や、一次変換のとこですね。
そこら辺は全然、すんなり行きませんね…(- -;)