اذهب إلى المحتوى

لوحة المتصدرين

  1. عبد اللطيف ايمش

    • نقاط

      2

    • المساهمات

      1406


  2. مهند داود

    مهند داود

    الأعضاء


    • نقاط

      1

    • المساهمات

      37


  3. وليد زيوش

    وليد زيوش

    الأعضاء


    • نقاط

      1

    • المساهمات

      78


  4. محمد حبش

    محمد حبش

    الأعضاء


    • نقاط

      1

    • المساهمات

      22


المحتوى الأكثر حصولًا على سمعة جيدة

المحتوى الأعلى تقييمًا في 12/13/18 في كل الموقع

  1. الإصدار 1.0.0

    20399 تنزيل

    رافقت زيادة استخدام شبكة الإنترنت زيادةً كبيرةً في عدد الحواسيب التي تعمل مخدماتٍ لمختلف الخدمات الشائعة، كمواقع الويب والبريد الإلكتروني والمراسلة الفورية وخواديم الملفات وخلافه؛ وقد أثبت لينُكس تفوقه في مجال الخواديم، وخصوصًا بعد الانتشار الواسع لتوزيعة أوبنتو الخاصة بالخواديم؛ الذي يُعنى هذا الدليل بشرح طرق تثبيت وضبط مختلف خدماتها. آمل أن يكون هذا الكتاب إضافةً مفيدةً للمكتبة العربية؛ وأن يفيد القارئ العربي في تعلم إدارة أشهر نظام لتشغيل الخواديم. والله وليُّ التوفيق.
    1 نقطة
  2. الإصدار 1.0.0

    45536 تنزيل

    لا يخفى على أحدٍ سطوع نجم لغة HTML5 وانتشار تطبيقاتها انتشارًا كبيرًا، إذ ذاع صيتها وأصبحت حديث الكثيرين لما تحتويه من تقنياتٍ مهمةٍ لتطبيقات الويب، فهي تتضمن كل ما يتعلق بتشغيل مقاطع الفيديو على صفحات الويب، وتوليد الرسوميات ديناميكيًا، وتحديد الموقع الجغرافي للمستخدم، وإتاحة استعمل تطبيقات الويب دون اتصال، إضافةً إلى تنظيمها لبنية المستند الهيكلية تنظيمًا دقيقًا يسهِّل تفسيرها من المتصفحات والبرمجيات الأخرى، والمزيد… لذا جاء هذا الكتاب محاولًا تقديم مفاهيم HTML5 وتقنياتها وطرائق استخدامها إلى القارئ العربي، مدعمًا بأمثلة علميةٍ تسهّل توضيح الأفكار، وحاولتُ فيه توفير أحدث المعلومات عن دعم تلك التقنيات قدر المستطاع، وأعدت النظر في بعض الفصول لتناسب التغييرات التي طرأت حديثًا. هذا الكتاب مترجمٌ عن كتاب Dive Into HTML5 للمؤلف Mark Pilgrim المرخّص برخصة المشاع الإبداعي CC BY 3.0، والذي نشرته O’Reilly لاحقًا باسم HTML5: Up and Running. هذا الكتاب مرخص بموجب رخصة المشاع الإبداعي نسب المُصنَّف - الترخيص بالمثل 4.0 (CC BY-SA 4.0). شعار HTML5 والشعارات البقية مرخصة برخصة المشاع الإبداعي CC BY 3.0. وفي النهاية، أحمد الله على توفيقه لي بإتمام العمل على الكتاب، وأرجو أن يكون إضافةً مفيدةً للمكتبة العربية، والله ولي التوفيق. يمكنك قراءة فصول الكتاب في صورة مقالات مما يلي: المقال الأول: خمسة أشياء عليك معرفتها عن HTML5 المقال الثاني: نظرة على تاريخ HTML - الجزء الأول المقال الثالث: نظرة على تاريخ HTML - الجزء الثاني المقال الرابع: اكتشاف دعم المتصفحات لميزات HTML5 المقال الخامس: الرسم عبر عنصر canvas في HTML5 المقال السادس: صيغ ترميز الفيديو والصوت وحاوياتها وكيفية عملها في الويب المقال السابع: ترميز مقاطع الفيديو بعدة صيغ المقال الثامن: إضافة مقاطع الفيديو عبر العنصر <video> في HTML5 المقال التاسع: التعامل مع التأريخ في HTML5 المقال العاشر: تحديد الموقع الجغرافي (GeoLocation) في HTML5 المقال الحادي عشر: التخزين المحلي (Local Storage) في HTML5 المقال الثاني عشر: تطبيقات الويب التي تعمل دون اتصال – الجزء الأول المقال الثالث عشر: تطبيقات الويب التي تعمل دون اتصال – الجزء الثاني المقال الرابع عشر: النماذج (Forms) في HTML5 المقال الخامس عشر: مدخل إلى البيانات الوصفية (microdata) في HTML5 المقال السادس عشر: توصيف الأشخاص باستخدام metadata في HTML5 المقال السابع عشر: توصيف المنظمات/الشّركات باستخدام microdata في HTML5 المقال الثامن عشر: كيفية توصيف الأحداث والمراجعات باستخدام microdata على HTML5
    1 نقطة
  3. في بداية رحلتك إلى عالم التدوين كنوع من أنواع العمل الحر، تحتاج غالباً إلى الإلمام ببعض النقاط الهامة في هذا المجال، منها البحث عن منصة سهلة لإدارة ونشر المحتوى عبر الشبكة العنكبوتية، وبالطبع فإن معرفتك بمميزات وعيوب منصات التدوين المختلفة ستساعدك في اختيار المنصة الملائمة لك. حالياً تعتبر منصة وورد برس المنصة الأكثر استخداماً في تشغيل المواقع والمدونات حول العالم، لكن ربما يجد الكثير من المدونين في البداية بعض الصعوبة في التعامل معها، لذلك يلجأ الكثير منهم إلى منصة بلوجر الأسهل استخداماً من وجهة نظرهم، لكن سرعان ما يبدأ التفكير حول دقة اختيار المنصة ومدى توافقها مع رغبات المدون. بالتالي نجد تساؤلاً يطفو إلى السطح مع كل بداية جديدة من أحد المدونين ألا وهو بلوجر أم وورد برس: أيهما أستخدم؟ أو أيهما أفضل؟ وباعتقادي الشخصي فإن هذا التساؤل يجب أن يكون على نحو مغاير تماماً لأن أفضلية منصة معينة ليست العامل الأساسي الذي يجب أن ينطلق منه المدون، بل في مدى ملائمة هذه المنصة وتوافقها مع رغبات المدون. وبأي حال، سنحاول من خلال هذا الموضوع مناقشة بعض الفروقات الهامة بين منصة وورد برس ومنصة بلوجر والإجابة على هذا التساؤل، لكن أرجو أن نلتفت إلى النقاط التالية قبل البداية: المقارنة التالية موجهة بشكل أساسي للراغبين باستخدام إحدى المنصتين في مجال التدوين أو ما شابه، وليست مقارنة لما يمكننا فعله باستخدام كل منصة. المقارنة ستكون بين منصة بلوجر و WordPress.org غير المدفوعة هذه المقارنة لا تشبه المقارنات بين فريقي كرة القدم "ريال مدريد" و"برشلونة" أو بين شركتي Apple وSamsung، فهي لا تهدف إلى نسف منصة ما وتمجيد الأخرى، بل هي محاولة عملية لمساعدة القارئ للوصول إلى استخدام منصة معينة وفق معايير محددة. دعونا نبدأ أولاً: الملكيةبلوجر هي منصة نشر محتوى تمتلكها شركة Google العملاقة وبالتالي يمكنك الوثوق بها دون تردد كغيرها من منتجات شركة Google الرائعة، بينما منصة وورد برس هي نظام مفتوح المصدر لإدارة المواقع تمتلكه شركة Automattic ويعود حق ملكية المدونة إلى المدون نفسه. وذلك يعني أنك لست المالك الحقيقي لمدونة بلوجر، فيمكن لشركة Google حذف المدونة الخاصة بك أو إغلاقها مؤقتاً أو نهائياً فيما إذا قمت بمخالفة شروط النشر والاستخدام أو حتى إذا أرادت جوجل ذلك لسبب أو لآخر وحينها لن تكون الشركة مضطرة لإبداء أي تفاصيل حول أسباب الإغلاق. بينما مع مدونة وورد برس ستكون أنت المالك الفعلي للمدونة ويمكنك إغلاقها كيفما تريد، ولا يمكن لجهة معينة إغلاق أو حذف المدونة لسبب أو لآخر حيث ستكون لديك سيطرة كاملة على محتويات وملفات مدونتك من خلال استضافة خاصة. المسألة الثانية المترتبة على موضوع الملكية هي إمكانية بيع المدونة، فمع مدونات بلوجر هناك صعوبة بالغة في بيع المدونة مع عدم حقك أصلاً في بيعها، بينما مع مدونات وورد برس فلك الأحقية الكاملة في بيع المدونة متى شئت وبكل سهولة. الخلاصة: من الواضح أن استخدام وورد برس لديه أفضلية في هذه النقطة، لكن من الإنصاف القول بأن شركة Google لا تلجأ إلى إغلاق المدونة بسبب انتهاك بسيط وهي غير متعسفة إطلاقاً في استخدام هذا الحق. وبالتالي فإن الالتزام بسياسة بلوجر يضمن لك عدم المساس بالمدونة من طرف Google. ثانياً: التصميمالكثير من القوالب المتوفرة لمدونات بلوجر هي قوالب منخفضة الجودة، وحتى في حال حصولك على قالب مميز ستجد أن العديد من المدونات الأخرى تستعمل نفس القالب وبالتالي فإن الحصول على قالب احترافي ومميز لمدونات بلوجر ليس بالأمر السهل، خصوصاً مع وجود عدد قليل جداً من المطورين لمدونات بلوجر. وقد تتجه فعلاً لاختيار أحد المختصين في تطوير قوالب بلوجر وتدفع له مقابل ذلك للحصول على قالب يناسبك، لكنك في الغالب ستُصطدم بالخيارات المحدودة جداً التي تسمح بها منصة بلوجر من حيث التصميم والقالب. أما مدونات وورد برس فتمتلك مجموعة كبيرة جداً من القوالب الرائعة والتصاميم المتنوعة، كما يمكن للمدون الحصول على قوالب احترافية للغاية، ويمكنه وضع تصوره الخاص بالتصميم الذي يرغب به وسيجد الكثير من المطورين المميزين على استعداد لتنفيذ كل ما يريد وعلى أفضل وجه، وبالتالي فمنصة وورد برس تقدم لك خيارات غير محدودة من حيث التصميم والقوالب، وبالتالي لا داعي للقلق إطلاقاً حول مسألة التصميم. الخلاصة: الأفضلية من حيث القوالب والتصميم هي لمدونات وورد برس. ثالثاً: التعامل مع المنصةتتميز مدونات بلوجر بسهولة كاملة في التعامل مع المنصة، وبمجرد امتلاكك لحساب GMail ستكون قادراً على إنشاء مدونة مجانية عبر بلوجر والبدء في نشر المواضيع من خلال لوحة التحكم البسيطة ودون الدخول في أمور برمجية أو فنية. بينما تحتاج مدونات وورد برس إلى معرفة ببعض الأشياء الفنية والبرمجية بشكل مسبق حتى تتمكن من تنصيب المدونة والبدء في نشر المواضيع، وبالتالي قد يجد بعض المدونين صعوبة في التعامل مع وورد برس في البداية. الخلاصة: مدونات بلوجر لها الأفضلية من حيث التعامل وسهولة الاستخدام ولا تتطلب معرفة مسبقة بالأمور الفنية. رابعاً: التحكم في المنصةتوفر مدونات بلوجر خيارات محدودة جداً للتحكم في المنصة وتخصيصها بالطريقة الملائمة للمدون، وبالتالي على المدون العمل وفق ما تُمليه المنصة عليه وليس العكس، فمثلاً هناك خيارات محدودة جداً في التحكم بالتعليقات ونماذج الاتصال داخل المدونة. أيضاً لا تسمح مدونات بلوجر بإضافة محررين ومساهمين آخرين للمدونة، وجود عدد محدود من الصفحات الثابتة، عدم القدرة على التحكم في آلية ظهور المواضيع وغيرها. أما مدونات وورد برس فتمتلك خيارات غير محدودة للتحكم في المنصة وبالطريقة التي تلائم المدون، فيمكن إدراج عدد غير محدود من المساهمين والمحررين داخل المدونة وتخصيص ملفاتهم الشخصية، نظام تحكم مميز في التعليقات ونماذج الاتصال والصفحات الثابتة وآلية ظهور المواضيع، بالإضافة إلى إمكانية استخدام العديد من الإضافات لتوفير المزيد من الخيارات للتحكم في المنصة. الخلاصة: الأفضلية من حيث التحكم في المنصة هي لمدونات وورد برس. خامساً: تحسين الظهور في محركات البحث "SEO"يعتقد الكثير من المدونين بأن استخدام منصة بلوجر يعطيها أفضلية من ناحية SEO وذلك لأنها تابعة لشركة Google وبالتالي ظهور أفضل داخل محرك بحث Google على الأقل، في الواقع هذا الافتراض غير صحيح بالمطلق. دعونا نحتج برأي المهندس في شركة جوجل Matt Cutts، فهو يعمل لدى الشركة المالكة والداعمة لبلوجر بينما تعمل مدونته الشخصية عبر منصة وورد برس. يرى Matt أن كل من المنصتين تعمل بشكل مناسب مع SEO وكل منصة لها إيجابيات وسلبيات، لكن في نفس الوقت فإن منصة وورد برس تعطي خيارات وإمكانية تخصيص أكبر في هذه المسألة. ويضيف Matt بأنه إذا كنت تمتلك محتوى جيد وعددًا معقولًا من الروابط المؤدية لمدونتك وبالتالي زوارًا أكثر، فإن المسألة لن تشكل أي فارق بين استخدام وورد برس أو بلوجر. يمكننا القول بأن مسألة SEO تعتمد في الأساس على المدون نفسه، فكل من وورد برس وبلوجر لا تقدم أي مميزات في هذا الخصوص ابتداءً، وبالتالي على المدون معرفة بعض الاستراتيجيات المتعلقة بالسيو للحصول على ظهور أفضل. لكن يمكن لمستخدمي منصة وورد برس الاستعانة لاحقاً ببعض الإضافات المتعلقة بـ SEO مثل إضافة Yoast والتي توفر العديد من المميزات والاحتياجات المتعلقة بالسيو، وهذا الأمر غير متوفر في مدونات بلوجر. الخلاصة: وورد برس يتيح خيارات أوسع من ناحية تحسين محركات البحث "SEO" من خلال توفير العديد من الإضافات والقدرة على تهيئة المدونة لمحركات البحث بشكل أفضل، لكن في نفس الوقت يجب الالتفات إلى أن جودة المحتوى هي النقطة المركزية في المدونة، بمعنى لو أنك تمتلك محتوى ضعيف وسيء مع أفضل استراتيجية سيو في العالم فلا تتوقع أن تحقق مدونتك أي نجاح حقيقي على صعيد الشبكة العنكبوتية. بينما المحتوى الجيد سواء كان عبر منصة بلوجر أو وورد برس هو المفتاح الحقيقي للنجاح. سادساً: التكاليفتتيح لك منصة بلوجر إنشاء مدونة مجانية بشكل كامل، حيث يتم استضافة المدونة لدى سيرفرات جوجل دون دفع أي مبلغ مقابل ذلك، بالإضافة إلى ذلك ستحصل على 1 جيجابايت لتخزين الصور من خلال خدمة بيكاسا مجاناً ويمكنك زيادتها إلى 15 جيجابايت باستخدام حساب جوجل بلس أو حساب جوجل درايف مجاناً أيضاً، كما تسمح لك جوجل بنشر عدد لا نهائي من المواضيع عبر المدونة والقدرة على إنشاء عدة مدونات عبر حساب واحد، والأهم أن جوجل تتيح لمدونتك حجم تبادل بيانات Bandwidth غير محدود. وبالطبع يمكن دفع بعض التكاليف البسيطة بحسب الرغبة لظهور المدونة بشكل أفضل أهمها اختيار اسم نطاق خاص للمدونة بدلاً عن اسم نطاق فرعي تقدمه بلوجر بشكل افتراضي، بالإضافة إلى إمكانية اختيار قالب مدفوع. أما مع منصة وورد برس فيجب عليك امتلاك استضافة لمدونتك من خلال إحدى الشركات التي توفر خدمات الاستضافة، ويجب عليك حينها تحديد المتطلبات التي تحتاجها مدونتك مثل المساحة التخزينية وحجم تبادل البيانات وبالتالي يمكنك اختيار أنسب العروض التي توفرها شركات الاستضافة المختلفة، وبالطبع ستقوم بدفع مبلغ مادي شهري بحسب خطة الاستضافة التي اخترتها، وكلما ازدادت المتطلبات الخاصة لمدونتك مثل الحاجة لمساحة أكبر أو أصبحت المدونة تستقطب عدد زوار أكبر، كلما ازدادت الحاجة لدفع مبالغ إضافية والانتقال لاستضافة مناسبة أكثر لمتطلبات المدونة. هناك نقطة هامة مرتبطة بمسألة التكاليف وهي أي المنصتين أفضل لتحقيق الدخل من المدونة؟ في الواقع مسألة تحقيق الدخل هي مسألة مرتبطة بجودة المحتوى واختيارك لمجال المدونة بصورة ملائمة بالإضافة إلى اتباع طرق تسويق فعالة لجلب المزيد من الزوار وبالتالي دخل أفضل، وليس لها علاقة باستخدام هذه المنصة أو تلك لكن دعونا ننوه لأمرين، الأول أن خدمة جوجل أدسنس هي إحدى خدمات شركة جوجل وبالتالي فإن ربط مدونة بلوجر بحساب أدسنس يتم بصورة سريعة وتقدم جوجل تسهيلات لقبول المدونات التابعة لها من خلال التكامل بين أدسنس وبلوجر، بينما تحتاج أحياناً مدونات وورد برس لبعض الوقت لاعتمادها عبر جوجل أدسنس. الأمر الثاني يتعلق بمستقبل المدونة، فإذا أردت تحويل المدونة إلى أشبه بالمشروع التجاري وتحقيق دخل أكبر فربما تحتاج حينها لخيارات أكبر لإدارة المدونة وبالتالي ستكون منصة وورد برس خيارك الأفضل. الخلاصة: مدونات بلوجر لها الأفضلية من حيث التكاليف، بينما يجب أن يتوفر لك مبلغ مادي لإنشاء مدونة وورد برس. سابعاً: الأمانباستخدامك لمنصة بلوجر فأنت تقول وداعاً لمشاكل الأمان والحماية الخاصة بالمدونة، فشركة جوجل هي المسؤول المباشر عن المعالجة الأمنية للمدونة وحمايتها من الاختراق، وبالتالي فليس هناك داعي لوضع إضافات أو خدمات أمنية أو الاستعانة بأحد المختصين في هذا المجال. ولغاية الآن تعتبر مدونات بلوجر عصية على الاختراق من قبل القراصنة وربما تعتبر هذه الميزة هي الأقوى من بين كل المميزات الخاصة بمدونات بلوجر. أما عند استخدامك لمدونة وورد برس فستكون أنت المسؤول الأساسي عن توفير الحماية اللازمة للمدونة ومتابعتها في حال حدوث أي خلل أو اختراق. وبالرغم من وجود العديد من الإضافات المتعلقة بالحماية والتطوير والتحديث الأمني الدائم للمنصة إلا أن مدونات وورد برس تبقى عرضة لهجمات القراصنة. فمثلاً من الممكن أن تتعرض بعض المدونات لهجمات حجب الخدمة DDOS وإيقافها لمدة معينة، بينما لا يمكن حدوث أمر من هذا القبيل مع مدونات بلوجر وسيرفرات جوجل، وبالطبع هذا لا يعني أن منصة وورد برس هي منصة غير آمنة، لكن في نفس الوقت يجب الاهتمام بهذه النقطة من قبل المدون لضمان عدم وجود أي مشاكل مستقبلية. الخلاصة: مدونات بلوجر لها أفضلية واضحة من حيث الأمان والحماية، بينما تحتاج مدونات وورد برس إلى المتابعة من صاحب المدونة لتوفير الحماية اللازمة. ثامناً: الدعمللأسف فإن مدونات بلوجر لا تتمتع بدعم حقيقي من طرف جوجل، ففي حال اختيارك للتدوين عبر منصة بلوجر عليك أن تنسى تماماً بعض المصطلحات مثل فريق الدعم أو مجتمع الدعم ومن الأفضل ألا تتعب نفسك في محاولة الاتصال بهم أو حتى البحث عن طريقة للاتصال. وللتوضيح أكثر يوجد هناك منتدى دعم رسمي خاص ببلوجر يطرح بعض المشاكل والحلول الخاصة ببلوجر ويمكنك البحث خلاله عن إحدى المشاكل التي واجهتك، لكن على الأغلب لن تجد هناك أي مساعدة حقيقية لحل مشكلتك عبر هذه المنتديات أو حتى أي تفاعل من قبل المطورين. وباختصار إن واجهتك مشكلة داخل بلوجر فعليك اختصار الوقت والعمل على إيجاد الحل بنفسك أو عن طريق الاستعانة بأحد المختصين بعيداً عن الدعم الرسمي من جوجل. أما بالنسبة لمدونات وورد برس فهي تتمتع بدعم فني كامل، مع وجود العديد من المساهمين والمطورين المستعدين لتقديم المساعدة عبر قسم المساعدة أو المنتدى الرسمي الخاص بالمنصة، وبالتالي ستجد حلاً لأغلب المشاكل التي قد تواجهك عند استخدامك للمنصة بكل سهولة. الخلاصة: تمتلك مدونات وورد برس أفضلية كاملة من حيث الدعم الفني وإيجاد الحلول لأي مشكلة تواجه المدون. تاسعاً: مستقبل المنصّتيندعونا نعود إلى الوراء قليلاً ونتذكر الخطوة التي قامت بها شركة ياهو بإغلاق منتديات مكتوب والصدمة التي تلقتها شريحة واسعة من المستخدمين في العالم العربي حينها. لكن لا شك أن هذه الصدمة ستكون متواضعة جداً في حال أقدمت جوجل على إغلاق خدمة بلوجر بعد فترة معينة من الزمن، ولك أن تتصور ذلك الآن. هناك العديد من المخاوف حول إمكانية إقبال جوجل على خطوة شبيهة بخطوة ياهو يوماً ما، ومما يشير على هذا الأمر أن شركة جوجل لم تقم بإطلاق أي تحديثات حقيقية أو تطوير فعلي على منصة بلوجر منذ فترة طويلة جداً، بالإضافة إلى أن تطبيق بلوجر لنظام أندرويد يعتبر من أسوأ التطبيقات التي أطلقتها الشركة، مما يعطي انطباعاً لدى البعض بعدم اهتمام جوجل بمنصة بلوجر بشكل جدي، وتركيزها بشكل كبير جداً على خدمة يوتيوب التي تحقق لها أرباح طائلة. وعلى الرغم من أن المخاوف بإغلاق خدمة بلوجر هي مخاوف مبررة، لكن لا توجد أي دلائل حقيقية تدعمها أو حتى تلميحات حول الأمر من شركة جوجل، والمقارنة بمسألة إغلاق ياهو لمكتوب لا تستقيم مطلقاً، والمتابع الجيد للأحداث يعلم الصعوبات التي واجهتها ماريسا ماير الرئيسة التنفيذية لشركة ياهو واضطرارها على اتخاذ عدة خطوات حاسمة وقوية، وهو الأمر الذي لا تعاني منه جوجل حالياً ولا حتى في السنوات القليلة المقبلة. لكن لنفترض في أسوء الحالات أن جوجل قامت بإغلاق خدمة بلوجر فهل يعني ذلك ضياع المدونة؟ بالتأكيد لا فشركة عملاقة مثل جوجل لن تترك المستخدم الذي وضع الثقة في خدماتها لسنوات دون إيجاد حل فعال، وأبسط هذه الحلول هو إعطاء مهلة زمنية معينة لنقل المدونة عبر منصة أخرى. بالطبع ستكون هناك أضرار معينة جراء ذلك لكن يمكن مع الوقت تدارك هذه الأضرار والتغلب عليها. أما منصة وورد برس فلا شك أن أمامها مستقبلاً واعداً، فهي تسير يوماً بعد يوم نحو مزيد من التطوير والتحديث خصوصاً مع وجود آلاف المطورين والمختصين في البرمجة أو التصميم والمواضيع المرتبطة بتطوير منصة وورد برس، وبالتالي فإن استخدامك لمنصة وورد برس سيشعرك باطمئنان أكبر حول مستقبل مدونتك وتطويرها بشكل دائم، بالإضافة إلى ذلك ستكون أنت المتحكم الوحيد في مصير المدونة ومستقبلها. الخلاصة: تمتلك مدونات وورد برس أفضلية واضحة من ناحية مستقبل المنصة، سواء من حيث الملكية أو التطوير والتحديث، في نفس الوقت لا يوجد أي نهوض حقيقي لغاية الآن لمنصة بلوجر بالإضافة إلى المخاوف الخاصة بإغلاق الخدمة من طرف جوجل. بعد هذه المناقشة المفصلة لأوجه الفرق بين المنصتين دعونا نلخص أبرز مميزات وعيوب كل منصة على هيئة نقاط سريعة. مميزات بلوجر منصة بسيطة جداً وسهلة الاستخدام.التكامل مع خدمات شركة جوجل وأهمها جوجل أدسنس.مجانية تماماً، مع إمكانية دفع مبالغ بسيطة بحسب رغبة المدون مثل امتلاك دومين مدفوع أو الحصول على قالب خاص وأكثر احترافية من القوالب المجانية.توفر مستوى عالي من الحماية والأمانتساعد المدون بالتركيز على تقديم المحتوى بعيداً عن الأمور الفنية الأخرى.عيوب بلوجر عدم وجود إضافاتخيارات محدودة بالنسبة للتصميم والقالبلست المالك الحقيقي للموقععدم وجود دعم فنيخيارات محدودة جداً لتخصيص المدونة والتحكم بهامميزات وورد برس منصة مرنة تمتلك العديد من الوظائف والخيارات المختلفةوجود مجموعة كبيرة جداً من التصاميم والقوالب التي يمكنك الاختيار بينها.إمكانية تخصيص المدونة بشكل كامل، بالإضافة إلى وجود العديد من الإضافاتإمكانية التحكم الكامل بالمدونة بالإضافة إلى حق الملكية.دعم فني شامل والحصول على حل لأي مشكلة قد تواجهكعيوب وورد برس تحتاج بعض الوقت للتعلم والتعامل مع المنصةتحتاج إلى صيانة ومتابعة دوريةتحتاج إلى دفع تكاليف أكبر وتوفير ميزانية محددة منذ البداية لبناء المدونة.الصعوبة في التعامل مع المنصة والتكيف معها في البداية، خصوصاً للمدونين الجدد.والآن وصلنا إلى الإجابة النهائية عن التساؤل الأساسي لهذا الموضوع، ماذا أستخدم بلوجر أم وورد برس؟ في البداية دعونا نتفق بأن تجربة التدوين وتقديم محتوى جيد هي تجربة تستحق الدعم الكامل والتقدير بغض النظر عن المنصة التي ستقوم باستخدامها لهذا الغرض، فالمدونات هي نشاط لطيف وجميل جداً يساعدنا في قضاء بعض الوقت المفيد والممتع لنا وللآخرين، فتقاسم خبراتك ومعرفتك ومهاراتك مع الآخرين والبدء في تكوين شبكة من الأصدقاء والحصول على بعض الأموال هي تجربة مثيرة وممتعة فعلاً. لكن من الجيد أن تتيح لنفسك القليل من الوقت للتفكير واتخاذ القرار المناسب وفقًا لتطلعاتك وأهدافك التي تريد الوصول إليها من خلال مجال التدوين، فإجراء تعديلات ضخمة على مدونتك بعد فترة من الزمن قد يؤثر على تصنيفها داخل محركات البحث بالإضافة إلى انخفاض عدد الزوار لمدونتك. لذلك أرجو أن تساعدك النقاط التالية بالإضافة إلى المقارنة الفائتة في تحديد اختيارك بصورة ملائمة الحالات التي يُفضل فيها استخدام بلوجرالتدوين بشكل منقطع أو غير نظامي، بحيث تقوم بالتدوين بصورة غير رسمية وعلى فترات متباعدة. عدم الحاجة للعديد من المميزات والخصائص والتحكم داخل المدونة، أي أن ما يهمك هو نشر محتوى معين بعيداً عن خيارات التحكم الخاصة بالمدونة. خوض تجربة جديدة وشبه تجريبية في مجال التدوين، وبالتالي يمكنك استخدام منصة بلوجر لفترة معينة وتحديد خطواتك المقبلة اعتماداً على نتائج هذه الفترة. عدم امتلاك المعرفة اللازمة في الأمور التقنية والفنية المتعلقة بإدارة المدونة، ولا تريد تخصيص بعض الوقت للتعلم عدم الرغبة في إنفاق أي مبالغ مادية على المدونة اقتصار المدونة على مجال واحد فقط من مجالات التدوين. الحالات التي يُفضل فيها استخدام وورد برسإنشاء مدونة شاملة ومتكاملة وتحتاج إلى العديد من إمكانيات التخصيص الرغبة في التحكم الكامل بالمدونة، والاحتفاظ بملكية محتويات المدونة بصورة تامة. العمل على المدونة بشكل تجاري، أي وجود نية لبيعها في مرحلة معينة المقدرة على التعامل الفعال مع منصة وورد برس ومعرفة بالأمور الفنية. المقدرة على دفع التكاليف الخاصة بالمدونة الحاجة لوجود خيارات واسعة لقالب المدونة والتصميم الخاص بها. التدوين المتواصل وطويل المدى ووجود رؤية مستقبلية لدى المدون.
    1 نقطة
  4. بعد أن انتهينا من الكائنات والقوالب اللازمة للعبة، سنقوم بإضافة مشهد جديد للمشروع من أجل صنع القائمة الرئيسية، ومن ثم سنقوم بإضافة بعض النوافذ والأزرار التي تسمح للاعب بالتنقل بين اللعبة والقائمة الرئيسية. ملاحظة: يمكن تحميل الملفات المصدرية لكامل هذه السلسلة عبر حساب أكاديمية حسوب على Github، يمكن أيضا تحميل ملف APK لتجريب اللعبة على أجهزة Android. بناء الشاشة الرئيسية والواجهةلإضافة مشهد جديد اضغط Control+N ومن ثم قم بحفظ هذا المشهد باسم MenuScene. آلية التنقل بين المشاهد في محرك Unity تعتمد على رقم كل مشهد في ترتيب بناء اللعبة. هذا الترتيب يمكن الوصول إليه عن طريق القائمة: File > Build Settings النافذة التي ستظهر هي المسؤولة عن ترتيب المراحل في اللعبة وتصديرها. ما يهمنا الآن هو الترتيب. قم بسحب المشهدين MenuScene و GameScene من مستعرض المشروع إلى القائمة Scenes in Build كما ترى في الصورة التالية. من المهم هنا مراعاة الترتيب حيث يأخذ المشهد MenuScene الرقم 0 والمشهد GameScene الرقم 1. بعد إضافة المشاهد قم بإغلاق النافذة حيث سيتم الحفظ تلقائيا. بعد ذلك سنقوم ببناء القائمة الرئيسية للعبة، والتي ستحتوي على زرين هما "ابدأ اللعب" و "خروج". الأول سيعرض للاعب مجموعة من المراحل ليختار أحدها ليلعبها، والثاني سيخرج من البرنامج نهائيا. إضافة لذلك سنضيف نصا على الشاشة وهو اسم اللعبة وليكن "الحيوانات الغاضبة" مثلا. سنكرر هذا النص مرتين بحيث نضع نسخة أمام الأخرى ونصغرها ومن ثم نغير ألوانهما لدرجات مختلفة. هذا سيؤدي لأن يظهر النص الخلفي كأنه ظل. لنر الآن كيف تتم إضافة كائنات واجهة المستخدم في Unity. عناصر واجهة المستخدم في محرك Unity تندرج تحت القائمة: Game Object > UI لنبدأ أولا بصورة خلفية للشاشة الرئيسية. هذه الخلفية تتم إضافتها عن طريق لوح: Game Object > UI > Panel بعد أن تضيف هذا اللوح للمشهد، ستلاحظ أن Unity قد قام بإضافته كإبن لكائن جديد اسمه Canvas، وقام أيضا بإضافة كائن آخر اسمه EventSystem. هذان الكائنان جزء من الآلية المتبعة لبناء واجهة المستخدم، حيث يعتبر Canvas الكائن الجذري لجميع كائنات الواجهة، ويقوم EventSystem بتسهيل عملية استقبال مدخلات اللاعب على عناصر الواجهة بغض النظر عن نوع أداة التحكم التي يستخدمها. ما يهمنا الآن هو الكائن الذي أضفناه نحن وهو Panel والذي ستلاحظ أنه تلقائيا قد ملأ إطار الواجهة كاملا. وأنه يحتوي على مكوّن من نوع Image وهو عبارة عن صورة يتم عرضها على الواجهة. قبل الخوض في خطوات بناء الواجهة لنتعرف معا على الآلية المستخدمة للإبقاء على عناصرها في أماكنها وأحجامها الصحيحة بغض النظر عن قياس الشاشة التي تعرض اللعبة عليها. المكوّن المسؤول عن هذه الآلية هو RectTransform والذي ستراه في كائنات واجهة المستخدم بدلا من المكوّن Transform الموجود في كائنات المشهد الأخرى. هذا المكوّن موضح في الصورة التالية: أكثر ما يعنينا في هذا المكوّن هو متغيرا الحجم Scale على المحورين x و y، إضافة إلى نوع وموقع نقطة الارتكاز لكل عنصر من عناصر واجهة المستخدم. لنتحدث بقليل من التفصيل عن طريقة الارتكاز التي عن طريقها يتم تحديد موقع العنصر على الشاشة ولنطّلع أولا على الصورة التالية التي تمثل الخيارات المتوفرة للارتكاز: أول ما يمكن ملاحظته هو إمكانية تحديد نوع الارتكاز بشكل مختلف أفقيا وعموديا، حيث يمكننا استخدام التمدد stretch والذي يجعل العنصر مربوطا من زواياه الأربع وبالتالي يجب أن تبقى هذه الزوايا دائما في مواقعها بغض النظر عن حجم الشاشة. أما الخيارات الأخرى مثل left ،center ،right أفقيا أو top ،middle ،bottom عموديا، فهي تحدد نقطة ارتكاز العنصر بالنسبة للكائن الأب، فإذا حددت مثلا نقطة الارتكاز بأنها middle center، فإن العنصر سيحافظ على مسافة ثابتة من وسط الكائن الأب بغض النظر عن حجم هذا الأخير وحجم الشاشة. سنستخدم هذا الخيار عند إضافة أزرار القائمة الرئيسية كأبناء لكائن اللوح، وبذلك نضمن وجودها دائما في وسط الشاشة. بالعودة لخلفية القائمة، قم بسحب إحدى صور الخلفية المتوفرة إلى الخانة Source Image لتظهر هذه الصورة في خلفية الشاشة الرئيسية. افتراضيا سيقوم Unity بجعل كائن اللوح شفافا نسبيا مما يظهره بشكل معتم وهذا ما لا نريده. لنقم بإزالة هذه الشفافية عن طريق فتح لوح الألوان بالضغط على المستطيل الأبيض في الخانة Color، ومن ثم تحريك منزلق الشفافية A إلى أقصى اليمين كما ترى هنا: بعد ذلك قم بتغيير اسم الكائن من Panel إلى MainMenu. سنضيف لهذا اللوح ثلاثة أبناء: الأول هو ظل العنوان GameTitleShadow.الثاني والثالث هما الزران "ابدأ اللعب" NewGame و "خروج" Exit.لنبدأ أولا مع ظل العنوان: لماذا أضفت ظل العنوان قبل العنوان نفسه؟ السبب هو أن ترتيب تصيير عناصر واجهة المستخدم يقدّم تصيير الآباء على الأبناء. لذا سنضيف العنوان نفسه GameTitle كابن لظل العنوان GameTitleShadow. بعد ذلك قم بكتابة عنوان اللعبة "الحيوانات الغاضبة" داخل الخانة Text لكل من الظل والابن، ومن ثم غير ألوانهما للأخضر بحيث يبدو الظل أفتح من العنوان نفسه. وأخيرا قم بتصغير العنوان قليلا حتى يظهر الظل من خلاله. (استخدمت خطا يسمى HACEN PROMOTER LT ويمكن تحميله مجانا من الموقع hacen.net). الشكل التالي يوضح الإعدادات الكاملة لنص العنوان وظله: بالنسبة للنص العربي الذي يظهر مقطعا ومن اليسار لليمين: لا تقلق حيال هذا الأمر فالحل موجود وسهل وسنطبقه بعد قليل. أخيرا سيظهر شكل العنوان في الشاشة كما يلي: علينا بعد ذلك أن نقوم بإضافة كائنين من نوع Button أي أزرار، وسنضيفهما بشكل عمودي أحدهما فوق الآخر في منتصف الشاشة. لكن قبل ذلك لنضف بعض المصادر الجديدة ونقوم بإعدادها، وهذه المصادر هي عبارة عن صور ورموز لواجهة المستخدم تم استخراجها من المجموعتين التاليتين: http://www.kenney.nl/assets/ui-packhttp://www.kenney.nl/assets/game-iconsطبعا لن نحتاج لجميع محتويات المجموعتين، لكن سنكتفي بالعناصر الموضحة في الصورة التالية: لنبدأ أولا بإعداد صور الأزرار الستة: الثلاث الزرقاء والثلاث الحمراء. قم باختيار أحد الأزرار من مستعرض المشروع ومن ثم اضغط على الزر Sprite Editor في نافذة الخصائص. ستظهر لك نافذة تحرير الصورة Sprite Editor والتي تمكنك من تقطيع الصورة مستخدما نظام الأجزاء التسعة. هذا النظام يقوم على تقسيم أي صورة نريد استخدامها في واجهة المستخدم إلى 9 مناطق كما هو موضح في الصورة التالية: الهدف من هذا التقسيم هو جعل الصورة قابلة للتمدد أفقيا وعموديا، بحيث تبقى الزوايا دائما بحجمها الأصلي ويتم شد الأجزاء أفقيا وعموديا دون أن يؤثر ذلك سلبا على المظهر. يمكنك من خلال النافذة المذكورة تحريك خطوط التقسيم الخضراء من أجل عزل الزوايا عن بقية الأجزاء التي ستتم عملية شدها أثناء تغيير حجم عنصر الواجهة. ل احظ أن لدينا 3 أزرار من كل لون: الأول مرتفع والثاني عادي والثالث مضغوط للأسفل. الأزرار التي سنضيفها ستعمل كالآتي. في الحالة الافتراضية سنعرض صورة الزر العادي، وحين تمرير الفأرة على الزر سنعرض صورة الزر المرتفع، وحين الضغط عليه سنعرض صورة الزر المنخفض. يمكنك تحقيق هذا السلوك عن طريق ضبط إعدادات المكوّنين Image و Button في كائن الزر وفق القيم التي تراها في الصورة التالية. تذكر أن نقطة الارتكاز للأزرار وللعنوان هي المنتصف أفقيا وعموديا middle center. لاحظ أننا حددنا الصورة الافتراضية للزر عبر المكوّن Image، حيث تلاحظ أن نوع الصورة هو Sliced أي صورة مقسمة إلى 9 أجزاء كما سبق ورأينا. بعدها قمنا بتغيير نوع الانتقال في الزر Transition إلى Sprite Swap بحيث نقوم بتبديل الصورة حين الانتقال بين الحالات. حددنا هنا صورتين أخريين إحداهما لحالة التحديد أو المرور بالفأرة Highlighted Sprite والثانية لحالة الضغط Pressed Sprite. أخيرا ستلاحظ وجود كان ابن لكل زر وهو عبارة عن نص يعرض الكتابة التي نرغب بظهورها على الزر. بالتالي يمكننا استخدام هذه الكائنات للكتابة والحصول في النهاية على النتيجة التالية: حل مشكلة اللغة العربيةمشكلة اللغة العربية في محرك Unity قديمة وقد عانيت معها منذ أول إصدار استخدمته وهو 3.5، وحتى الإصدار الخامس لم تحل هذه المشكلة من قبل الشركة. إلا أن الحل موجود، حيث قمت قبل عدة سنوات بكتابة بريمج يسمى ArabicText، ومبدأ عمله يقوم على عكس ترتيب الأحرف بحيث تصبح من اليمين لليسار كما يفترض، إضافة إلى استبدال رموز الحروف المتقطعة بالمتصلة حسب موقع الحرف في الكلمة. هذا البريمج موجود في المشروع داخل المجلد Assets\Scripts\UI وكل ما عليك هو إضافته لكل كائن من نوع Text (أي العنوان وظل العنوان وكائنات الأبناء النصيّة للأزرار). عند تشغيل اللعبة سيقوم البريمج بعمله في تصحيح النص كما ترى في الصورة التالية. هذا البريمج مجرد أداة مساعدة لا علاقة لها بموضوع الدرس لذا لن أقوم بشرحه هنا، لكن يمكنك الاطلاع عليه في المجلد المذكور إن كنت ترغب بذلك. التفاعل مع عناصر واجهة المستخدمأصبحت القائمة الرئيسية جاهزة الآن، إلا أن ضغطك على الأزرار لن يكون ذا تأثير حيث لا توجد أية أوامر ترتبط بها بعد. ربط الأوامر بالأزرار يتم عن طريق استدعاء داّلة أو أكثر من بريمج محدد عند الضغط على الزر. من أجل ذلك سنقوم بكتابة بريمج لكل أمر من هذه الأوامر. البريمج الأول وهو الأسهل هو برنامج الخروج من اللعبة ExitGameCommand. أمر الخروج يمكن تنفيذه في القائمة الرئيسية وفي مشهد اللعبة على حد سواء، حيث يقوم في الحالة الأولى بإغلاق تطبيق اللعبة نهائيا وفي الثانية بالعودة للقائمة الرئيسية. هذا البريمج موضح في السرد التالي: using UnityEngine; using System.Collections; public class ExitGameCommand : MonoBehaviour { //يتم استدعاؤها مرة واحدة عند بداية التشغيل void Start () { } //يتم استدعاؤها مرة عند تصيير كل إطار void Update () { } //تخرج من اللعبة public void ExitGame() { if (Application.loadedLevel == 0) { //نحن الآن في القائمة الرئيسية، بالتالي أغلق التطبيق نهائيا Application.Quit(); } else if (Application.loadedLevel == 1) { //نحن في مشهد اللعبة، بالتالي عد للقائمة الرئيسية Application.LoadLevel(0); } } }لاحظ أن البريمج يستخدم أوامر مباشرة يتيحها محرك Unity من أجل تحميل المشاهد حسب أرقامها. حيث نعرف المشهد الحالي عن طريق المتغير Application.loadedLevel ونقوم بتحميل المشهد الذي نريد عن طريق الدّالة ()Application.LoadLevel. تذكر أن مشهد القائمة الرئيسية يحمل الرقم 0 ومشهد اللعبة يحمل الرقم 1. أخيرا يمكنك ملاحظة أن الدّالة ()Application.Quit تستخدم لإغلاق التطبيق. الخطوة التالية هي ربط الضغط على الزر "خروج" باستدعاء الدّالة ()ExitGame. الخطوة الأولى هي أن نضيف هذا البريمج إلى المشهد على أي كائن، وليكن كائن الزر نفسه. بعدها نعود للمكوّن Button حيث سنجد في أسفله قائمة بالأوامر التي نريد استدعاءها حين الضغط على هذا الزر وهي مرتبة في القائمة ()OnClick كما في ترى في الصورة التالية. يمكنك إضافة أمر جديد بالضغط على الزر + في أسفل القائمة: عند إضافة أمر جديد للقائمة، عليك تحديد الكائن الذي سينفذ الأمر، ومن ثم تحدد البريمج، وأخيرا تحدد الدّالة داخل هذا البريمج. بما أننا أضفنا البريمج ExitGameCommand على كائن الزر نفسه، علينا أن نسحب الزر "خروج" Exit من الهرمية إلى داخل الخانة الخاصّة بالكائن، ومن ثم نفتح قائمة الأوامر والتي تكون قيمتها الافتراضية No Function حيث نختار البريمج ExitGameCommand ومن ثم الدّالة ()ExitGame كما في الصورة التالية: بالتالي عند الضغط على الزر "خروج" فإن التطبيق سيتم إيقاف تشغيله (ملاحظة: لا يعمل الأمر ()Application.Quit من داخل محرر المحرك، عليك بناء التطبيق وتشغيله منفردا لتجربته). لننتقل الآن للزر الثاني وهو زر بداية اللعب. عند الضغط عليه سيعرض نافذة جديدة تحتوي على المراحل الموجودة بحيث يتسنى للاعب اختيار مرحلة منها. من أجل ذلك علينا أولا بناء نافذة مستقلة تحتوي على أزرار المراحل. مبدئيا سنكتفي بزرين يحملان الأرقام 1 و 2 حيث سيكون لدينا مرحلتان فقط في هذا المثال. إضافة لذلك سيكون هناك زر ثالث يحمل الرمز X يقوم بإغلاق النافذة والعودة للقائمة الرئيسية مرة أخرى. لعمل النافذة المذكورة قم بإضافة لوح جديد Panel واحرص على أن يكون ترتيبه بين أبناء الكائن Canvas تحت اللوح الأول الخاص بالقائمة الرئيسية MainMenu. هذا الترتيب مهم حيث أن الكائنات في أسفل الهرمية تظهر على الشاشة أمام الكائنات التي في الأعلى، وهذا ما نريده: أن تظهر هذه النافذة حين عرضها أمام القائمة الرئيسية. قم بتغيير لون اللوح للأسود مع الإبقاء على الشفافية، ومن ثم غير اسمه إلى LevelSelector وحجمه على المحورين الأفقي والعمودي إلى 0.9. هذا سيجعل شكله يبدو كالآتي (لاحظ أيضا ترتيب العناصر في الهرمية على اليسار). ما يلزمنا الآن هو ترتيب الأزرار داخل هذه النافذة على شكل جدول مكون من صفوف وأعمدة، بحيث تكون هذه الأزرار متساوية في الحجم وبينها مسافات ثابتة. لحسن الحظ فإن Unity يسهل علينا هذه المهمة عن طريق توفير المكوّن GridLayoutGroup. هذا المكوّن يقوم بترتيب العناصر داخل اللوح بالطريقة التي ذكرتها للتو، وهو يحتوي على عدة متغيرات كما ترى في هذه الصورة. انتبه لأن إضافة مكوّن كهذا يلغي تأثير طريقة الارتكاز التي تحدثنا عنها سابقا، حيث يصبح المكوّن هو المسؤول عن المواقع والأحجام الخاصة بالعناصر التي يحتويها. المتغيرات الأربع تحت البند Padding تحدد حجم الهوامش من الجهات الأربعة بالبكسل، وهنا اخترت القيمة 32. بعدها نقوم بتحديد حجم كل عنصر أفقيا وعموديا عن طريق المتغير Cell Size وأخيرا نحدد المسافات بين العناصر وهي هنا 16. باقي المتغيرات يمكن تركها على قيمها الافتراضية. بعد هذا علينا أن نصنع قالبا لزر المرحلة بحيث يمكننا إضافته عدة مرات مع تغيير المرحلة التي سيتم تحميلها بتغير الزر. الزر المذكور شبيه بالأزرار التي أضفناها حتى الآن من حيث آلية العرض بتغيير الصور، لكن الذي سيتغير هو النص حيث سيحمل كل زر رقم المرحلة (1، 2، 3، …) إضافة لتغيير البريمج الذي سيستقبل الأمر. بعد صنع قالب الزر حسب الوصف السابق، سنضيف عليه البريمج LevelButton، وهو موضح في السرد التالي: using UnityEngine; using System.Collections; public class LevelButton : MonoBehaviour { //تستدعى مرة واحدة عند بداية التشغيل void Start () { } //تستدعى مرة عند تصيير كل إطار void Update () { } //تقوم ببدء اللعبة مستخدمة رقم المرحلة المزود public void StartLevel(int levelIndex) { //SelectedLevelخزن رقم المرحلة في الإعدادات في الخانة PlayerPrefs.SetInt("SelectedLevel", levelIndex); //قم بتحميل المشهد رقم 1 وهو مشهد اللعبة Application.LoadLevel(1); } } يعمل هذا البريمج عند استدعاء الدّالة ()StartLevel على تحميل مشهد اللعبة (المشهد رقم 1)، لكن قبل ذلك يقوم بتخزين رقم المرحلة التي يجب تحميلها في إعدادات اللاعب. هذه الإعدادات يتم تخزينها على القرص الصلب أي أنها دائمة وليست في الذاكرة. بالتالي فإن القيمة التي تخزن فيها ستبقى محفوظة حين الانتقال بين مشهدي القائمة واللعبة. يمكن الوصول لإعدادات اللاعب عبر PlayerPrefs والتي تحتوي على دوالّ لتخزين وقراءة بيانات بأنواع مختلفة. هنا مثلا استخدمنا الدّالة ()SetInt والتي تقوم بتخزين عدد صحيح، واخترنا اسما للقيمة التي قمنا بتخزينها وهي SelectedLevel. سنرى لاحقا كيف يمكننا قراءة هذه القيمة وتحميل المرحلة بناء عليها. ما علينا فعله الآن هو إضافة عنصر جديد للقائمة ()OnClick ومن ثم سحب الزر نفسه لخانة الكائن تماما كما فعلنا مع زر الخروج من اللعبة. بعدها سنختار البريمج LevelButton من القائمة ومن ثم نختار الدّالة ()StartLevel. الشيء الجديد الذي ستلاحظه هذه المرة هو وجود خانة لإدخال قيمة المتغير levelIndex، حيث أن هذه الدّالة تأخذ متغيرا بخلاف ()ExitGame التي تعاملنا معها في زر الخروج من اللعبة. لاحظ الصورة التالية: سنقوم بعمل زرين من هذا القالب. أحدهما سيحمل النص 1 والقيمة 0 للدّالة ()StartLevel، والآخر سيحمل النص 2 والقيمة 1 للدّالة ()StartLevel. هذان الزران سنقوم بإضافتهما كأبناء للكائن LevelSelector. بعد إضافة الأزرار بالترتيب الصحيح سيتكفل المكوّن Grid Layout Group بوضع كل منهما في الموقع الصحيح وبالحجم الصحيح. قبل الانتقال للحديث عن الزر الثالث وهو زر إغلاق النافذة، لنقم بكتابة البريمج الذي سيحول هذا اللوح إلى نافذة يمكن فتحها وإغلاقها. هذا البريمج هو UIDialog وهو موضح في السرد التالي: using UnityEngine; using System.Collections; public class UIDialog : MonoBehaviour { //قياس النافذة حين تكون مفتوحة public Vector2 maxSize = Vector2.one; //هل تتمدد النافذة حاليا؟ private bool expanding = false; //هل تتقلص النافذة حاليا؟ private bool shrinking = false; //تستدعى مرة واحدة عند بداية التشغيل void Start () { //أخف النافذة مبدئيا transform.localScale = Vector2.zero; } //تستدعى مرة عند تصيير كل إطار void Update () { //اجلب القياس الحالي للنافذة Vector2 scale = transform.localScale; //احسب القياس الجديد بناء على حالة النافذة if (expanding) { scale = Vector2.Lerp(scale, maxSize, Time.deltaTime * 10); //تحقق من الوصول للمنطقة الميتة if (Vector2.Distance(scale, maxSize) < 0.01f) { scale = maxSize; expanding = false; } } else if (shrinking) { scale = Vector2.Lerp(scale, Vector2.zero, Time.deltaTime * 10); //تحقق من الوصول للمنطقة الميتة if (Vector2.Distance(scale, Vector2.zero) < 0.01f) { scale = Vector2.zero; shrinking = false; } } //قم بتغيير القياس للقيمة الجديدة transform.localScale = scale; } //تقوم بفتح النافذة public void Show() { expanding = true; shrinking = false; } //تقوم بإغلاق النافذة public void Hide() { shrinking = true; expanding = false; } } يعتمد مبدأ عمل هذا البريمج على قيمة المتغيرين expanding و shrinking، حيث يحددان ما إذا كانت النافذة تتقلص إلى أن تصل لمرحلة الإغلاق أو إن كانت تتمدد حتى تصل لمرحلة الفتح. حين فتح النافذة يتم إيصال قياسها لقيمة الحد الأعلى المحددة في maxSize، أما حين الإغلاق يجب أن تصل قيمة القياس لصفر حتى تختفي النافذة تماما. لاحظ أن تمدد وتقلص النافذة يتم بشكل سلس عبر ()Vector2.Lerp والتي تستخدم الاستيفاء الذي شرحناه سابقا. افتراضيا يتم ضبط قياس النافذة على Vector2.zero مما يؤدي لأن تبدأ مختفية (مغلقة)، وسيتم إظهارها (فتحها) حين استدعاء الدّالة ()Show، كما يمكن استدعاء ()Hide لإخفائها (أو إغلاقها) ثانية. بعد إضافة هذا البريمج للكائن LevelSelector ستلاحظ أنه يختفي تلقائيا عند تشغيل اللعبة. بقي علينا أن نظهره حين يضغط اللاعب على "ابدأ اللعب" ونخفيه حين يضغط اللاعب على الزر X الذي سنضيفه لهذه النافذة. لنبدأ بعمل زر إغلاق النافذة مستخدمين الصور الثلاث للزر الأحمر. بعد إضافة هذا الزر سنقوم بحذف مكوّن النص من الكائن الإبن Text ونضيف بدلا منه كائن صورة Image كما هو موضح في الصورة التالية: بعدها سنقوم بسحب الصورة cross والموجودة في مجموعة رسوم واجهة المستخدم في المجلد Assets\Kenney.nl\UI Pack إلى الخانة Source Image مما يجعل الشكل النهائي لنافذة اختيار المرحلة يبدو كالتالي: بالنسبة لزر الإغلاق الأحمر سيكون الكائن الهدف لتنفيذ الأمر هو النافذة LevelSelector بالتالي سنسحبها لعنصر جديد نضيفه للقائمة ()OnClick، ومن ثم سنقوم بتحديد البريمج UIDialog والدّالة ()Hide كأمر يتم تنفيذه حين الضغط على هذا الزر. بعدها سنعود للزر الأول في القائمة الرئيسية وهو "ابدأ اللعب" ونضيف له النافذة LevelSelector كهدف للأمر والبريمج UIDialog أيضا، إلا أن الدّالة هذه المرة ستكون ()Show حيث أن الضغط على هذا الزر سيظهر النافذة. الشكل النهائي للقائمة ()OnClick في هذين الزرين سيبدو كالآتي: لو قمت بتشغيل اللعبة الآن ستلاحظ أن الضغط على "ابدأ اللعب" سيظهر لك نافذة اختيار المراحل، ومن هناك يمكنك الضغط على الزر 1 أو 2 لتحميل المرحلة التي تريدها. بطبيعة الحال لا توجد أي مراحل حاليا، لذا سيأخذك الضغط على هذه الأزرار إلى مشهد اللعبة الفارغ. ما نريد عمله الآن هو إضافة زر في مشهد اللعبة يمكّن اللاعب من العودة للقائمة الرئيسية. كل ما علينا فعله هو إضافة زر صغير في أعلى يمين الشاشة يحمل إشارة X ، وعند الضغط عليه سيظهر للاعب نافذة صغيرة يسأله من خلالها إن كان يريد أن يعود للقائمة الرئيسية. بالنظر لموقع الزر المفترض، علينا مراعاة أن تكون نقطة ارتكازه في أعلى اليمين، وذلك حتى يبقى على مسافة ثابتة من أعلى يمين الشاشة بغض النظر عن حجمها. هذا الزر لا يختلف عن التي أنشأناها سابقا سوى أنه أصغر حجما. سنعود لاحقا لإضافة الأمر الخاص بهذا الزر. الصورة التالية توضح موقعه في الشاشة، ويمكنك ملاحظة نقطة ارتكازه في أعلى اليمين: بعد إضافة هذا الزر سنضيف نافذة حوار جديدة كالتي أضفناها في القائمة الرئيسية لاختيار المراحل، إلا أنها ستكون أصغر حجما وتحتوي على سؤال لتأكيد العودة للقائمة الرئيسية، إضافة لزرين للاختيار بين نعم و لا. الصورة أدناه تمثل الشكل والحجم المفترضين لنافذة كهذه. (لاحظ الهرمية في يسار الصورة لترى مم تتكون هذه النافذة): الزر الذي يحمل علامة ✓ سيعود باللاعب للقائمة الرئيسية، بينما الآخر سيقوم بإغلاق نافذة الحوار هذه مع البقاء في مشهد اللعبة• من أجل العودة للقائمة الرئيسية سنحتاج مرة أخرى للبريمج ExitGameCommand ولكننا سنضيفه هذه المرة على الكائن الجذري للواجهة Canvas حيث سنحتاج لاستدعائه من أكثر من نافذة كما سنرى. بعد إضافة البريمج ستكون الدّالة ()ExitGame المعرفة فيه هي الأمر الذي سينفذ حين الضغط على الزر ✓، بينما سيكون Canvas هو الكائن الهدف حيث أنه من يحمل هذا البريمج. بالتالي سيكون شكل القائمة ()OnClick كما يلي: تذكر أن الدّالة ()ExitGame تعود للقائمة الرئيسية في حال تم استدعاؤها من مشهد اللعبة. بعد ذلك علينا أن نضيف لهذه النافذة الصغيرة البريمج UIDialog بحيث تبدأ مختفية وتظهر حين استدعاء ()Show. بطبيعة الحال سيكون زر الخروج الموجود أعلى يمين الشاشة هو من يستدعي الدّالة ()Show عند الضغط عليه، بينما سيكون زر الإغلاق X الموجود على النافذة نفسها هو من يستدعي لها الدّالة ()Hide. أعتقد أنه إلى هنا أصبحت فكرة ربط الضغط على الزر بكائن معين واستدعاء دالّة من بريمج عليه واضحة، لذا لن أعاود شرحها بالصور وسأكتفي بذكر الارتباطات اللازمة. بهذا تكون القائمة الرئيسية للعبة جاهزة، ويمكننا الانتقال بينها وبين مشهد اللعبة. بقي علينا أن نجهز المراحل وما يتعلق بحالة اللعبة حتى تصبح لعبتنا مكتملة ويمكننا لعبها. إضافة المراحل والتنقل بينهابعد أن أصبحت عناصر بناء المرحلة مكتملة لدينا إضافة للشاشة الرئيسية وبعض عناصر واجهة المستخدم، سنقوم الآن بصنع مرحلتين لتجربة تتابع المراحل إضافة للتنقل بينها وبين الشاشة الرئيسية. يمكنك أن تستخدم أي مقذوفات ترغب بها وأي وحدات بنائية وخصوم. المهم هو أن تتبع بناء هرميا محددا حتى تكون جميع المراحل متوافقة في الشكل. الشكل التالي يوضح مثالا على مرحلة صغيرة ومما تتكون هرمية المرحلة. لاحظ أن المرحلة تتكون من 3 عناصر: القاذف، والعناصر البنائية والوحوش والتي تندرج تحت الكائن الفارغ Elements، وأخيرا المقذوفات والتي تندرج تحت الكائن الفارغ Projectiles. لاحظ أيضا أن جميع العناصر على مستوى أفقي واحد وهو المستوى الذي ستظهر فيه الأرضية. عند بناء المرحلة، راعي أن يكون الكائن الفارغ الأب للمرحلة (Level1 في الصورة السابقة) في منتصف المشهد، وأن يكون أسفل المرحلة على مستوى الأرضية التي ستظهر. بعد بناء المرحلة يجب أن نحولها كاملة إلى قالب واحد كبير، لكن قبل ذلك علينا إضافة بريمج بسيط لكائن المرحلة الجذري. هذا البريمج مهمته تحديد رقم الخلفية التي ستظهر حين تحميل المرحلة ويسمى GameLevel وهو موضح في السرد التالي: using UnityEngine; using System.Collections; public class GameLevel : MonoBehaviour { //صورة الخلفية التي ستظهر عند تحميل المرحلة public int backgroundIndex; //تستدعى مرة واحدة عند بداية التشغيل void Start () { } //يتم استدعاؤها مرة عند تصيير كل إطار void Update () { } }المهم في هذا البريمج هو أن نعرف أي صورة خلفية يجب أن نختار عند تحميل المرحلة، عدا عن ذلك فمحتويات المرحلة كفيلة بالتحكم بحالة اللعبة كما سنرى بعد قليل. بعد تجهيز المراحل على شكل قوالب، سنقوم بعمل بريمج جديد لتخزين هذه القوالب ومن ثم إنشائها حسب الحاجة، أي حسب المرحلة التي يتم تحميلها. هذا البريمج يسمى GameLevelLoader وسنقوم بإضافته للكائن الجذري في المشهد. السرد التالي يوضح هذا البريمج: using UnityEngine; using System.Collections; public class GameLevelLoader : MonoBehaviour { //تقوم بتخزين القوالب الخاصة بجميع المراحل public GameLevel[] allLevels; //العنصر الخاص بالمرحلة المحملة حاليا private int currentLevel = -1; //مرجع لبريمج التحكم بالخلفية private BackgroundManager bgManager; //مرجع لبريمج أمر الخروج من اللعبة ExitGameCommand egc; //يتم استدعاؤها مرة عند بداية التشغيل void Start () { bgManager = GetComponent<BackgroundManager>(); egc = FindObjectOfType<ExitGameCommand>(); } //يتم استدعاءها مرة عند تصيير كل إطار لكن في وقت متأخر void LateUpdate () { if (currentLevel == -1) { //قم بتحميل المرحلة التي تم اختيارها من القائمة الرئيسية //إذا لم تكن هناك أي مرحلة، قم تلقائيا بتحميل المرحلة الأولى int selectedLevel = PlayerPrefs.GetInt("SelectedLevel", 0); LoadLevel(selectedLevel); } } //تقوم بتحميل المرحلة المحددة public void LoadLevel(int index) { //قم بالتأكد من وجود المرحلة المطلوبة في المصفوفة //إن لم تكن موجودة فعد للقائمة الرئيسية if (index < 0 || index >= allLevels.Length) { egc.ExitGame(); return; } //قم بالبحث عن المرحلة المحملة حاليا وتدميرها إن وجدت GameLevel current = FindObjectOfType<GameLevel>(); if (current != null) { Destroy(current.gameObject); } //قم بإنشاء المرحلة الجديدة مستخدما قالبها GameObject newLevelObject = (GameObject)Instantiate(allLevels[index].gameObject); GameLevel newLevelScript = newLevelObject.GetComponent<GameLevel>(); //قم بتحديد الكائن الأب والموقع للقائمة الجديدة newLevelObject.transform.parent = transform; newLevelObject.transform.position = Vector2.zero; //قم بتغيير رقم العنصر الخاص بالمرحلة الحالية currentLevel = index; //قم بتغيير الخلفية للصورة المحددة في المرحلة الجديدة bgManager.ChangeBackground(newLevelScript.backgroundIndex); //قم بإبلاغ البريمجات الأخرى بان هناك مرحلة جديدة تم تحميلها للتو SendMessage("NewLevelLoaded"); } //تقوم بإعادة لعب المرحلة الحالية public void RestartCurrentLevel() { if (currentLevel != -1) { LoadLevel(currentLevel); } } //تقوم بتحميل المرحلة التالية في المصفوفة public void LoadNextLevel() { LoadLevel(currentLevel + 1); } }هذا البريمج يحتوي على متغير عام واحد فقط وهو المصفوفة allLevels التي تحتوي على قوالب جميع مراحل اللعبة. لاحظ أن تحميل المرحلة يتم تأخيره باستخدام الدّالة ()LateUpdate وذلك حتى نضمن أن جميع البريمجات الأخرى قد بدأت العمل ويمكننا الاعتماد عليها مثل البريمج BackgroundManager والذي سنستخدمه لتغيير صورة الخلفية للصورة المحددة في البريمج GameLevel الخاص بالمرحلة الحالية. يبحث البريمج مبدئيا عن متغير مخزن في إعدادات اللاعب ويحمل الاسم SelectedLevel. كما تذكر فإن هذا المتغير يفترض أن يتم تخزينه من قبل البريمج LevelButton والخاص بأزرار المراحل في القائمة الرئيسية. إذا لم يوجد هذا المتغير يتم إرجاع القيمة الافتراضية وهي 0 بالتالي يتم تحميل المرحلة الأولى في المصفوفة. الدّالة ()LoadLevel هي الأساسية في هذا البريمج حيث نعطيها رقم المرحلة التي نرغب بتحميلها من المصفوفة، فإذا لم يكن رقم المرحلة المحددة صالحا ستعود للقائمة الرئيسية للعبة. أما إذا كان الرقم صحيحا فإنها تتأكد من عدم وجود مرحلة محملة حاليا عن طريق البحث عن بريمج من نوع GameLevel، إذا وجدت هذا البريمج فإنها تقوم بتدمير الكائن الذي يحمله، وبما أن الكائن هو جذر عناصر المرحلة جميعها، سيتم تدمير جميع هذه العناصر أيضا، مما يجعل المشهد فارغا وجاهزا لاستقبال المرحلة الجديدة. هذه المرحلة يتم إنشاؤها عن طريق استخراج القالب الموجود في الموقع المحدد index ومن ثم بناء كائن منه. هذا الكائن تتم إضافته كابن للكائن الجذري لمشهد اللعبة كما يتم وضعه في منتصف المشهد. بعدها يتم تحديث قيمة currentLevel إلى المرحلة الجديدة وتغيير الخلفية باستخدام المتغير backgroundIndex الخاص ببريمج المرحلة الجديدة. أخيرا تقوم الدّالة بإرسال الرسالة NewLevelLoaded حتى تخبر البريمجات الأخرى بأن المرحلة الجديدة تم تحميلها. إضافة لذلك لدينا الدّالتان ()RestartCurrentLevel والتي تقوم بإعادة تحميل المرحلة الحالية، و ()LoadNextLevel والتي تقوم بتحميل المرحلة التالية في الترتيب في المصفوفة. حالة اللعبة وشروط الفوز والخسارةبعد أن أصبحت جميع محتويات اللعبة مكتملة بما فيها المراحل، بقي علينا أن نضيف شروط الفوز والخسارة وما يترتب عليها من تغيير على حالة اللعبة. في ألعاب من هذا النوع يفوز اللاعب إذا قام بتدمير جميع الخصوم وهي الوحوش في لعبتنا هذه، ويخسر إذا استنفد جميع ما لديه من مقذوفات دون تدمير الخصوم. تذكر أننا سابقا أضفنا البريمج Enemy لكائنات الوحوش والذي يرسل للكائن الجذري الرسالة EnemyDestroyed حين يتم تدمير الكائن، كما أن بريمج المقلاع Launcher يقوم بإرسال الرسالة ProjectilesConsumed عندما يتم إطلاق كافة المقذوفات التي كانت بحوزة اللاعب. ما يتوجب علينا هو كتابة بريمج يستقبل هاتين الرسالتين وبناء عليهما يقوم بفحص حالة اللعبة والتأكد من فوز أو خسارة اللاعب. هذا البريمج هو GameStateManager وهو موضح في السرد التالي: using UnityEngine; using System.Collections; public class GameStateManager : MonoBehaviour { //متغير لمعرفة ما إذا فاز اللاعب بالمرحلة private bool playerWon; //تستدعى مرة واحدة عند بداية التشغيل void Start () { playerWon = false; } //تستدعى مرة عند تصيير كل إطار void Update () { } //والتي ترسلها EnemyDestroyed تستقبل الرسالة //كائنات الوحوش عند تدميرها void EnemyDestroyed() { //قم بعد الوحوش المتبقية في المشهد Enemy[] enemies = FindObjectsOfType<Enemy>(); if (enemies.Length <= 1) { //تم تدمير جميع الوحوش، أي فاز اللاعب بالمرحلة SendMessage("PlayerWon"); playerWon = true; } } //تقوم باستقبال رسالة استنفاد اللاعب //لجميع المقذوفات التي كانت بحوزته void ProjectilesConsumed() { if (!playerWon) { SendMessage("PlayerLost"); } } //التي تعني NewLevelLoaded تستقبل الرسالة //false إلى playerWon أنه تم تحميل مرحلة جديدة، وبناء عليها تعيد void NewLevelLoaded() { playerWon = false; } }في كل مرة يتم فيها تدمير أحد الوحوش يستقبل هذا البريمج الرسالة EnemyDestroyed ومن ثم يقوم بعد الوحوش المتبقية في المشهد عن طريق البحث عن البريمج Enemy. لاحظ أن وجود بريمج واحد في المشهد يعني أن اللاعب قد فاز فكيف هذا؟ الجواب هو أن تدمير الكائن لا يتم مباشرة عند استدعاء ()Destroy، وإنما يتم تأخيره حتى نهاية الإطار الحالي. لذا فمن المحتمل أن تصل الرسالة ويتم بعدها البحث عن بريمج من نوع Enemy وإيجاده. فإن كان العدد واحدا فهذا يعني أنه الأخير المتبقي في المشهد واستقبال الرسالة يعني أنه تم تدميره. لذا نعرف هنا بأن اللاعب قد فاز في المرحلة ويتم إرسال الرسالة PlayerWon وتغيير قيمة playerWon إلى true. أما استقبال الرسالة ProjectilesConsumed فيعني أن آخر مقذوف أطلقه اللاعب قد انقضت مدة بقائه وتم حذفه من المشهد، وأن القاذف لم يجد أي مقذوفات أخرى. حينها تقوم الدّالة ()ProjectilesConsumed باستقبال الرسالة ومن ثم التأكد من أن اللاعب لم يفز باللعبة حتى الآن – أي لم يدمر جميع الوحوش – وفي هذه الحالة تحكم بخسارة اللاعب عن طريق إرسال الرسالة PlayerLost. السؤال الآن هو ماذا سيحدث عندما يتم إرسال PlayerWon أو PlayerLost؟ الجواب هو أن كل رسالة ستقوم بإظهار نافذة حوار مختلفة. ففي حال فوز اللاعب ستظهر له نافذة تخيره بين إعادة اللعب وبين التقدم للمرحلة التالية واسمها WinDialog، وفي حالة الخسارة تظهر نافذة أخرى تخيره بين إعادة المرحلة والخروج للقائمة الرئيسية واسمها LoseDialog. هاتان النافذتان ستكونان كالنوافذ السابقة عبارة عن كائنات Panel مضاف عليها البريمج UIDialog وتحتوي كل منهما على نص وزرين تماما كنافذة تأكيد العودة للقائمة الرئيسية. بداية لنقم ببناء هاتين النافذتين وتحديد الوظائف الخاصة بأزرارها. لنبدأ مع نافذة الفوز والتي ستبدو بالشكل التالي: المشترك في الزرين الموجودين على النافذة هو أن الهدف لأوامرهما هو الكائن الجذري لمشهد اللعبة SceneRoot وتحديدا بريمج تحميل المراحل GameLevelLoader. أما الفرق فهو أن الزر الأيمن سيقوم باستدعاء الدّالة ()LoadNextLevel عند الضغط عليه مما ينقل اللاعب للمرحلة التالية، بينما الزر الأيسر يستدعي عند الضغط عليه الدّالة ()RestartCurrentLevel مما يؤدي لإعادة تحميل المرحلة الحالية. علاوة على ذلك، يجب أن يقوم كلا هذين الزرين أيضا بإخفاء النافذة حتى يتمكن اللاعب من متابعة اللعب سواء في المرحلة التالية أو الحالية. من أجل ذلك يجب أن نضيف لكل منهما هدفا آخر وهو النافذة نفسها، حيث سيقوم كلاهما باستدعاء الدّالة ()Hide من البريمج UIDialog. لاحظ أن ()OnClick هي عبارة عن قائمة كما ذكرنا سابقا، بالتالي يمكنها أن تستدعي أكثر من أمر من أكثر من كائن وبريمج كما هو مبين في الصورة التالية: النافذة الأخرى وهي التي تظهر في حال الخسارة تبدو بهذا الشكل: الزر الأيمن وهو زر العودة للقائمة الرئيسية سيكون الكائن الهدف بالنسبة له هو الكائن الجذري للواجهة Canvas وتحديدا البريمج ExitGameCommand والدّالة ()ExitGame. أما الزر الأيسر فتماما كما في نافذة الفوز يستدعي الدّالة ()RestartCurrentLevel ويقوم أيضا باستدعاء ()Hide من البريمج UIDialog الموجود على كائن نافذة الخسارة LoseDialog. بقي علينا الآن أن نربط بين الرسائل التي يرسلها GameStateManager وبين ظهور هذه النوافذ. المشكلة التي تواجهنا هنا هي أن النوافذ تقع تحت كائن جذري مختلف عن الكائن الجذري للمشهد، وكل منهما ذو وظيفة محددة ولا يجب أن تتداخل هذه الوظائف كثيرا. من أجل ذلك سنقوم بكتابة بريمج يعمل على استقبال الرسائل من GameStateManager ومن ثم استدعاء دوال من بريمج آخر سنضيفه على Canvas بحيث يشكل هذان البريمجان معا جسر التواصل بين واجهة المستخدم ومنطق اللعبة. لنبدأ مع البريمج الأول الذي سنضيفه على جذر واجهة المستخدم Canvas وهو GameStateDialogs الموضح في السرد التالي: using UnityEngine; using System.Collections; public class GameStateDialogs : MonoBehaviour { //متغير لتخزين نافذة فوز اللاعب public UIDialog winDialog; //متغير لتخزين نافذة خسارة اللاعب public UIDialog loseDialog; //تستدعى مرة واحدة عن بداية التشغيل void Start () { } //تستدعى مرة عند تصيير كل إطار void Update () { } //تعرض نافذة فوز اللاعب public void ShowWinDialog() { winDialog.Show(); } //تعرض نافذة خسارة اللاعب public void ShowLoseDialog() { loseDialog.Show(); } } كل ما يفعله هذا البريمج البسيط هو تخزين نافذتي الفوز والخسارة في مراجع ومن ثم عرضها عند استدعاء الدّالة ()ShowWindDialog أو الدّالة ()ShowLoseDialog. بعد إضافة هذا البريمج للجذر Canvas عليك أن تسحب كلا من نافذة الفوز ونافذة الخسارة لخانة المتغير المناسب لها كما ترى في الصورة التالية: لننتقل الآن للطرف الآخر وهو جذر المشهد SceneRoot والذي سنضيف عليه البريمج GameStateReporter الموضح في السرد التالي: using UnityEngine; using System.Collections; public class GameStateReporter : MonoBehaviour { //مرجع لبريمج عرض نافذتي الفوز والخسارة GameStateDialogs gsDialogs; //تستدعى مرة عند بداية التشغيل void Start () { gsDialogs = FindObjectOfType<GameStateDialogs>(); } //تستدعى مرة عند تصيير كل إطار void Update () { } //تستقبل رسالة فوز اللاعب void PlayerWon() { gsDialogs.ShowWinDialog(); } //تستقبل رسالة عرض اللاعب void PlayerLost() { gsDialogs.ShowLoseDialog(); } }كل ما يفعله هذا البريمج هو استقبال رسائل الفوز والخسارة ومن ثم استدعاء الدّالة التي تعرض النافذة المناسبة من البريمج GameStateDialog. بهذا تكون لعبتنا قد اكتملت على جهاز الحاسب ويمكن تشغيلها ولعب المراحل والفوز والخسارة بها. بقي علينا أن ننقلها للهواتف الذكية وشاشات اللمس، وهي خطوة بسيطة نظرا للطريقة المنظمة التي اتبعناها في استقبال المدخلات.
    1 نقطة
  5. ​لماذا لا تقوم بإنشاء مدونة على Wordpress.com إذا كنت لا تريد الخوض في أمور البرمجة وغيرها؟ يمكنك ربط اسم نطاق خاص، واستعمال قالب مجاني أو شراء قالب خاص أما إذا كنت تريد التحكم بزمام الأمور على استضافة خاصة بك، فلا مجال من التهرب من تعلم كيفية تنصيب ووردبريس وقاعدة بيانات وربطهما، وتعلم كيفية تنصيب قالب خاص يدويا، على الأقل... كخيار آخر، قد يهمك التعرف على static site generators يُمكنك متابعة الدرسين الذين قمت بترجمتهما، ستجد فيهما مثالا حيا للناتج النهائي: http://academy.hsoub.com/code/ruby/مدونتك-الخاصة-باستعمال-jekyll-الجزء-الأول-r39/ http://academy.hsoub.com/code/ruby/مدونتك-الخاصة-باستعمال-jekyll-الجزء-الثاني-r45/
    1 نقطة
  6. هذا شرف لي صديقي محمود، انتظر باقي السلسلة سنكمل شرح المكونات التسعة مع مثال عملي ليكون لديك بالنهاية كورس كامل مبسط اتمنى أن يصل لكل رواد الأعمال العرب الذين يخططون لإطلاق شركة ناشئة
    1 نقطة
×
×
  • أضف...