الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

تعلم كيفية تصميم Class لكاميرا سهله ومرنة الاستخدام

مثبّت
بدأه time1 في 17 أكتوبر 2008 · 7 رد · 7,063 مشاهدة · في DirectX
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

بسم الله الرحمن الرحيم

اخواني الاعزاء , اقدم لكم اليوم درس حول كيفية تصميم كاميرا على طريقة Frank.Luna

بداية سنقوم بتعريف نوعين من الكاميرا , وهي AirCraft والتي تسمح للمستخدم التحرك والانتقال بكل حرية داخل فضاء المشهد وتستخدم في الالعاب التي تحاكي الطيران , وLandObject والتي تحاكي الانتقال المقيد وهي مفيدة وتستخدم في ألعاب الرماية واطلاق الرصاصات ...إلخ

الخطوة رقم 1

نبدأ الـClass بتعريف نوعين من الكاميرا ,

	enum CameraType{AirCraft,LandObject};

يتم تعريف الكاميرا من خلال ثلاثة متجهات , Right,Up,Look

واخيرا نقوم بتعريف متجه يحدد لنا موضع الكاميرا Pos

post-82612-1224201077_thumb.jpg

وتحديد القيم هذه جميعا سنقوم بها من خلال الباني حيث سياخذ وسيط واحد يقوم بتحديد نوع الكاميرا وبعدها يقوم بإعطاء القيم للمتجهات

Camera::Camera(CameraType t)
{
	Type=t;

	Pos=D3DXVECTOR3(0.0f,1.0f,10.0f);
	Look=D3DXVECTOR3(0.0f,0.0f,-1.0f);
	Right=D3DXVECTOR3(-1.0f,0.0f,0.0f);
	Up=D3DXVECTOR3(0.0f,1.0f,0.0f);
}

الخطوة رقم 2 : تكوين مصفوفة العرض

مصفوفة العرض ستكون على الشكل التالي :

post-82612-1224201105_thumb.jpg

ولتحقيق ذلك سنقوم بالخطوات التالية :

1- تنظيم المتجهات وجعلها متعامدة:

نقوم بتنظيم متجه وضربه ضرب اتجاهي مع متجه اخر ونعلم عندها بأن ناتج هذه العملية سيكون متجه ثالث عمودي على المتجهين , نقوم بتنظيم المتجه الناتج ونكرر الخطوة على المتجهات الاخرى .

	D3DXVec3Normalize(&Look,&Look);
	D3DXVec3Cross(&Up,&Look,&Right);
	D3DXVec3Normalize(&Up,&Up);
	D3DXVec3Cross(&Right,&Up,&Look);
	D3DXVec3Normalize(&Right,&Right);

2- نوجد الانسحاب من خلال p- لانه p-p=0 للموقع pos

	float x=-D3DXVec3Dot(&Right,&Pos);
	float y=-D3DXVec3Dot(&Up,&Pos);
	float z=-D3DXVec3Dot(&Look,&Pos);

3- نكون بعدها المصفوفة على الشكل السابق:

(*V)(0,0)=Right.x;(*V)(0,1)=Up.x;(*V)(0,2)=Look.x;(*V)(0,3)=0;
(*V)(1,0)=Right.y;(*V)(1,1)=Up.y;(*V)(1,2)=Look.y;(*V)(1,3)=0;
(*V)(2,0)=Right.z;(*V)(2,1)=Up.z;(*V)(2,2)=Look.z;(*V)(2,3)=0;
(*V)(3,0)=		x;(*V)(3,1)=   y;(*V)(3,2)=		z;(*V)(3,3)=1;

الخطوة رقم 3 :الدوران حول المحاور

وهناك ثلاثة انواع من الدوران وهي :

Pitch : الدوران حول محور Right

Yaw: الدوران حول محور Up

Roll: الدوران حول محور Look

اولا الدوران نحو اليمين Pitch

نقوم بكتابة التابع الذي يمثل لنا الدوران حول اليمين Pitch وذلك من خلال الدوران حول محور Right باستخدام التابع D3DXMatrixRotationAxis والذي يأخذ الوسيط الاول مصفوفة الدوران والثاني الشعاع او المتجه المراد الدوران حوله والثالث مقدار الدوران .

بعد ذلك نجري التحويل على المتجهات الاخرى كما يلي :

	D3DXMATRIX T;
	D3DXMatrixRotationAxis(&T,&Right,angle);

	D3DXVec3TransformCoord(&Look,&Look,&T);
	D3DXVec3TransformCoord(&Up,&Up,&T);

post-82612-1224201146_thumb.jpg

ثانيا الدوران حول محورUp والذي يسمى Yaw

وهو مشابه للسابق باختلاف اننا سنضع قيدا على الكاميرا LandObject كما يلي

	D3DXMATRIX T;
	if(Type==LandObject)
		D3DXMatrixRotationY(&T,angle);
	else
		D3DXMatrixRotationAxis(&T,&Up,angle);

	D3DXVec3TransformCoord(&Right,&Right,&T);
	D3DXVec3TransformCoord(&Look,&Look,&T);

ثالثا الدوران حول محور Look والذي يسمى Roll

هذا الدوران فقط اذا كانت الكاميرا AirCraft وهو ايضا مشابه لسابقيه , كما يلي :

	D3DXMATRIX T;
	if(Type==AirCraft)
	{
		D3DXMatrixRotationAxis(&T,&Look,angle);

		D3DXVec3TransformCoord(&Up,&Up,&T);
		D3DXVec3TransformCoord(&Right,&Right,&T);
	}

الخطوة رقم 4 :المشي والطيران

اولا المشي Walk

يتم التعامل هنا في هذه الخطوة بأكملها مع المتجه Pos ( موضع الكاميرا ) فعلى سبيل المثال , اذا كانت الكاميرا AirCraft وكنا نرغب بالتقدم او المشي بمقدار Z فأننا سنقوم بضرب المتجه Look في المقدار z ونجعل المتجه Pos يساوي Pos+حاصل الضرب .

	if(Type==AirCraft)
		Pos+=Look*z;
	else
		Pos+=D3DXVECTOR3(Look.x,0.0f,Look.z);

اما اذا كانت الكاميرا LandObject عندها كما رأينا فأننا نفرض قيد على الكاميرا بعدم التحرك بحرية في الفضاء عند المشي وانما تبقى مسايرة للارض .

ثانيا الطيران :

كذلك الامر في الطيران فأن الكاميرا AirCraft تأخذ الحرية في الطيران والتحليق في الفضاء , بينما الكاميرا LandObject فالطيران يمثل الارتفاع فقط .

	if(Type==AirCraft)
		Pos+=Up*u;
	else
		Pos.y+=u;

واخيرا سنقوم بعرض الكود كاملا :

class Camera
{
public:
	enum CameraType{AirCraft,LandObject};
	Camera(CameraType);
	void Set_Camera(CameraType);
	void Set_VeiwMatrix(D3DXMATRIX *V);
////////////////////////////////////////////
	void Pitch(float);
	void Yaw(float );
	void Roll(float);
/////////////////////////////////////////
	void Walk(float);
	void Fly(float);
	void Strafe(float);
private:
	D3DXVECTOR3 Pos;
	D3DXVECTOR3 Look;
	D3DXVECTOR3 Right;
	D3DXVECTOR3 Up;
	CameraType Type;
};

Camera::Camera(CameraType t)
{
	Type=t;

	Pos=D3DXVECTOR3(0.0f,1.0f,10.0f);
	Look=D3DXVECTOR3(0.0f,0.0f,-1.0f);
	Right=D3DXVECTOR3(-1.0f,0.0f,0.0f);
	Up=D3DXVECTOR3(0.0f,1.0f,0.0f);
}

void Camera::Set_Camera(CameraType t)
{
	Type=t;
}

void Camera::Set_VeiwMatrix(D3DXMATRIX *V)
{
	D3DXVec3Normalize(&Look,&Look);
	D3DXVec3Cross(&Up,&Look,&Right);
	D3DXVec3Normalize(&Up,&Up);
	D3DXVec3Cross(&Right,&Up,&Look);
	D3DXVec3Normalize(&Right,&Right);
///////////////////////////////////////////////
	float x=-D3DXVec3Dot(&Right,&Pos);
	float y=-D3DXVec3Dot(&Up,&Pos);
	float z=-D3DXVec3Dot(&Look,&Pos);
///////////////////////////////////////////////
(*V)(0,0)=Right.x;(*V)(0,1)=Up.x;(*V)(0,2)=Look.x;(*V)(0,3)=0;
(*V)(1,0)=Right.y;(*V)(1,1)=Up.y;(*V)(1,2)=Look.y;(*V)(1,3)=0;
(*V)(2,0)=Right.z;(*V)(2,1)=Up.z;(*V)(2,2)=Look.z;(*V)(2,3)=0;
(*V)(3,0)=		x;(*V)(3,1)=   y;(*V)(3,2)=		z;(*V)(3,3)=1;

}

///////////////////////////////////////////////////////////////

void Camera::Pitch(float angle)
{
	D3DXMATRIX T;
	D3DXMatrixRotationAxis(&T,&Right,angle);

	D3DXVec3TransformCoord(&Look,&Look,&T);
	D3DXVec3TransformCoord(&Up,&Up,&T);
}

void Camera::Yaw(float angle)
{
	D3DXMATRIX T;
	if(Type==LandObject)
		D3DXMatrixRotationY(&T,angle);
	else
		D3DXMatrixRotationAxis(&T,&Up,angle);

	D3DXVec3TransformCoord(&Right,&Right,&T);
	D3DXVec3TransformCoord(&Look,&Look,&T);
}

void Camera::Roll(float angle)
{
	D3DXMATRIX T;
	if(Type==AirCraft)
	{
		D3DXMatrixRotationAxis(&T,&Look,angle);

		D3DXVec3TransformCoord(&Up,&Up,&T);
		D3DXVec3TransformCoord(&Right,&Right,&T);
	}
}

void Camera::Walk(float z)
{
	if(Type==AirCraft)
		Pos+=Look*z;
	else
		Pos+=D3DXVECTOR3(Look.x,0.0f,Look.z);
}

void Camera::Fly(float u)
{
	if(Type==AirCraft)
		Pos+=Up*u;
	else
		Pos.y+=u;

}

واخيرا , تستطيع التعديل على الClass السابق كما تشاء وابتكار انواع جديدة من الكاميرات مناسبة لاحتياجاتك , لتكون في النهاية كاميرا تخدم لعبتك بشكل مناسب كما في الصورة :

post-82612-1224201872_thumb.jpg

,اتمنى ان اكون قد وفقت في هذا الدرس ,

تمنياتي لكم بالتوفيق ..

تم تعديل هذه المشاركة بواسطة time1 في 17 أكتوبر 2008 في 03:15

llback.jpg

اشهد ان لا إله إلا الله وان محمدا ً رسول الله

#3

السلام عليكم ، موضوع رائع (أول موضوع اقرأه فى برمجة الألعاب)

تمكنت من فهم الكود برغم انى لم اعمل على C++ لغتى هى C# لكن لدى بعض الأسئلة

هل تعلم ال c++ ضرورى لبرمجة الألعاب ؟؟

هل هناك فرق بين ال c++.Net و ال C++ Classic ؟؟

ام المهم هو التركيز على معرفة منطق الألعاب و DirectX ؟؟

هل هناك اى كتب تنصحنى بها ( أعشق القراءة ) ؟؟

و فى النهاية مجهود رائع و الف الف الف شكر لحضرتك

جازاك الله كل خير

#4

اهلا اخي DotNet-XML

لست خبيرا لاصل لمرحلة النصح ولكن لن ابخل عليك بشئ وسأقول مالدي ...

لاتكترث كثيرا بمسألة اللغة وتضيع وقتك في اكتشاف المزايا بين اللغات وعمل المقارنات العقيمة ,, ماهي اللغة التي تجدها .. !! حسنا ابدع بها وواصل اتقانها وادخل المجال الذي تحبه , بالأول والاخير انت قد اختصرت الكلام بعبارتك هذه :

اقتباس
ام المهم هو التركيز على معرفة منطق الألعاب و DirectX

ركز على فهم منطق الالعاب , مقدمة عن الادوات الاساسية التي تحتاجها لبرمجة الالعاب ( ليس المهم الوصول لدرجة الاتقان ) وافهم مبادئ التعامل مع هذه المكتبة .

فقط هذا مالدي وبشأن الكتب استطيع ان انصحك اذا كنت من هواة C/C++ ولكن C# اعذرني لم اتعامل معها .. :blush:

llback.jpg

اشهد ان لا إله إلا الله وان محمدا ً رسول الله

#5

اشكرك كثيرا من كل قلبى

و انا معك فى النقطة :

اقتباس
لاتكترث كثيرا بمسألة اللغة وتضيع وقتك في اكتشاف المزايا بين اللغات وعمل المقارنات العقيمة ,

من منطلق لا تبحث عن ماذا تفعله لك هذة اللغة و لكن ابحث ( و ايضا طٌّّور ) ما تستطيع انت تفعله انت بها

تقبل جزيل شكرى

#6
DotNet-XML كتب:
من منطلق لا تبحث عن ماذا تفعله لك هذة اللغة و لكن ابحث ( و ايضا طٌّّور ) ما تستطيع انت تفعله انت بها

Bang Bang :lol:

llback.jpg

اشهد ان لا إله إلا الله وان محمدا ً رسول الله

#7

جميل جدا بارك الله فيك أخي

لكن ليتك تفصلت في كل شيء

بالمناسبة ماذا تعني

0.0f ماذي يعني حرف (f)

وما وظيفة الدالة (D3DMATRIX)

هل هو خاص بعمل مصفوفة

الجزائر قلبي وغزة نبضه

2522zn0.png
#8

0.0f تعني ان هذه القيمة من نوع float

ام D3DMATRIX كلاس تعربف ب مصفوفة

والله اعلم

مواضيع مشابهة