/سلسلة تطوير الألعاب للبلاليص | الجزء الثاني : الدبابات #1

سلسلة تطوير الألعاب للبلاليص | الجزء الثاني : الدبابات #1

تمهيد :كنت أنوي العمل مباشرة على لعبة صغيرة وشرحها هنا ولكن قبل البدء في العمل على أي شئ, يجب أن أوضح بعض الأشياء المتعلقة بالعالم الثلاثي الأبعاد … بطريقة بسيطة, لن نتكلم بالتفصيل … هذه الأشياء ضرورية لفهم كيفية التعامل مع العوالم ثلاثية الأبعاد …. حسناً, فلنبدأ ….


(س ص ع) (X Y Z) : المحاور الثلاث ….. هكذا سنرمز للأبعاد الثلاثة في الفراغ “الثلاثي الأبعاد” …. قد يتبدّل القصد من كل رمز على حسب التطبيق الذي تستعمله ….. فعلى سبيل المثال … الارتفاع في اليونتي يرمز له بـ”ص , Y” , في حين يرمز له بـ”ع , Z” في 3D Studio Max ….على أي حال … سنستفيد من هذه الرموز في تحديد الاتجاهات التي قد نرغب أن يتحرك فيها الجسم …. وهذا ينقلنا لنقطة أخرى … “المتجهات” .


(أ.1)

(أ.2)

(المتجهات) (Vectors) : في الفضاء الثنائي الأبعاد … على ورقة مثلاً …. إذا أردت تحديد اتجاه فيجب على الأقل أن تعرف نقطتين …. وإذا كان عندك إطار مرجعي فيجب أن تعرف نقطة واحدة على الأقل …. كما في الرسم التوضيحية (أ.1) …. نفس الطريقة نتبعها في المتجهات الثلاثية الأبعاد …. عليك أن تعرف نقطتين في الفراغ على الأقل … أو نقطة واحدة إذا كان لديك إطار مرجعي …. في حالتنا مع اليونتي فغالباً سيكون هناك إطار مرجعي ونقطة أصله هي (0,0,0) سواء كان الإطار المرجعي محلّي -Local أوشامل – Global …. وسنفهم القصد من هؤلاء لاحقاً ولكن الآن فلنضرب مثالاً لمتجه في الفراغ الثلاثي الأبعاد …. المتجه الثلاثي يُرمز له بـ Vector3 في البونتي …و لهذا إذا أردنا مثلا أن نحرك جسم ما عمودياً للأعلى فسيكون متجه الوحدة له هكذا :

Vector3(0.1.0)

وهكذا مع بقية الاتجاهات …. ماذا لو أن يتحرك الجسم في اتجاه زاوية معينه ؟! … 45 درجة مثلاً على الأرض …. للقيام بهذا علينا أولا تجاهل بعد الارتفاع “ص – Y في هذه الحالة” …لأن الحركة ستكون في مستوى الأرض “أفقي” …. ولأن ظل الزاوية 45 يساوي 1 …. فهذا يعني أن كلا من “س و ع – X,Z” قيمتهم تساوي واحد لنقطة تقع على هذا المتجه وتتقاطع مع دائرة قطرها الوحدة …. والنتيجة ستكون كالآتي :-

Vector3(1,0,1)

إذا كان هناك شئ غير مفهوم في موضوع المتجهات فربما عليك مراجعة كتب خارجية في هذا الموضوع والتي قد تساعدك أكثر في توظيف المتجهات بشكل أفضل في لعبتك كفهم كيفية الضرب الاتجاهي والقياسي ..إلخ من المواضيع المرتبطة, أو انتظر فسنتعرّض للموضوع كثيراً خلال هذه السلسلة ..



الأسطح في الفراغ الثلاثي الأبعاد : فلنتخيل معاً شكل بسيط كالمكعب, به ستة أسطح, ياترى كيف يتم التعبير عن هذه الأسطح في العالم الثلاثي الأبعاد ؟! …. تعال نحلل هذا المكعب ببساطة …. يوجد في هذا المكعب ستة “أسطح/مضلعات – Polygons” كما ذكرنا مسبقاً … وكل سطح/مضلع يوجد به “وجه – Face” ….هنا يخلط الكثيرون بين الوجه والسطح …. يتعامل الحاسب بطريقة مختلفة مع الفراغ الثلاثي الأبعاد عن ماهي موجود في الواقع … فلكل سطح وجه واحد تستطيع النظر من خلاله … فإذا نظرت من خلف هذا الوجه مثلاً لن تتمكن من رؤيته …. وهذا يعني أن السطح هو الهيكل مثلاً …. وأن الوجه هو المتجّه الذي سيظهر فيه هذا السطح …. وهنا نأتي لتعريف شئ آخر وهو العموديات – Normals …. وهو المتجه العمودي على الوجه “عمودي على الوجه فقط ولكن يمكنك تغير اتجاهة بالنسبة للسطح وعندها تحصل على اتجاه آخر للوجه”… وهو الذي يحدد كيف سيظهر السطح بالنسبة للإضاءة مثلاً … هناك شئ آخر وهو “النقاط – Vertices” … النقاط تحدد لك قمم الأسطح/المضلعات … ويمكنك تحريكها في الفضاء لتغير من شكل المجسم كما يحلو لك …. وعند إيصال نقطتين ينتج لنا ما يسمّي “الحرف-Edge” ….. انظر لهذه الرسم فستساعدك على فهم الموضوع :



والآن … ماذا لو أردنا إعطاء هذا المكعب لوناّ ؟!! أوأردنا أن نرسم عليه صورة ليبدو كصندوك مثلاً …. سنقوم بتطبيق خامة – Material على كل وجه … لينتج الشكل المطلوب ….



حسناً , هذه كانت مجرد نبذة عن الأساسيات … عليك أنت أن تبحث في الموضوع أكثر …. والآن فلننتقل لنقطة أخرى …. وهي نبذة أخرى ولكن هذه المرة عن أساسيات البرمجة, سأشرح بعض المفاهيم بإيجاز …. وأنت عليك الباقي :-


متغيّر – Variable : فلنأخذ على سبيل المثال محفظتك …. كم من النقود بها الآن ؟! …. أنا مثلاً الآن محفظتي بها 4 جنيهات O_O” …. ولكن منذ أربع ساعات فقط كان بها 50 جنيهاً ….. والآن فلنعتبر محفظتي هذه عنوان “المتغيّر” …. والقيمة التي بها هي الجنيهات التي تتغير …. وبهذا فعندنا متغيّر من نوع “جنيهات” واسمه “محفظتي” …. يمكننا الآن أخذ هذا المتغير وطرح بعض الجنيهات منه لشراء العلكة مثلاً … أو دفع أجرة المواصلات …… وهكذا ….. إذا أردنا التعبير عن هذا في اليونتي مثلاً … فلنفترض أن في اليونتي نوعاً من المتغيرات يدعى “EP” أي جنيهات مصرية …. فإذا أردنا حجز متغير باسم “محفظتي” من نوع “EP” فسيكون كالآتي :-

var myPocket : EP ;

فـ “var” هي إختصار لـ Variable … وهذه بالضبط الطريقة التي تعلن بها عن متغير في اليونتي …. وضّح أولاً أنك تريد أن تعلن عن متغير بكتابتك var في أول السطر … وبعدها اكتب اسم المتغير وهو myPocket ….. وبعدها “:” …. ثم بعدها وضّح نوع المتغير وهو هنا على سبيل المثال EP …. ثم تخبر اليونتي بأنك انتهيت بأن تضع “;” وهي ضرورية وقد تسبب لك مشاكل لو لم تهتم بوضعها …


دالة – Function : فلنكتفي للآن بتعريفها على أنها مجموعة من الأوامر التي يمكن تفيذها أكثر من مرة ….


الفصائل والعناصر – Classes & Objects: ربما من درس بعض الفلسفة ومنطق التصنيفات لن يجد مشكلة في فهم فكرة الفصائل ….. فلنأخذ مثالاً من الطبيعة …. البشر مثلاً … فهذه فصيلة …. فالبشر كلهم لهم خصائص مشترك تستطيع من خلالها التعرف عليهم … ولكن أنا وأنت لنا خصائص تميزنا عن بعضنا البعض … فأسمائنا وملامحنا مختلفة مثلاً ..ولكن لازلنا بشر … هذه بالضبط هي العلاقة بين الفصل والعنصر …. فالعنصر يحتوي على خصائص الفصل والتي تميزه عن الفصائل الأخرى … ولكن مع ذلك فليست كل عناصر هذه الفصر متشابها … فهي تختلف وتتغير في خصائصها المندرجة تحت هذا الفصل …. إذا لم تفهم شيئاً من هذا الكلام الآن فلا عليك … سنتطرق لها لاحقاً أيضاً بتفصيل أكثر …. ولمن يريد القراءة أكثر فعليه بفهم مبادئ “البرمجة الموجّهة للكائنات” – “Object Oriented Programming” ….

حسناً …. يكفي ما تطرقنا له الآن من أساسيات … الباقي سيأتي مع التطبيق…. في المرة القادمة سنبدأ في صناعة لعبة صغيرة باليونتي …. هذه المرة أوعدكم  P=

تمهيد : أولاً عذراً على التأخير … عذري هو انشغالي بالتجهيز للـEED (يوم الهندسة المصري) ….. على أي حال .. انتهى الـ EED وها قد عدت …… ستكون هذه أول تطبيقاتنا العملية على الـ Unity …….. لعبة دبابات بسيطة …. في البداية يجب علينا أن نتصور كيف ستكون اللعبة …. ولكن بما أن هذه اللعبة بسيطة جداً فلن نحتاج للكثير من الكتابة … فقط بضعة سطور لتصف اللعبة …..

وصف اللعبة : ببساطة ستتحكم في دبابة بمفاتيح التنقل الأساسية (<- , -> , ^ , V ) … يطلق قذيفة بالضغط على “المسطرة – Space” … يقابل دبابات تتحرك في اتجاه عمودي عليه في نفس المستوى الأفقي …. عليه تدميرها بإطلاق قذيفة … و إذا اصطدم بأحدى الدبابات المتحرك فسيخسر ….


الرسوم : في هذه المرحلة لن نحتاج لرسوم معقدة وتحريك ومظللات (Shaders) ….إلخ إلخ …. فقط يمكنك استعمال عناصر بسيطة كالمكعبات مثالاً …. أو لو كنت أصلاً فنان 3D … فيمكنك استخدام نماذجك الخاصة … على أي حال …. قمت بعمل دبابة بسيطة بأسلوب كرتوني لنستخدمها في اللعبة , يمكنك تحميلها بالضغط على الصورة :-

الباقي سنبنيه بالعناصر المبدأية الموجودة في اليونتي …. كالمكعب …إلخ إلخ ….

إنشاء مشروع جديد : كما أوضحنا في الجزء الثاني من السلسلة … المشروع هو اللعبة ككل … المشروع سيكون به كل الموارد والملفات التي قد تستخدمها في اللعبة … والآن فلنبدأ مشروعاً جديداً ….. File >> New Project …. سيطلب منك تحديد مكان حفظ المشروع … اختر المكان الذي تشاء … وأيضاً هناك خيارات لتضمين موارد “حزم” جاهزة الإعداد لتستخدمها في لعبتك …. الغ تحديدها الآن إذا كانت مفعّله …. فلن نحتاج لها الآن ….. كما في الصورة :-



سترى أمامك مشهد خال من أي شئ عدا الكاميراً … كما في الصورة ….. يمكنك التعديل في نسق (تشكيلة) التبويبات بالتغير في Layout كما هي معلمه في الصورة … أنت حر في إعداد مساحة العمل الخاصة بك بالصورة التي تريحك …. يمكنك تقل أي تبويب و إدراجة في أي منطقة ترغب :-



يستحسن أن تبدأ في تنظيم مجلد مشروع قبل البدأ في أي شئ … التنظيم إختياري ولكن مستحسن حتى تعتاد …. ففي المشاريع المعقدة بعض الشئ سيختصر عليك الكثير من الوقت … لأن هذا اللعبة بسيطة فسيكون هناك فقط أربعة مجلدات كالآتي :-

علىّ هنا أن أوضّح أن كل مجلدات مشروعك يجب أن تكون في Assets … لا علاقة لك بـ Liberary و Temp الآن …

تصدير مجسّم : الآن فلنصدّر مجسّم الدبابة للمحرك …. للقيام بذلك كل ما عليك فعله هو نسخ الملف Tank.max إلى مجلد Objects وافتح اليونتي ستجده يقوم بتصدير النموذج آلياً ….. بعد ان ينتهي من التصدير ستجد الآتي :-

كما تلاحظ فيوجد النموذج الأساسي وسنطلق عليه الشبكية “Mesh” وبه كل المعلومات المطلوبه عن النموذج … لو تذكر عندما تحدثنا عن الأسطح في الجزء الثالث من السلسلة … هناك الخامة التي تضاف لتعط اللون/الصور المطلوبة للمجسّم … وهذا بالضبط الموجود في مجلد Materials …


والآن فلندرج Tank في المشهد/Scene …..عن طريق السحب والإدراج …. بعدها حدد Tank من الـ Hierarchy …. ستجد أن خصائصه ومكوناته ظهرت في تبويب المفتش/Inspector …. يوجد مكوّن أساسي موجود في كل العناصر التي قد تظهر في اللعبة وهو مكون الـ Transform ويمكنك من خلاله تحديد موقع/Position واتجاه دوران/Rotation وحجم/Scale العنصر ….. ستكون إعدادات الـ Transform للـ Tanks كالآتي :-

يوجد مكوّن آخر في عنصر Tank وهو Animation … لأن المجسم به عدد من الأطّر/Frames والتي قد تستخدمها للحركة فسيفترض اليونتي أن هناك حركة ولهذا أضاف هذا المكون ….. على العموم لن نحتاج لهذا المكون الآن ..

كذلك سنعدّل قليلاً في إعدادات الـ Transform للكاميرا الأساسية في اللعبة/Main Camera كالآتي :-

يمكنك الآن بناء البيئة بوضع أرضية مثلاً من خلال أن تضيف Plane وتغير في أبعادها …

كتابة سكربت الحركة : سنقوم الآن بكتابة سكريبت التنقل , أولاً فلننشئ ملف Javascript جديد من Create في تبويب المشروع/Project :-

أعد تسمية السكربت إلى tankController وافتحه …. ستجد التالي أمامك :-


function Update () {
}

هذه أول دالة ستتعامل معها في اليونتي …. ببساطة كل ماتكتبه بين الـ{} سيدخل في دوّارة اللعبة/Game Loop ويتكرر بمعدّل معين في الثانية الواحدة … مثلا 60 مرة في الثانية …. مثلاً لو حجزت متغير و كتبت كود لإضافة 1 للمتغير ووضعته في دالة Update() …. فستجد أنه بعد ثانية مثلا أصبح المتغير قيمته 60 أو أي رقم آخر يدل على معدل تنفيذ العملية في الثانية على حسب سرعة الجهاز ….

الآن قبل أن نبدأ علينا تعريف متغيّر لسرعة الدبابة tankSpeed … في البداية وخارج أي دالة سنكتب الكود التالي :

var tankSpeed : int  = 2.0 ;
وتعني أننا أعلنا عن متغيّر باسم tankSpeed ومن نوع integer والذي يعني ببساطة “أرقام صحيحة” وأعطيناه قيمة = 2 …


من مميزات اليونتي أنك تستطيع التعديل في المتغيرات في وقت التشغيل لتختبر النتائج وللتجربة … فمثلاً أدرج السكريبت الذي وضعناه هذا في العنصر Tank …. ستجد مكوّن جديد خاص بالسكريب … سيندرج تحته المتغيرات المعروضة Exposed Variables ….

على أي حال …. فلنعد مرّة أخرى للسكربت …. سنتعرف الآن على إحدى دوال التحكّم … وهي الدالة الشرطية … If Statement …. ببساطة هي كالآتي …. إذا كان كذاً صحيحاً نفّذ كذا …. مثلاً … إذا “مات مبارك” صحيحة فنفّذ الآتي بأن “تورّث الحكم لجيمي” … أو إذا كانت “محفظتك فارغة” فنفّذ الآتي وهو أن “تستلف من زميلك” أو “تسرق بنك” مثلاً …. استخدامها هنا هو لنتأكد من أن شيئاً حدّث وبعدها نتّخذ إجراء معين للرد على هذا الحدث … مثلا لو ضغط اللاعب على زر المسافة/Space … فرد الفعل سيكون أن تنشئ طلقة في الاحدثيات كذا وكذا ….. فلنرى ذلك :-

if(Input.GetButton(“Vertical”))
{
transform.position += Input.GetAxis(“Vertical”) * transform.right * tankSpeed * Time.deltaTime;
}

ماحدّث هو كالآتي …. دالة Input.GetButton ترجع قيمة صحيح/True أو خاطئ/False بناءاً على الزر المضغوط عليه … فهنا مثلا Vertical معرّفة في اليونتي على أنها زر التقدم أو التأخر … بحيث إذا ضغط على أي من الزرين فستعيد دالة Input.GetButton قيمة صحيحة/True …. وهكذا فعندما يضغط اللاعب على زر التقدم مثلاً “^” … فسينفذ الكود الموجود بين الـ {} …. و الكود الموجود بينهما يقوم بالآتي …. يأخذ قيمة الـ Position الموجودة في مكوّن Transform الموجود في العنصر (هل تذكره ؟!) … ويقوم بإضافة “transform.right*tankSpeed*Time.deltaTime” … تعالوا نرى ما في هذا الكود … أولا هذا ضرب اتجّاه في قيمة …. الاتجاه وهو transform.right والذي يعتبر متجه الوحدة في اتجاه اليمين…. والقيمة وهي tankSpeed والتي عرّفناها بـ 2 في بداية السكريبت … و Time.deltaTime وهذه لها وظيفة معينة ولكن منعاً للتعقيد الآن فلنكتفي بأن نعرف وظيفتها وهي الإبقاء على ما تدخله وما تراه متزامناً …. أما Input.GetAxis(“Vertical”) فوظيفتها بسيطة جداً …. هل سألت نفسك كيف يفرق اليونتي بين زر التقدم والتأخر ؟! … فكلاهما سيرجع True عند الضغط عليهم …. هنا تأتي وظيفة GetAxis …. فهي ترجع قيمة مختلفة هذه المرة , 1 أو -1 … أي القيمة سالبة أو موجبة … وببساطة إذا ضربنا هذه القيمة عند إضافة متجّه الحركة الجديد …. فسيعكس مثلا لو كانت القيمة سالبة وبهذا يتأخر اللاعب عند ضغط زر التأخر … وسيتقدم اللاعب عندما تضغط زر التقدم لأنه أرجع قيمة +1 و التي هي المحايد الضربي … أي لا تؤثر في قيمة الضرب …..


الناتج النهائي للكود كالآتي :-

var tankSpeed : int = 2.0 ;function Update () {

if(Input.GetButton(“Vertical”))
{
transform.position += Input.GetAxis(“Vertical”) * transform.right * tankSpeed * Time.deltaTime;
}
}

… يمكنك الآن تطبيق الكود على الدبابة ورؤية النتيجة والتي من المفترض أن تكون كالآتي : http://dl.dropbox.com/u/9047337/TankGame/001/TankGame001.html
… اممممم … أعتقد أن الدبابة بطيئة بعض الشئ ….. يمكنك التعديل في tankSpeed كما تريد حتى ترى السرعة المناسبة …

يمكنك تحميل ملف المشروع والذي به ما تمّ حتى الآن من هنا : http://dl.dropbox.com/u/9047337/TankGame/TankGame.rar

في المرة القادمة سنضيف بعض التعديلات على الكاميرا و حركة الدبابة وربما بعض الأعداء ……

TAGS: