الأربعاء، 4 أغسطس 2010

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

تمهيد : أولاً عذراً على التأخير ... عذري هو انشغالي بالتجهيز للـ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

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

هناك 5 تعليقات:

  1. شرح ممتاز لكن انت بالغت في وصف البلاليص ..

    انت ملحد ؟

    ردحذف
  2. انت ملحد ؟

    ردحذف
  3. هتفرق معاك في إيه ياسيادة الغير معرّف إذا كنت ملحد ولا بوذي ولا حتى كائن فضائي؟! كلّه كلام في الفضا... وبعدين إيه علاقة الموضوع بسؤالك أساساً؟! D:

    ردحذف
  4. ما شاء الله عليك مبدع
    كنت اواجة مشاكل في الحركة
    لاكن فادني شرحك بشكل كبير في الحركة

    ردحذف
  5. أنت زنجى؟

    ردحذف