post

لمحة حول ميزات 2018.1 Unity النسخة التجريبية

السلام عليكم ورحمة الله وبركاته ، طرحت شركة unity تسخة تجريبية للإصدار الجديد لمحركها لعام 2018 تحت رقم إصدار 2018.1 ، حيث قامت بذكر أهم الأجزاء التي سيحتويه والتي ستكون مضمنة في النسخة النهائية من الإصدار، حيث سيحتوي الإصدار على الكثير من التحسينات والإضافات الجديدة مثل نظام التفاصيل الزائدة Tessellation for Metal و إستحدام كرت الشاشة في الإضاءة غير المباشرة GPU Instancing ، إضافة منظور ال PS4 لنافذة Game Resolution وتحسينات على نظام الجزئيات Particle system والتحسين على بلجت التصدير FBX وغيرها الكثير. وهنا ذكر لأهم الميزات لهذه النسخة :

* نظام تصيير جديد  Scriptable Render Pipeline

حيث قدمت الشركة في هذه النسخة نظام إظهار آني real-time rendering ذو الإختصار SRP ، حيث أنه تم تصميمه خصيصاً لمواكبة الأجهزة الحديثة وكروت الشاشة السريعة جداً ، فبدلاً من النظر إلى ملايين أسطر البرمجة بلغة السي ++ أصبح الآن بالإمكان التعامل معه بواسطة لغة السي شارب و عمل شيدرز سريع للمواد Material Shaders بسهولة. حيث ستقوم الشركة بوضع أنظمة جاهزة Templates تستطيع من خلالها إختيار طريقة العرض التي ستلائم مشروعك بتقسيمين : Lightweight  حيث سيكون مثالي لأجهزة الموبايل والأجهزة الخفيفة و High-Definition حيث سيكون ملائم للمواصفات العالية جداً مثل أجهزة الحاسوب وغيرها.

* أداة visual shader creation

حيث تم تطوير هذه الأداة خصيصاً للمصممين والرسامين ، فبواسطة هذه الأداة يمكنك عمل مواد معقدة من خلال طريقة ال Graph Nodes  ،  فبدلاً من كتابة Shaders خاصة بواسطة الأسطر البرمجية أصبح بإمكانك عمل Shader كامل بواسطة ربط ال Nodes ببعضها لتحصل على الشكل النهائي الذي تريده ، وهذه الميزة كانت من أكثر الميزات طلباً من جمهور المطورين وتم الإستجابة لهم من الشركة .

* قريباً C# Job System

تحسينات وتطويرات ستكون متاحة قريباً تزيد من كفاءة اللعبة خاصة لمن يقوم بكتابة الأسطر البرمجة بلغة السي شارب

* تعديل على المواصفات الدنيا System Requirements

قامت الشركة بحذف العديد من الأمور التي كانت ضمنياً متاحة داخل المحرك وذلك بهدف جعل المحرك أكثر مرونة، وتركت باب الحصول على الميزات السابقة متاحة بتنزيلها منفصلة عن المحرك ، فقد قامت بفصل إمكانية إستيراد مواد Substance Designer materials وفصل Wii U  و فصل Windows XP in standalone player و فصل محرر MonoDevelop حيث أنها تنصح بإستخدام فيجوال ستوديو من شركة مايكروسوفت ، وقامت بزيادة مواصفات macOS إلى النسخة 10.11 على الأقل ، وهي تعمل على فصل نظام الجزئيات التقليدي  Legacy Particle System في النسخة القادمة وإستبداله بنظام جديد

يجدر بالذكر أن النسخة هي نسخة تجريبية ويمكنك تنزيلها والمشاركة بها من خلال هذا الرابط : https://unity3d.com/unity/beta

 

 

post

#19 مواضيع متقدمة عن Classes – البرمجة بواسطة #C

رمز فتح مرحلة هذا الدرس في تطبيق طورني : MRE

تَعلُمُ البرمجةِ للمبتدئينَ كلياً بواسطةِ #C –  مواضيع متقدمة حول الفئات Classes

مواضيع متقدمة حول الفئات Classes :

ما هو الـ Garbage Collector ، و ما هي دلالات كلمة  new التس نستخدمها عند الاشتقاق من الكلاس الرئيسي ، ما هي الـ Static ، و ما هو الـ Constructer الدالة التي تقوم بتنفيذ أسطر برمجية عند الاستنساخ من كلاس رئيسي ؟

هذا كله سنتعرف عليه في هذا الدرس بعد الفاصل إن شاء الله .

 

السلام عليكم و رحمة الله و بركاته ، و أهلاً و سهلاً بكم في درس جديد من دروس سلسلة تعلم البرمجة للمبتدئين كلياً بواسطة السي شارب

بسم الله الرحمن الرحيم ، في الدرس الماضي تحدثنا عن مدخل إلى البرمجة كائنية التوجه OOP و التي هي اختصار لـ Object Oriented Programming ، و تعلمنا كيفية بناء Class ، و التي  أصبحنا نعلم أنه يمكن ترجمة الـ Class إلى العربية بكلمة ” الفئة ” ، و تكلمنا كيف يمكنك بناء فئات أو Classes تحوي معلومات مشتركة ، و رأينا كيف يمكننا تعريف الـ Property  و رأينا كيف يمكننا استنساخ Object من هذا الـ Class

في هذا الدرس سنتكلم إن شاء الله عن أمور و تطبيقات إضافية للـ Classes و الـ Method نفسها ، و سنتكلم عن مفهوم الـ Object نفسه ، فما هو مفهوم الـ Object عندما نقوم باشتقاقه من الـ  Class ، و كيف يتم تخزينه و استدعائه ، و ماهي حلقة الوصل بينه و بين الذاكرة ، سيتم مناقشة هذا في القسم الأول من الدرس ، و سنراجع معاً ما هو دور الـ Dot Net Runtime في عملية إدارة الذاكرة .

 

تكلمنا في البداية أن الـ Dot Net له أقسام معينة و هو مسؤول عن تحويل أمور معينة و تعرفنا على Common Language Runtime و اختصارها CLR ، حيث سنأخذ فكرةً عنها ، و كيف ستساعدنا هذه الأمور في انتاج برامج قوية قادرة على إدارة الـ Data  ، و قادرة على إدارة عمل البرنامج بشكل افضل .

و سنتكلم أيضاً عن شيء يسمّى Constructer  ؛ و هو Method خاصة يتم استدعاؤها عندما يتم استنساخ Object من الـ Class ، و سنتكلم أيضاً عن معنى كلمة Static ، و التي رافقتنا من أول درس إلى هذا الدرس .

 

كالعادة نقوم بإنشاء مشروع جديد بلغة c# من النوع Console App

في الدرس الماضي تكلمنا عن المكان المناسب لتعريف الـ Class ، حيث قلنا أنه يجب أن يكون موازياً للـ Class الرئيسي ، في المنطقة الواقعة داخل الحافظة الرئيسية namespace  ؛ و التي تحتوي على مجموعة من الكلاسات .

 

في البداية هناك قضية أودُّ التنويه لها ، و هي إمكانية كتابة Class ضمن كلاس آخر ، أو ما يعرف بالـ Nested Class ، لكننا لن نتعمق في هذا الموضوع ، و سنتعلم الـ Class بمفهومه البسيط ، و الذي يمكن استخدامه في أي مكان .

إذا لكتابة Class جديد نذهب لأي منطقة موازية لأي كلاس آخر ، و يمكن كتابة الـ Class فوق الكلاس الرئيسي أو تحته ، فلا مشكلة في هذه النقطة ، إذا سننتقل إلى السطر رقم 15 ، و أقوم بكتابة نفس الـ Class الذي تعاملنا معه في الدرس الماضي .

لاحظوا أن هذا الـ Class المسمّى Car يحتوي على 4 خصائص ، كل منها لديه نوع خاص ، فالشركة المصنعة لديها النوع string و سنة التصنيع من النوع int .

اشتقاق Object من Class معين :

و لاشتقاق Object من هذا الـ Class تعرفنا أنه يمكننا كتابة اسم الـ Class الرئيسي أولاً ، ثم نقوم بتعريف متغير جديد myCar على سبيل المثال ، ثم وضع إشارة المساواة ، ثم new ثم اسم الكلاس مرة أخرى ، مع وضع اقواس () و الفاصلة المنقوطة ، حيث قمنا هكذا بجعل هذا الـ Object مستنسخاً من الـ Class الذي اسمه Car ؛ لاحظوا في هذه الجملة قمنا بتعريف متغير نستطيع أن نقول عنه أنه Object من النوع Car ، و لاحظوا أنه عندما قمت بوضع كلمة new فهناك عمليات موجودة خلف هذه الكلمة .

 

ما معنى كلمة new ؟

عندما تقوم بعملية استنساخ أو بناء مجسم جديد ، فأنت فعلياً قمت بربط هذا المجسم و معلوماته بمكان معين في الذاكرة ، Address  معين في الـ Memory ، و هذا المكان في البداية هو مكان فارغ عندما قمنا بكتابة Car myCar ، و لكن عندما قمنا بكتابة new Car قمت بإضافة المعلومات الأساسية التي يتكون منها هذا الكائن ، فعندنا في البداية كائن قمنا بتعريفه فارغاً و لكن عندما قمنا بعملية ربطه بكلمة new قام فعلياً بعملية انشاءه و تهيئته بالشكل الذي قمنا بكتابته في الـ Class ، و سنتعرف بعد قليل على ميزة خاصة بعملية الـ new Car الموجودة هنا .

يمكن أيضا تشبيه هذا الموضوع بالبالون ، حيث نفترض بالون معين يطير في الهواء ؛ هذا البالون له خيط ، هذا الخيط هو عبارة عن الـ myCar ، و هو اسم المتغير  ، أما المعلومات الموجودة به فهي موجودة على البالون ، فالمتغير يدل على المنطقة في الذاكرة التي تحتوي المعلومات الكاملة .

 

القضية التي نودُّ شرحها هنا أنه بإمكاننا كما تعرفنا في الدرس السابق ، بإمكاننا إضافة المعلومات الموجودة بداخله ، حيث نضيف معلومات اللون و الخصائص السابقة ،

يمكننا أيضاً إضافة Object آخر من نفس النوع Car و جعله يشير إلى نفس المكان الموجود في الذاكرة ، بمعنى … سنقوم بإضافة متغير جديد باسم myOtherCar ، و لاحظوا أنني في هذه الجملة قمت بتعريف Object لكنه فارغ ، لا يشير إلى مكان في الذاكرة ، أو ليس له محتويات يشير إليها ، فإن قلت له في السطر التالي ، myOtherCar = myCar ، ففعلياً في هذا السطر جعلت الـ Object يشير إلى المكان الذي يشير إليه myCar

نعود لمفهوم البالون لتوضيح الصورة أكثر .

لدينا البالون الذي اتفقنا سابقاً أن له خيطاً و اعتبرناه myCar ، بالجملة التي كتبناها قمنا بعمل خيط آخر ، و الذي هو myOtherCar و الخيطين يشيران إلى نفس البالون ، و لاحظوا أنني لم أقم بإسناد أي قيمة للمتغير ، بل جعلته مساوياً للـ Object السابق .

بمعنى أنني إذا قمت بعمل طباعة الجملة التالية ، فعندها سيقوم بطباعة Black ، على الرغم من أنني قمت بطباعة myOtherCar  و ليس myCar ، إذا فعليا في المتغير myOtherCar قمت بالإشارة إلى نفس البالون الذي يحمله الـ myCar و لتتأكدوا أكثر أن الاثنان مرتبطان بنفس المنطقة في الذاكرة ، سأقول له
;”myOtherCar .color = “Red
أنا فعلياً هنا قمت بتغيير اللون لـ myOtherCar و ليس myCar ، و سأقوم مباشرة بطباعة myCar.color
و للتوضيح باختصار : انا قمت بتعريف متغير myCar و قمت بوضع اللون الأسود له ، ثم قمت بتعريف Object آخر من النوع Car و قمت بإسناد موقع الـ myCar إلى myOtherCar ، و قمت بتغيير myOtherCar.color ،و سأقوم بطباعة الـ myCar الأولى ، عند التشغيل سيظهر Red المعدلة و ليس Black ، لأنه كما ذكرنا أنه عبارة عن مكان موجود في الذاكرة و هناك أكثر من خيط يشير له ، فأي تعديل على أحدهما يؤثر على الآخر ، فـ myCar و myOtherCar هما عبارة عن خيوط للمكان المحجوز في الذاكرة نفسه .

 

ماذا لو أردت أن أقطع هذا الخيط ، بمعنى أريد فصل myOtherCar عن المكان الذي قمت بتعريفه في الأعلى . بمعنى أن تنفصل myOtherCar عن myCar ، فأنا أريد جعلها تشير إلى مكان آخر في الذاكرة ، فعلياً في السطر 17 أنت تعرف خيطاً فقط لا يشير إلى شيء ، و لا يوجد معلومات به ، و لا نعرف كيف سيكون و ما هي محتوياته ، لذلك يوجد جملة myOtherCar = null هذه القيمة null فعلياً فارغة ، و بذلك في السطر 20 قلت له أن يقوم بفصل myOtherCar عن أي شيء آخر ، و اجعله فارغاً لا يحوي أي شيء ، و بذلك ، و بدءاً من هذا السطر لو قمت بعملية طباعة أي معلومة من معلومات  myOtherCar فسنلاحظ أنه سيظهر مشكلة و خطأ برمجي ، و هو : myOtherCar was null  أي أنه فارغ !! و لا أعرف ما هو الـ color الذي تريده ، و لذلك لا اعرف كيفية طباعة هذه الجملة ، و بالتالي يظهر الخطأ .

إذاُ .. فعليا في السطر 20 قمت بقطع الحبل الخاص بـ myOtherCar الذي كان يربطه بالبالون ؛ و عند هذا السطر ، فقط myCar هو الذي يحتوي الوصلة للبالون .

 

إذا قمت بعد ذلك بقص الخيط الثاني  و ذلك بجعل myCar  تساوي null أيضاً ، و لاحظوا أنني هنا بعد تعريف الـ  Object و اضافته أن هناك بالون معين و يحتوي على المعلومات القيمة التي أريدها . و بعد السطرين 20 و 21 قمت بقطع الشريطين ، و طار البالون في الهواء و المعلومات فعلياً ذهبت إلى الأعلى و انفجرت !!

إذاً القضية التي أريد أن اوضحها لكم أن في هذه الخطوات هي فعلياً عملية ربط Object معين بموقع ، و عندما تقوم بفصله ، أو عندما يصل إلى نهاية الـ Block الذ تم تعريفه داخله فإنه فعلياً يصبح null  أي فارغاً بغض النظر عن السطرين 20 و 21 .

 

هنا يأتي دور Dot Net Runtime فماذا يفعل ؟؟

هناك معلومات قيمة و معلومات كثيرة ، فنحن الآن نتكلم عن كلمتين أو خمس حروف و هكذا ، و لكن ماذا عن المشاريع الكبيرة ، عندنا كم هائل من الـ  Data و هذه البيانات إذا بقيت في الذاكرة و لم يتم التحكم بها ، فسيكون هناك مشاكل كبيرة نحن بغنى عنها ، و هنا يأتي دور الـ Dot Net Runtime  و الذي قلنا سابقاً أن اختصاره هو CLR سيقوم بالتالي :

ستذهب و تبحث في جميع الأكواد التي قمنا بكتابتها في هذا البرنامج ، و ستجد أن هناك بالون فارغ لا يوجد أي وصلة له ، و تقوم بالبحث إن كان هناك خيوط مرتبطة بهذا البالون أم لا ، و فعلياً لن تجد أي وصلة له ، و تقول : ” أنت يا بالون خارج  التغطية و لا أريدك ، سأقوم بتهيئة مكانك ، قم باستخدامه لمتغير آخر استفيد منه خلال البرنامج ”

إذا هذا الموضوع الذي يقوم بحذف و إدارة الذاكرة شيء يسمى Garbage Collector ، هو شيء خاص بـ CLR ، و يقوم بالبحث عن المناطق أو الـ Object  التي تم فصل الارتباط بها ، و يقوم بتهيئتها لاستخدامها بشيء آخر ، هذا المصطلح يجب أن تكونوا على اطلاع عليه ، و نحن عندما نقول أن لغة السي شارب هي لغة managed  يعني أنه يوجد شيء وسيط بينك و بين الآلة يقوم بإدارة أمور معينة أنت في غنى عنها ، و لكن لاحظوا أننا عندما نقول عن لغة السي و السي بلس بلس هي لغة unmanaged  ، فإنك عندما تقوم بالتعامل مع هذه اللغات فأنت مضطر لمتابعة المتغيرات و الذاكرة و مواضيع أخرى ، فأنت مجبر أن تقوم يدوياً بعمل تفرغ لكل Object  قمت بالانتهاء منه ، كي لا تحدث مشاكل في الذاكرة و حجم البرامج ، و مشاكل كبيرة أنت في غنىً عنها .

لماذا اخترنا السي شارب ؟؟
لأنها لغة managed ، حيث توفر لنا إمكانيات و أدوات نحن في غنىً عن الغوص في تفاصيلها ، فنحن نريد أن نركز على فكرة التطبيق الذي نريد عمله

 

الآن في السطر رقم 13 عند تعريف Object  جديد قمت باستخدام قوسي الدالة () ، الحقيقة هنا يتم استدعاء  Method داخل الكلاس حتى و إن لم تقم بكتابتها و تعريفها ، ألا و هي دالة الـ Constructer  ، و هي دالة يتم استدعاؤها عندما تقوم بعمل initialize  للـ Object ، بمعنى أنه عندما تقوم بعمل فتح و اغلاق قوس يتم تنفيذ شيء معين ، و فعلياً هنا لأننا لم نقم بكتابة شيء ، هو قام بمناداته ، و لكنه ضمنياً فارغ .

لكي نتعامل مع هذا الموضوع و نتعرف عليه أكثر ، سنقوم الآن بالتعرف على كيفية كتابة الـ constructer  .

شكلها كالتالي :

()public Car

{
}

و اسمها طبق الأصل مع اسم الكلاس ..
هذه الأسطر من 29 إلى 32 ضمنياً موجودة ، و لكنها فارغة ، طالما قمت بكتابتها ، فالأولوية لما قمت بكتابته ، سأقوم بعمل التالي :

سأقول له عندما تقوم بعمل Object  جديد ضع الشركة مثلا Nissan  و سأقوم بالرجوع إلى الأسطر في الأسفل و اجعلها جمل ملاحظات .

أنا فعلياً قمت بتعريف الـ Object ، و لكن لم أقم بإسناد أي قيمة ، فقط قم بطباعة الـ Make  و عندما أقوم بتنفيذ التطبيق سيقوم بطباعة كلمة Nissan  ؛ من أين أتت هذه الكلمة !!!!

هذه الكلمة أتت من الـ Constructer    و هو كما قلت يتم استدعاؤه ضمنياً عندما تقوم بعملية استنساخ Object  جديد ،

هنا أيضاً مفهوم آخر ذكرناه في الMethods و سنعيده مرة أخرى  ، ألا و هو الـ Overload ، و هو إمكانية كتابة نفس الـ Method بنفس الاسم ، لكن مع اختلاف عدد الـ Parameter الموجود بداخلها ، لاحظوا أننا تكلمنا أنه داخل الـ Method بإمكانك إضافة  Parameter معينة  يتم اسنادها من خارج الدالة و يتم التعامل معها من داخل الدالة .

سنقوم بإضافة دالة جديدة و هي عبارة عن public Car و لكن سنقوم بإضافة Parameter  من خارج الدالة ، و تسمى هذه العملية Overload ، فسأقول له مثلاً string make  و string model  و int year و string color  ، و لاحظوا أن الكلمة make  تختلف تماما عن الكلمة Make لأننا تكلمنا أن لغة سي شارب هي لغة Case sensitive  فالحرف الصغير يختلف عن الكبير ، إذا في الـ overload هذه هنا سأقوم بعمل التالي ، حيث أنني في السطر رقم 13 ثمت بتعريف Object  جديد و القوسين فارغين ، فعليا قام باستدعاء الدالة التي قمنا بكتابتها ، و لكن أريد منه أن يقوم في عملية الـ Initialization أن أسند إليه قيماً و يقوم مباشرة بوضعها داخل كيان الـ Object  للتعامل معها لاحقاً .

فمثلاً سأقول له كالتالي :

الـ Make ذات الحرف الكبير اجعلها الـ make ذات الحرف الصغير ،  و التي أرسلتها من خارج الدالة

و كذلك بالنسبة للـ Model & Year & Color ، نعود للأعلى في السطر 13 ، بمجرد فتح القوس الأول يقوم بإظهار خيارات ، و بالضغط على الأسهم الظاهرة ، ستلاحظ أنه يوجد أكثر من Method يمكن استدعاؤها ، و هنا الأولى لا تحتاج أي Parameter و التي استخدمناها في السطر السابق ، و لكن هنا أريد استخدام الثانية ، حيث أريد اسناد الشركة و الموديل و السنة و اللون في نفس السطر ، فسأقول له  BMW مثلا , و كذلك الموديل و السنة و اللون ، إذا قمت بإنشاء Object جديد و قمت باستدعاء دالة البناء التي تحتوي على Parameter .

إذا عندما أقوم بعمل طباعة لنوع الشركة ، لن يقوم بإعادة اسناد Nissan بل سيقوم بطباعة BMW لأني قمت بإسنادها في بداية انشاء التطبيق  .

فهذا هو مفهوم الـ Constructer ، و هو مميز جداً   ، و استخدامه مفيد جداً في حالات كثيرة .

 

كلمة Static :

القسم الرابع من درسنا هو كلمة Static  ، لاحظوا أننا من أول تطبيق و حتى الآن ، كانت ترافقنا كلمة static الموجودة في الـ voidMain ، فقد تكلمنا عن int و string و void و تحدثنا عن الـ Class و كيف يمكننا استخدامه  و تحدثنا عن كلمةnew و تعلمنا كيف يمكن استخدامها  .

لطن ما معنى كلمة static ، و لماذا ترافقنا دائماً ، و لماذا في درس الدوال عندما قمنا بإضافة دالة ، وضعناها أيضاً من النوع Static كي نتمكن من استخدامها داخل الـ  voidMain ؟

الحقيقة أن كلمة static هي شيء يكون standard في كل الكلاس ، فكلمة Make و Model و Year و Color هي لا تتبع للكلاس ،هذه تتبع للـ Object المستنسخ من الكلاس ، فإن قمت بكتابة Car و بعدها نقطة ، فلن أجد الـ property السابقة ، لماذا ؟؟

لأن الـ Property الموجودة هنا تكون تابعة للـ Object الذي يأتي بعد عملية الاستنساخ ، فهنا عندما قمت باستنساخ Object جديد و وضعت myCar و النقطة ، حصلت على كل الـ Property الموجودة فيه ، و لدي أيضاً دوال ستكون متاحة هنا ، لماذا؟

لأنها ليست من النوع static

أما عندما أقوم بتعريف متغير جديد من النوع static ، لاحظوا أنني قمت بتعريف Property جديدة و لكنها من النوع static ، فهي تعني أن هذه الـ Property يمكن استدعاؤها من الكلاس نفسه ، بذكر اسم الكلاس قم ارفاقه مباشرة و ارفاق اسم الـ static ، إذاً عندما أكتب Car و هي اسم الكلاس بالحرف الكبير ، و اضع النقطة ، مباشرة أصبح لدي Property يمكن استخدامها على مستوى الـ Class .

 

دعونا الآن نتعامل مع الكلمة static بشكل أكبر .

لاحظوا هنا في داخل الكلاس ، وضعت أنه عند تعريف متغير جديد سيقوم بتغيير الـ Make ، مبدئياً سأقوم بعملها جملة ملاحظة ، و سأضع ، عندما يتم انشاء Object جديد ، قم بزيادة الـ Count برقم 1 ، فإذا قمت بطباعة Car.Count ، فعملية الزيادة لا تتم في الـ Constructer الذي يقوم بإعطاء parameter ، فأنا عندما قمت بإنشاء مجسم جديد ، لم أقم باستخدام هذا الـ Constructer ، بل قمت باستخدام الثاني ، و الذي يقوم بإعطاء وParameter ، ففعلياً هنا لا يوجد زيادة ، فبالتالي تظهر القيمة 0 ، لذلك سنقوم بعمل جملة الزيادة جملة ملاحظة و وضعها في الـ  Constructer الثاني ، و نجعل السيارة الثانية فارغة تستدعي الـ Constructer الأول ، و بذلك تكون السيارة الأولى و الثالثة تستدعي الـ Constructer الثاني ، أما الثالثة ، فتقوم باستدعاء الأول ، و عندها في كل Constructer يتم زيادة القيمة بواحد ، و لدي 3 سيارات ، فعندما أقوم بطباعة الـ Count يجب أن يظهر الرقم 3 .

 

موضوع الـ static  ليس حصرياً على الـ Property بل يمكن استخدامه كذلك في الـ Method .

لاحظواً أننا طول الوقت ، و من أول سطر لم نقم باستنساخ مجسم من الـ Console Class ، لم نقل له أعطني مجسم جديد و اريد استخدام هذه الدالة .

لاحظوا أن الـ Method ذات الاسم WriteLine تابعة مباشرة لاسم الكلاس ، و ليست تابعة لـ Object يتم اشتقاقه من الكلاس .

ايضاً مر معنا في درس التاريخ و الوقت أننا قمنا بالتعامل مع هذه الـ Property المسماة Now ، و هي لا تحتاج لعملي اشتقاق من الـ Data Type المسماة DateTime ، فقد حصلت عليها مباشرة من خلال النقطة ، لأن هذه الProperty عبارة عن static .

أيضاً لو لاحظتم في درس المصفوفات ، حيث تعاملنا مع دالة Reverse ، و هي ايضاً لا تحتاج لعملية اشتقاق من الكلاس Array .

إذا بالمثل سأقوم بإنشاء Method جديدة ، هذه الدالة من النوع static  أي أنها تابعة للكلاس بشكل كامل ، و سأقوم باستدعائها بالكلاس الرئيسي ، و حيث أن هذه الدالة تقوم بطباعة Count
و لو قمت بتنفيذ التطبيق سيقوم بطباعة عدد السيارات التي قمت بإنشائها من هذا الكلاس .

 

مصطلحات الدرس :

Garbage Collector :

Static :

Constructer :

Object Oriented Programming (OOP) :

Property   :

Object :

Class :

Dot Net Runtime :

Common Language Runtime (CLR) :

namespace   :

Nested Class :

null   :

managed   :

unmanaged  :

initialize   :

Initialization :

Parameter :

Reverse :

Count :

Public  :

الأسطر البرمجية التي قمنا بتنفيذها في هذا الدرس

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ObjectLifeTime
{
    class Program
    {
        static void Main(string[] args)
        {
            //Car myCar = new Car();
            Car myCar = new Car("BMW","Z",1990,"Yellow");
            Car myCar2 = new Car();
            Car myCar3 = new Car("BMW","Z",1990,"Yellow");
            
            Car.PrintCount();
            //myCar.Color = "Black";

            //Car myOtherCar;
            //myOtherCar = myCar;
            //myOtherCar.Color = "Red";
            //myOtherCar = null;
            //myCar = null;
            
            //Console.WriteLine("{0}", Car.Count);
            Console.ReadLine();
            
        }
    }
    class Car
    {
        public Car()
        {
            //Make = "Nissan";
            Count++;
        }
        public Car(string make,string model,int year,string color)
        {
            Make = make;
            Model = model;
            Year = year;
            Color = color;
            Count++;
        }

        public static void PrintCount()
        {
            Console.WriteLine("{0}", Count);
        }

        public static int Count { get; set; }
        public string Make { get; set; }
        public string Model { get; set; }
        public int Year { get; set; }
        public string Color { get; set; }
    }
}

post

البرمجة كائنية التوجه OOP – الجزء الأول

البرمجة كائنية التوجه OOP :

السلام عليكم ورحمة الله وبركاته، عندما تم تطوير البرمجة كائنية التوجه Object Oriented Programming المعروفة بالإختصار OOP أحدثت ثورة كبيرة في علم البرمجة، فلقد قامت بحل العديد من الإشكاليات والمعضلات التي كانت تؤرق المطورين أنفسهم، سنأخذكم في جولة سريعة نشرح فيها أهم المبادئ للبرمجة كائنية التوجه ومن ثم نتطرق إلى كيفية إستخدامها داخل لغة #C مباشرة، فمن أهم مبادئها :

التغليف (Encapsulation ):

وتعني ببساطة منع الوصول إلى المتغيرات الموجودة داخل الكلاس بشكلٍ مباشر، والسماح بتعديلها أو استرجاعها من خلال دوال مخصصة لذلك، وتبرز أهمية التغليف في قدرتنا على وضع قواعد معينة للتعامل مع المتغيرات، مثلا لنفرض ان هناك متغير لتخزين عمر الشخص، لو أتحنا الوصول المباشر لهذا المتغير سنفقد أي تحكم بالقيمة التي سيدخلها الشخص الذي يستخدم هذه الفئة Class (مبرمج آخر)، ولربما لن يكون لديه معرفة كافية عن طريقة عمل هذه الفئة Class فربما سيفترض أن إدخاله للعمر 0 لن يسبب اي مشاكل، لكن هذا افتراض خاطئ، ربما في أحد دوال هذه الكلاس هناك عملية قسمة لمتغير آخر على هذا العمر، و القسمة على صفر تؤدي إلى حدوث خطأ، والمشكلة أن مثل هذه الأخطاء عادةً لا تظهر مباشرة لـ مستخدم الفئة Class، إنما يظهر الخطأ فيما بعد وربما أثناء عمل البرنامج لدى المستخدم النهائي وهي ما تعرف بإسم Run-Time Error، لكن لو قمنا بالسماح باستخدام هذا المتغير من خلال دالة فنستطيع التحكم وتنبيه المطور مباشرة عند ادخاله للرقم 0 للعمر، أو تحويل الـ 0 الى 1 او غيرها .. ولأن مطور الفئة Class يعرف آلية عملها بالتفصيل فيجب أن يحمي المتغيرات الموجودة داخلها.

الوراثة (Inheritance):

الوراثة هي عملية إنشاء كلاس جديد بنائاً على كلاس سابق، أو بمعنى آخر اشتقاق، وتبرز أهمية الوراثة في تمكيننا من إعادة استخدام أكواد مكتوبة سابقاً، وتعديل بعضها أو إضافة خصائص جديدة بدل من إعادة كتابتها كل مرة، وتسمى الفئة Class التي نرث منها بالأب Parent والتي نُورِّثُ إليها بالابن Son . لنفهم أهمية الوراثة نأخذ المثال التالي، لنفرض أن هناك فئة Class تقوم باستخدامها لإظهار زر على الشاشة، وهذه الفئة كتبها مبرمج غيرك وهي تعمل بكفائة، وداخل تطبيقك تحتاج لإضافة خصائص إضافية لهذا الزر ، أو خصائص غير موجودة حالياً، لنقل مثلاً خاصية النقر المزدوج، في هذه الحالة لديك عدة خيارات قد تستطيع القيام بها:
1 – الدخول إلى تلك الكلاس والقيام بتعديله وقد تقوم بتعطيل شيء فيها دون قصد.
2 – القيام بنسخ الكود الخاص بهذه الكلاس ولصقها ثم إجراء التعديلات واستخدام هذه الكلاس الجديدة، لكن في هذه الحالة أي شيء نقوم بتغييره او تطويره، او اصلاح بعض الاخطاء على الكلاس الأصلية يجب أن نغيره على هذه ايضاً، وهذا فيه إضاعة كبيرة للوقت.
3 – الوراثة ! عمل كلاس جديدة ترث الكلاس القديمة بكامل خصائصها، ثم تقوم بإضافة الخاصية الجديدة فقط، وبهذه الطريقة نتأكد من استمرارية عمل الكلاس القديمة بلا اي مشاكل، واي تطويرات على الكلاس القديمة ستنعكس ضمنياً على هذه الكلاس.

تعدد الأشكال (Polymorphism):

ويعني أن الكائن يمكن أن يتخذ أكثر من شكل، والفكرة ببساطة أن مجموعة كائنات ترث خصائصها من أب واحد، لكن كل منهم يقوم بتعديل هذه الخصائص لـ تقوم بأمر مختلف.
ومن أهم استخداماته هو القدرة على تمرير هذه الكائنات المختلفة إلى نفس الدالة، أي لو كان لدينا الكائنات التالية: مربع، مستطيل و مثلث، ولدينا كلاس اسمه Area للتعامل مع المساحات وفيها خاصية طباعة مساحة الشكل على الشاشة، بدون مفهوم تعدد الأشكال سيكون علينا أن نقوم بعمل ثلاث دوال لطباعة مساحة كل شكل من هذه الاشكال، مثلا PrintSquareArea و PrintTriangleArea و PrintRectangleArea لكن بتطبيق مبدأ تعدد الأشكال بإمكاننا الاكتفاء بـ دالة واحدة مثلا PrintArea وتستطيع استقبال جميع الاشكال، لانهم بالنهاية مشتقين من كائن واحد، وهذا ممكن ببساطة لان جميع الكلاسات الخاصة بهذه الاشكال يجب ان ترث من كلاس أب يمتلك الخصائص التي نحتاجها وليكن اسمه Shape مثلاً ولديه دالة CalculateArea لحساب المساحة، ثم تقوم كل كلاس ترث منه بتعديل طريقة حساب المساحة بما يناسبها، لكن المهم انها تمتلك هذه الدالة ! فتستطيع دالة الطباعة استدعاء الدالة على أي شكل يمرر لها دون الاهتمام بـ نوعه، المهم أنه يرث من اب يمتلك هذه الدالة فبالتأكيد أن الكائن الابن يمتلكها ايضاً.

تطبيق البرمجة كائنية التوجه OOP بواسطة #C

هناك بعض المصطلحات المرافقة للبرمجة كائنية التوجه التي يجب عليك كمطور الإلمام بها ومعرفتها، سنقوم بالتعرف عليها وإستخدامها مباشرة بشكل أسطر برمجة بإستخدام لغة C# ، وهنا  أهمها تباعاً :

1 – الفئات والكائنات (Classes and Objects)

الفئة هي عبارة عن نموذج أو وصف للكائن (blueprint)، أما الكائن فهو عبارة عن نسخة من هذه الفئة (instance)، على سبيل المثال، لو كان لدينا فئة Student فإننا نقوم بإنشاء كائنات من هذه الفئة كما يلي:

Student std = new Student();

فهنا لدينا Student هي النموذج العام، ثم قمنا بإنشاء كائن Std وهو مستقل بذاته، أي إذا قمنا بانشاء 10 كائنات، فإن التعديل على خصائص أحدهما لا يؤثر في الآخر، لكن التعديل على الفئة نفسها ينعكس على جميع الكائنات المنشئة منها. وهنا طريقة إنشاء الفئة Class في لغة #C :

Class Student
{
}

تتكون الفئة Class من التالي :
الخصائص والمتغيرات (properties): وهي عبارة عن البيانات التي يتم تخزينها داخل الفئة Class
الدوال (methods): ويمكن ان نقول انها تمثل سلوك هذه الكلاس أو بعبارة أبسط المهام والأمور التي تقوم بها هذه الكلاس، مثلا دالة Max لإيجاد الأكبر بين رقمين.
الأحداث (events): والأحداث عبارة عن قنوات للتواصل بين الفئات والكائنات المختلفة.

2 – الخصائص والمتغيرات Properties & Variables

يمكن أن نقوم بإضافة متغيرات Variables للفئات Classes في لغة ال #C كما يلي :

Class Student
{ 
       public int age;
}

لكن كما تلاحظ فقد قمنا بانتهاك أحد مبادئ البرمجة كائنية التوجه، والتي تم شرحها في بداية المقالة، وهو التغليف Encapsulation ، لذلك يجب أن نحول متغير العمر الى شيء محمي ويبقى داخل الفئة وهو ما يعرف بالإسم private  كما يلي :

Class Student
{ 
      private int age;
}

هنا يأتي دور الخصائص Properties والتي تقوم بتعديل أو طباعة قيمة هذا المتغير وتحافظ عليه من أي تعديل خارجي، حيث يمكننا تعريفها داخل لغة #C كالتالي :

Class Student
{
	private int _age;
	public int Age
	{
		get {return _age;}
		set 
		{
			if(value <= 0)
				_age = 1;
			else 
				_age = value;
		}
	}
}

وكما تلاحظ هنا، فإننا نملك تحكم كامل بالقيم المدخلة أو المرتجعة من هذا المتغير، أي أننا قمنا بتغليفه، وفي حال أننا رغبنا بتمكين لغة السي شارب من العمليات الداخلية لهذا المتغير يمكن تعريفها بصيغة مختصرة جداً كالتالي :

Class Student
{
	Public int Age { get; set; };
}

3 – الدوال Methods

الدالة عبارة عن حدث أو مهمة تقوم بإجراءات وظيفية داخل الفئة وغالباً تتعامل مع المتغيرات والخصائص الداخلية، فمثلاً تأخذ العمر وبناءاً عليه تحدد شيء معين، وتكتب بهذا الشكل

public int Method(string param)
{
// code
}

ويمكن للفئة Class امتلاك أكثر من دالة تحمل نفس الاسم، لكن بشرط اختلاف عدد المتغيرات الممررة لها Parameters او اختلاف نوعها، وهو ما يعرف ب overloading ، كالتالي :

public int Method(string param) {};
public int Method(int param) {};

4 – دوال البناء Constructors

دالة البناء هي دالة يتم استدعائها بشكل تلقائي عند إنشاء الكائن باستخدام new ويجب ألا تقوم بإرجاع أي قيمة، وان يكون اسمها نفس اسم الفئة Class، كما يمكنك انشاء اكثر من دالة بناء من خلال ال overloading وعادة تستخدم دالة البناء لتهيئة الكلاس ووضع قيم أولية لـ متغيراتها قبل البدء باستخدامه.وهذا مثال عليها

public class SampleClass 
{
	public SampleClass()
	{
	}
	public SampleClass(int age)
	{
	}
}

كما تلاحظ، قمنا بإنشاء دالتي بناء، الاولى سيتم استدعائها عندما ننشئ كائن بهذا الشكل

SampleClass sc1 = new SampleClass();

والثانية عند تمرير قيمة مثل

SampleClass sc1 = new SampleClass(22);

5 – الكلاسات المتداخلة Nested Class

بإمكاننا تعريف فئة Class داخل فئة أخرى، وتسمى nested class اي فئة داخلية أو متداخلة

class Main
{
	Class Nested
	{
	}
}

كما نلاحظ هنا الكلاس Nested موجودة داخل الكلاس Main ونستطيع استخدامها بهذا الشكل

Main.Nested nested = new Main.Nested();

6 – سماحية الوصول (Access Modifiers)

نستطيع التحكم بإمكانية الوصول إلى المتغيرات والدوال داخل الكلاس عن طريق ال Access Modifiers ، وهناك خمس أنواع :
عام (public): نستطيع الوصول إلى هذا المتغير أو الدالة من اي مكان في المشروع، او حتى من خلال مشروع آخر يعتمد على هذا المشروع.
خاص (private): نستطيع الوصول إلى هذا المتغير أو الدالة من خلال نفس الكلاس فقط، وليس من أي مكان آخر.
محمي (protected): نستطيع الوصول إلى هذا المتغير أو الدالة من نفس الكلاس او من كلاس أخرى مشتقة منها (أي ترث منها كما شرحنا سابقاً).
داخلي (internal): نستطيع الوصول إلى المتغير أو الدالة من نفس المشروع فقط، أي أن المشاريع الأخرى التي تعتمد على هذا المشروع لا تستطيع الوصول اليه.
داخلي محمي (protected internal): نستطيع الوصول إلى هذا المتغير أو الدالة من نفس المشروع أو من كلاس موجودة في مشروع آخر تشتق (ترث) من هذه الكلاس.

تم كتابة الجزء الاول من المقالة بواسطة Ward Mahmoud وترجمتها إستناداً إلى مقالة أصلية هنا، نلقاكم في الجزء الثاني قريباً إن شاء الله.

post

بولي Poly مقصدك للمجسمات الخاصة بالواقع الإفتراضي

السلام عليك ورحمة الله وبركاته، أطلقت شركة Google موقع متخصص بتحميل المجسمات القليلة التفاصيل والتي قامت بتسميته Poly ، حيث أنها أعطت الفرصة لمن يقومون بتطوير تطبيقات الواقع الإفتراضي Virtual Reality المعروف بالإختصار VR والواقع المعزز Augmented Reality المعروف بالإختصار AR ،بإستخدام ألاف النماذج 3D Models القابلة للتحميل المباشر والإستخدام في تطوير التطبيقات السابقة.

استخدم Poly في كل مكان:

من الجدير بالذكر أن معظم التصاميم الموجودة هي من خلال تطبيقي  Tilt Brush  و Blocks  التي تمكنك من تصميم النموذج داخل الواقع الإفتراضي، بالتالي يمكنك تصديره ليراه الجميع، حيث قامت شركة Google  بإيجاد خدمة Poly خصيصاً لرفع تصاميمك من التطبيقين السابقين، لكن هناك إمكانية لرفع النماذج التي قمت بصنعها خارج هذين التطبيقات بواسطة الإمتداد OBJ وملف الخامة الخاصة به MTL . أيضاً يمكنك إستدعاء أي نموذج للتعديل عليه أو إستخدامه في التطبيقين السابقين أو حتى في تطوير لعبتك على محرك الألعاب Unity.

ألاف النماذج تنتظرك:

يمكنك زيارة الموقع poly.google.com لتجد العديد من النماذج، فإن قمت بالبحث عن طائرة مثلاً ووضعت Plane ستجد عشرات النماذج، قم بإختيار أي واحدة منها وقم بتصديرها لتستخدمها في مشاريعك، لكن إنتبه أن هناك بعض النماذج يشترط عليك أن تقوم بذكر إسم صاحبه في حال إستخدمته في مشروعك. ليس هذا فحسب، بل يمكنك تحويل أي مجسم أعجبك إلى صورة متحرك Gif لتستطيع نقلها لأي مكان آخر بعد ذلك، كما في الصورة التالية:

 

 

post

#16 التعامل مع النصوص Strings – البرمجة بواسطة #C

رمز فتح مرحلة هذا الدرس في تطبيق طورني : KUT

تَعلُمُ البرمجةِ للمبتدئينَ كلياً بواسطةِ #C –  التعامل مع النصوص Strings

كيفَ يُمْكِنُنا التَّعامُلُ مَع النُّصوصِ المُخْتَلِفة ، و كَيْفَ يُمْكِنُنا اقْتِباسُ جُزْءٍ مُعَيَّنٍ مِنْ نَصٍّ كامِلٍ ، و كيف يمكننا استبدال أحرف معينة في نص كامل ، و كيف يمكننا أيضاً معرفة عدد خانات الحروف في نص ما ؛ هذا ما سوف نعرفه في هذا الدرس بعد الفاصل إن شاء الله .

 

السلام عليكم و رحمة الله و بركاته ، و أهلاً بكم في درس جديد من دروس سلسلة تعلم البرمجة للمبتدئين كلياً بواسطة السي شارب .

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

التعامل مع النصوص هو أمر أساسي في التطبيقات المستخدمة ، ففي كل مشروع يجب أن يكون هناك نصوص متداولة

و من خلالها يتم استخدامها في أمور معينة ، و عمل تعديلات عليها ، لذلك يجب أن يكون عندك معرفة بالأدوات و الـ Methods التي بإمكانك استخدامها للحصول على نص أو جزء من نص  ، و تعديل نص معين يمكنك استخدامه في البرنامد الخاص بك

 

نبدأ بإنشاء مشروع جديد بلغة #C من النوع Console App

في البداية سأكتب الأسطر التالية لأننا سنستخدمها بشكل أساسي

نلاحظ الآن أننا إذا قمنا بتشغيل البرنامج فلن يظهر شيء

حسناً ، إذا توجب علينا في حالة ما استخدام علامتي التنصيص في نص معين ، فإذا حاولت إضافة علامتي تنصيص فسيحدث مشكلة ، لماذا ؟

لأن الـ Compiler أخذ الجزء الأول و اعتبر العلامة الثانية في المنتصف هي نهاية النص الأول .

لذلك إذا أردت استخدامها فبإمكانك وضع Back Slash قبلها لكي تخبر الـ Compiler  أن هذه العلامة هي فعلاً رمز  سيستخدم داخل النص

نوضح الفرق بين الـ Slash و الـ Back Slash حتى لا يحصل التباس ، فالـ Slash  هي التي تكتب بالشكل (  /  )

أما الـ Back Slash فتكتب (  \  )

و نلاحظ أن الـ Slash /    لا تعمل عمل الـ Back Slash

الآن بعد إضافة الـ Back Slash و تشغيل التطبيق سنلاحظ أن البرنامج قام بطباعة علامتي التنصيص بشكل صحيح

و هذا هو أول استخدام للـ Back Slash

نقوم بتحويل الجملة السابقة إلى جملة ملاحظة .

 

الآن في هذه الجملة الجديدة أحتاج إلى النزول إلى سطر جديد … فإنني إن قمت بطباعتها فستظهر ف نفس السطر

لذلك إن أردنا النزول لسطر جديد فسنكتب   (Back Slash + n)      ، و عندها سيفهم الـ Compiler أنه عند هذه النقطة قم بالنزول إلى سطر جديد . و بتنفيذ البرنامج نرى أن المطلوب قد حدث فعلاً

 

نقوم بتحويل الجملة السابقة أيضاً إلى جملة ملاحظة .

 

الآن ماذا لو أردنا طباعة الـ Back Slash  في النص المراد طباعته ، فبوضعها مباشرة ضمن التطبيق ستظهر مشكلة في تطبيقنا ، و السبب أن الـ Compiler افترض أن هذا الـ Back Slash سيأتي بعده Character  معين لكي يقوم بعملية معينة ، لكن هنا في مثالنا الـCharacter التالي للـ Back Slash  هو مسافة فارغة

لذلك إن أردت استخدام الـ Back Slash قم بوضع Back Slash قبلها مباشرةً ، بالتالي فإن الـ Back Slash  الذي سيأتي ثانياً هو الذي سيتم طباعته ، أما المكتوب قبله مباشرة سيخبر الـ Compiler أن التالي هو عبارة عن نص وليس Back Slash escape Character

نلاحظ أننا إذا قمنا بتشغيل التطبيق سيقوم بطباعة المطلوب بشكل صحيح و دون مشاكل أو أخطاء

حسناً .. ماذا لو كان لدينا أكثر من Back Slash  في ذات النص ، فهل سأذهب إلى كل واحد منها و أضع قبله Back Slash إضافي ؟؟

بالطبع لا ، فبإمكانك الذهاب إلى ما قبل علامة التنصيص التي في بداية النص و إضافة الرمز @ ، و التي بدورها ستخبر الـ Compiler أن يعتبر كل رموز Back Slash الموجودة ضمن النص عبارة عن Character  عادي و ليس Back Slash Escape Character، و بالتالي تخبره أن يقوم بطباعة هذا الرمز

 

تكلمنا سابقاً عن :

;string myString = string.Format(“{0} = {1}” ,”First” , “Second” )

و كما تحدثنا ، إن أردت وضع قيمة معينة داخل نص فلا داعي لكتابة الجملة ثم أقوم بإنهائها ثم أضع القيمة ثم أعود لمتابعة الجملة ، بدلاً من ذلك سأقوم بوضع index  ، بحيث يقوم الصفر بأخذ أول خانة مباشرةً بعد الـ string

و الرقم 1 يقوم بأخذ الخانة رقم 2 ، و يتم فصل الخانات بفاصلة

بتشغيل التطبيق نلاحظ أنه أخذ أول قيمة بعد الـ string عند الرقم 0 ، ثم قام بأخذ القيم الثانية عند الرقم 1

و ليس من الضروري أن نقوم باستخدام 0 ثم 1 ثم 2 …. ، فبإمكاننا أخذ القيمة الأولى مرتين ، أو نقوم بطباعة القيمة الثانية ثم القيمة الأولى .

 

حسناً.. هذا المكان الموحود في الكود السابق {…}  له Format خاصة به ، من الممكن أن نقوم باستخدامها للتأثير على القيمة الموجودة هنا بطريقة معينة

نقوم بطباعة جملة جديدة و وضعنا بعد الرقم الحرف C فسيقوم بتحويل القيمة إلى الموجودة إلى قيمة عملة ، حيث سيضع قبلها علامة العملة الخاصة ببلد معين ، فإن قمت تستخدم الدولار فسيقوم بوضع العلامة $ ، و تتغير بحسب العملة المتبعة في بلدك ، لكن في جهازي أنا استخدم الليرة التركية ، فسيظهر علامة استفهام لأن رمز الليرة التركية غير معرف

 

الآن إذا كان لدينا رقم طويل بحيث يكون صعب القراءة ، كما تعلمنا في دراستنا فإن الرقم عادة يقسم بحيث يوجد فاصلة بين كل 3 خانات ، فإذا أردت أن يكون الرقم مفصولاً كذلك فيمكن أن نستخدم الحرف N ، عندها سيقوم بوضع الفواصل و النقط و عند التنفيذ نلاحظ أنه أضاف النقط بحيث يقسم كل 3 منازل ، و يضيف الفاصلة العشرية حتى لو لم تكن موجودة ، و يضيف الصفر إلى يمينها

 

ماذا لو أردنا استخدام النسبة المئوية percentage ، مثلا 20% , 30%

فيمكنك استخراجها باستخدام الحرف P و سنكتب في البداية كلمة percentage أو أي نص آخر

عندها سيقوم بتحويل الرقم  251. إلى 25.10%

 

ماذا لو أردت استخدام Format خاص بي

حيث سأقوم بإضافة الفواصل و النقاط و الشرطات بحسب رغبتي ، فيمكن عمل ذلك كما يلي،

ليكن لدي الرقم 1234567890 و اريد أن أحوله إلى رقم هاتف

لاحظو بعد النقطتين يمكننا طباعة الرقم كما نريد

فنضيف (###) ###-####)

كل إشارة من الإشارات السابقة هي عبارة عن خانة ، و بذلك قمنا بتنسيق الرقم كما أردنا ، و بتطبيق البرنامج سيطبع الرقم (123) 456-7890

و هذا يعد Format خاص

 

ماذا لو أردت التعامل مع نص حقيقي

لدي جملة و أريد أن آخذ أجزاء منها أو أقوم بعمليات عليها فماذا أفعل

سنعرف المتغير myString من النوع string  ثم أقول له

myString القديم سيصبح muString نفسه و اضع نقطة ، و بمجرد وضع النقطة ، و لأنه متغير نصي سيظهر لديك جميع الـ Methods الخاصة بـ string ، و بالطبع لكل نوع من أنواع البيانات Methods  خاصة به

يمكنني هنا أن أقوم بعملية قص عن طريق اختيار الدالة Substring التي اخترناها بعد النقطة

نفتح قوسي الدالة و نكتب 5 على سبيل المثال ، عندها سيقوم بقص أول 5 خانات و يطبع الباقي

يمكننا عن طريق إضافة فاصلة و رقم آخر إلى المثال السابق ، و عندها سيقوم بطباعة ما بين الخانة 5 و 11 ، و يقوم بحذف الباقي

 

ماذا لو أردت أن تحول كل أحرف الـ string إلى حروف كبيرة

عندها سنستخدم الدالة ToUpper بدلاً عن الدالة Substring ، و بعندها سيقوم بطباعة الخانات كلها مع تغيير حالة الحروف إلى حروف كبيرة

 

ماذا لو أردت استبدال خانة أو حرف بخانة أخرى ،

مثلا في النص السابق أريد استبدال خانة المسافة بخانة أخرى ، فعندها سنستخدم الدالة Replace ،

و هذه الدالة تحتاج إلى قيمتين ، فالأولى هي Old Character  و الثانية هي New Character

نكتب كل قيمة بين علامتي تنصيص ، و يفصل بين القيمتين بفاصلة

ندخل القيمة الأولى هي المسافة ، أما الثانية نجعلها الرمز –   ، عندها سنرى أن التطبيق استبدال المسافة بالرمز –

 

ماذا لو اردنا حذف جزء من الكلمة الموجودة ، فيمكن استخدام الدالة Remove  ، و لهذه الدالة أكثر من استخدام

فلو أدخلنا رقم واحد فقط ،  و ليكن الرقم 5 ، فسنلاحظ أنه أخذ أول 5 خانات و حذف الباقي

و لو قمنا بوضع قيمتين فسيقوم بحذف ما بين الخانة 5 و 11 و يطبع كل ما تبقى

 

استخدام الـ StringBuilder :

هناك قضية يجب أن ننوه لها ، فاستخدامك للـ string مكلف فعليا ، و نعني بذلك ، حاول قدر الإمكان التقليل من استخدامك للـ string

فاستخدامك له و تخزين Data  كبيرة داخله يحجز مساحات كبيرة في الذاكرة ، و هناك فرق شاسع بي تخزينك للـ integer  و تخزينك للـ string

لذلك حاول أن تكون حذراً و دقيقاً في استخدامه

 

لاحظ الآن سأقوم بمحاولة طباعة لـ string ضخم جداً ، و أقوم باستخدامه بطريقة غير مجدية

لاحظو هذه الطريقة في كتابة الحلقة for  ،

نكتب كلمة for و لا نكتب مسافة بعدها ، ثم نضغط Double Tab فسيقوم بوضع الهيكل الخاص بحلقة for

و هذه الميزة غير موجودة في كافة المحررات

بعد وضعه للهيكل الخاص يمكن التعديل عليه

 

سنشرح قضية هنا مهمة

لاحظو هنا القيم الموجودة قيمة integer  و في بعض الأحيان لا يقبل وضع قيمة int في متغير string

فمن الممكن تحويل أي متغير يمكن تحويله مهما كان نوعه  إلى string عن طريق الدالة ToString ،

الآن سيقوم البرنامج بعملية يأخذ القيمة الجديدة و وضعها في مكان معين ثم أخذ هذا المتغير مرة أخرى ،

و هذه العملية غير صحيحة كما تعلمنا ، فهي تقوم بعملية إضاعة

نحن هنانقوم بعملية 100 حلقة ، لكن تخيل لو كان لدينا 1000 حلقة أو مليون حلقة ، فسيكون مكلفاً جداً و سيقوم التطبيق باستهلاك مساحات كبيرة

لذلك لو كان لدينا string  كبير و يحتوي على أمور تجعلك بحاجة إلى القيام بعملية إضافة قيم له

فيفضل استخدام نوع جديد اسمه StringBuilder ، هذا النوع جداً مميز لاستخدام النصوص الكبيرة و عملية إضافة القيم إلى المتغير

لاحظو في المثال السابق كان يقوم بالإضافة بأسلوب غير مجدِ ، لذلك سنقوم بتحويل السابق إلى جمل ملاحظة

و مثلا هنا سنقوم بتعريف متغير من النوع StringBuilder باسم myString

 

لو قمنا بتطبيق البرنامج سيقوم تماما بعمل البرنامج السابق ، لكن قام بتقليل المساحة المستخدمة و لم يقم بوضعها في مكان و نقلها إلى مكان آخر ، بل قام بعمليات خاصة و مميزة للتقليل من حجم الذاكرة ،

 

إذا يفضل استخدام الـ StringBuilder إذا كان لدينا نص كبير يتم قراءته ، كملف تقوم بتخزين نصوص عليه ، و تحتاج لقراءته مرة أخرى ، يفضل وضعه بـ StringBuilder لأنه مخصص للنصوص الكبيرة

 

و إلى هنا نصل إلى نهاية درسنا :

تعلمنا طريقة استخدام الـ Back Slash Escabe Character

يمكنكم الاطلاع على  Standard Numeric Format String من شركة Microsoft

ستجدون بها جميع الخانات التي يمكن استخدامها

كان هذا درساً سريعة عن الـ string لتحصل على النتائج المطلوبة ، فقد استخدمنا الكثير من الـ Methods لنصل إلى النتيجة المطلوبة و لو حاولنا الوصول إلى النتيجة بدون هذه الدوال سيكون صعباً بل مستحيلاً

ملخص الدرس

مقدمة:

السلامُ عليكم ورحمةُ اللهِ وبركاته، وأهلاً بكمْ في الدرسِ السادس عشر من دروسِ سلسلةِ، تَعلُمِ البرمجةِ للمبتدئينَ كلياً بواسطةِ السي شارب، في هذا الدرس سنتعرف على كيفية التعامل بشكل أكبر مع النصوص، كونها شيء أساسي في كل المشاريع، سنتعلم كيف نقوم بقص جزء معين من جملة، وكيف نقوم بطباعة أرقام بهئية خاصة نقوم بتعريفها.

التعامل مع النصوص Strings :

لا يخلو تطبيق صغير أو كبير من إستخدام النصوص والتعامل معها، لذلك هناك عدد كبير من الدوال للنوع النصي String يمكنك معرفة المزيد عن الدوال التي تقوم بوظائف معينة، هنا شرح لبعضها :

رموز خاصة Escape Character : ويتم بإضافة \ وبعدها خانة مثل : n لسطر جديد ، ” لطباعة التنصيص داخل نص، \ لطباعته داخل نص، القائمة الكاملة للحروف هنا.
تهيئة النص string.Format : وذلك بإستخدام أرقام Index ويمكن إضافة تخصيص لها مثل : N لطباعة الأرقام بالفواصل ، P لطباعة قيمة مئوية، القائمة الكاملة هنا.
Substring : تقوم بعمل قص للنص.
ToUpper : تقوم بتحويل جميع الأحرف إلى أحرف كبيرة Capital letter .
Replace : إستبدال نص بنص آخر.

 

مصطلحات الدرس :

Compiler :

Back Slash :

Character :

Back Slash Escape Character :

index :

Format :

Percentage :

Substring :

ToUpper :

Replace :

StringBuilder :

Double Tab :

Standard Escape Format String :

 

تجد في الأسفل الأسطر البرمجية التي قمنا بكتابتها خلال شرح الدرس.

post

النسخة 2017.2 من محرك Unity متاحة الآن!

السلام عليكم ورحمة الله وبركاته

عن النسخة :

النسخة التي وُعدنا بها من شركة Unity لمحركها الشهير Unity Engine أصبحت متاحة الآن! نعم النسخة 2017.2 أصبحت قابلة للتحميل، وبإمكانك الحصول عليها من هنا. التي تحتوي على العديد من الميزات الجديدة والتحديثات وحلول لمشاكل كانت تؤرق المطورين.

العناوين الرئيسية :

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

  • محرر المراحل Tilemap : 

  • أو يمكن أن نطلق عليه باني الخرائط، فهي أداة مميزة تعطيك تحكم كامل لبناء خرائط لعبتك ثنائية البعد، فسابقاً كان العمل أصعب من حيث أنك مضطر لوضع المربع الواحد Sprite واحداً تلو الأخر بطريقة يدوية، على الرغم من وجود أدوات مساعدة مثل ال Snap وغيرها، إلا أن هذه الميزة ستوفر الكثير من الوقت على المطورين.

مدير الإنتاج cinemachine الثنائي الأبعاد:

شهدنا في الإصدارات السابقة تواجد مدير الإنتاح الغني عن التعريف cinemachine للألعاب ثلاثية البعد 3D والتي بإمكانك التحكم في الكاميرات الموجودة في لعبتك وعمل الكثير من الميزات الحصرية التي تختصر عليه المئات من الساعات لعملها بمفردك، في هذه النسخة أصبحت الميزة متاحة لألعاب البعد الثاني 2D أيضاً، كما هو موضح في الفيديو السابق.

الدروس التفاعلية Interactive Tutorials :

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

ميزة إستيرا المجسمات Asset Management :

أو ما يعرف بالـ DCC المختصر من Digital Content Creation ، فالآن أصبح من السهل التعامل مع التطبيقات المختلفة مثل Autodesk وغيرها، ليس فقط إضافة ميزات لما تحويه هذه الملفات مثل الملف الشهير FBX الذي يحوي المجسمات والصور والحركة فحسب، بل إمتد الموضوع لإضافة مجسم جديد يمكنك إنشاءه وربطه لاحقاً بملف من تلك البرامج مما يتيح لك التعديل الآني ومن غير معاناة من إنتظار الوقت الكثير لإنعكاس التعديلات بين البرامج، فلقد تم إضافة Linked Prefabs  إلى قائمة الإنشاء كما هو موضح في هذا الفيديو :

إضافات للواقع الإفتراضي/المعزز XR :

يتضح جلياً تركيز المحرك على إعطاء القدرة القصوى لمطوريه للتماشي مع أكثر التطبيقات طلباً في الوقت الحالي، فقد إعتبرت كبرى الشركات مثل Microsoft و Sony و Google سنة 2016 على أنها سنة الواقع الإفتراضي VR المختصر من Virtual Reality والواقع المعزز AR المختصر من Argumented Reality بجدارة، أو ما يعرف كليهما بالإختصار XR ، فهناك العديد من الميزات التي تم إضافتها لتسهل العمل مع هذه التطبيقات، فها هي تضيف Vuforia  إلى محركها ضمنياً، وتدعم OpenVR و Google ARCore كما في الفيديو التالي :

ليس هذا فحسب، فهناك بعض الإضافات والتحسينات كالتالي :

+ ميزة Timeline للأصوات : بإمكانك الآن التعامل مع الأصوات أيضاً
+ تحديثات بالـ Profiler لتحليل اللعبة بشكل أكثر تفصيلاً
+ ميزة Lightmap background لإضافة لايت ماب للأماكن الفارغ سابقاً
+ أصبحت الأشجار يتم حساب ال Lightmap الخاص بها أيضاً
+ تحسينات على نظام ال Particle System

 

الخلاصة

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

post

محاكاة حركة أمواج البحار في محرك Unity

 

مقدمة :

السلام عليكم ورحمة الله وبركاته، في هذه المقالة سأتحدث عن أنه أحياناً يكون حل مشكلتك أبسط مما تتخيل، فلا يحتاج الموضوع إلى البحث الكثير والتعقيد الذي أنت في غنى عنه بما لا يتناسب مع طبيعة مشروعك أو وقتك الذي يصبح أضيق كلما وصلت إلى موعد التسليم، فموضوع هذه المقالة عن كيفية عمل محاكاة لأمواج البحار وتأثيرها على الأجسام التي تطفو مثل السفن وغيرها.

إعرف ميزانيتك قبل البدء :

عندما أتكلم هنا عن الميزانية، لا أقصد إطلاقًا النقود، وإن كانت جزء من الميزانية إلا أنها ليست كل شيء، فعندما تريد إنجاز أي شيء ( نتكلم هنا عن مجال الألعاب )، تحتاج إلى معرفة تفاصيل معينة مثل، كم من الوقت تجتاجه لإنجاز هذا الأمر، أيضاً هل يتوافق مع متطلبات مشرعك، فمثلاً يمكننا الإستعانة بمحاكاة متوفرة على المتجر ومناسبة، إلا أنها تفتقر للعمل بشكل سلس على متصفح الويب مثلاً, بمعنى آخر أنك لن تستطيع الإستفادة من تلك المحاكاة إن كان مشروعك على متصفح الويب، لذلك لا تضع الوقت بالحصول عليها وتجربتها إن كانت لا تتناسب مع منصتك أصلاً!
مسك، المشروع الحالي الذي أعمل عليه وأديره، تطلب مني محاكاة لبحر يحيط جزيرة، ليس هذا فحسب، بل تطلب أيضاً محاكاة حركة السفن التي يحملها هذا البحر، فللوهلة الأولى قمت إختصاراً للوقت بالذهاب إلى متجر Asset Store للبحث عن شيء يتناسب مع ما أريد، ووجدت العديد منها هذه الأداة :

للوهلة الأولى بدى لي أن هذا ما أريده،  لكن بعد البحث والقراءة عن هذه الأداة وجدت أنها لا تتناسب مع ميزانيتي ( الوقت + المنصة ) فمشروعي سيصدر على منصة Web GL وهذا ال Shader لا يدعها بشكل كلي، فضاع جزء من وقتي بلا فائدة!

الحل أبسط مما تتخيل أحياناً :

بحثت كثيراً عن Shaders تتناسب وما أريد، لكني لم أجد شيء مناسب، ثم خطر ببالي أن أقوم بعمل خدعة ستوفر علي الوقت الكثير وتعطي كفاءة أعلى بكثير كونها تعتمد على حسابات أقل، فما لبثت أن شرعت في تنفيذها كالتالي:

  • – قمت بوضع وجه Quad واحد وقمت بجعله بحجم كبير لكي يبدوا وكأنه البحر، أي قمت بجعل الـ Scale له 2000 كل كل محور.
  • – ثم قمت بوضع صورة لموج قابلة للتكرار Seamless .
  • – ثم قمت بكتابة أسطر برمجية تقوم بعمل تحريك لإكساء المجسم Texture Scrolling ، كما في الصورة التالية :

عند هذه النقطة، حصلت على البحر كما في الصورة التالية :

لكن هذا وحده لم يكفي بالغرض، فضفاف الجزيرة وإمتداد الرمل يجب أن يبدوا واضحاً لإعطاء مصداقية بتدرج العمق، وكان الحل بتحويل Shader المادة التي أستخدمها من Standard إلى Particle –> Multiply كما في الصورة التالية :

عند هذه النقطة، إنتهيت من البحر نفسه، لكن بقي المشكلة هي حركة الأجسام التي تطفو عليه، فالبحر هنا عبارة عن وجه واحد فقط Quad وليس فيه أي حساب للتضاريس Deformation لكي يتأثر بها مجسم السفينة!

حركة السفينة :

بعد دراسة حركة السفينة إتضح لي أنه لا داعي لإشغال موارد الجهاز في حساب شيء قد يبدوا ثانوياً وليس أساسياً، فلجأت إلى محاكاة حركة السفينة عن طريق الأسطر البرمجية كالتالي :

بهذه الطريقة حصلت على المطلوب تماماً، وكنت راضياً جداً عن النتيجة!

الخلاصة المستفادة :

دراسة بسيطة وتحليل لعدد الخيارات المتاحة لديك ومقارنته بالميزانية التي تملك ( وقت ، جهد ، تكلفة مادية ، مناسب للمشروع ) قد يساعدك على إيجاد أكثر الطرق مناسبة لما أنت عليه، فالموضوع قد يكون أبسط بكثير من الحسابات والتعقيدات التي تضع نفسك فيها أحياناً.

 

أسامة ديب
مطور ألعاب

 

 

post

#14 الدوال Methods – البرمجة بواسطة #C

رمز فتح مرحلة هذا الدرس في تطبيق طورني : OXW

تَعلُمُ البرمجةِ للمبتدئينَ كلياً بواسطةِ #C –  الدوال Methods

 

السلام عليكم و رحمة الله و بركاته ، و أهلا بكم في درس جديد من دروس سلسلة تعلم البرمجة لمبتدئين كلياً بواسطة السي شارب

درس اليوم ” الدوال الـ Method “

و هي من أساسيات البرمجة و هي التي أعطت للمطورين إمكانية أن يقوم بتنفيذ مشروعه دون أن يقوم بتكرار الأسطر البرمجية أكثر من مرة

سابقاً لم يكن هناك دوال و كان المطور مجبراً على كتابة أسطر برمجية متتالية ، فتجد أن البرنامج عبارة عن 1000 سطر على سبيل المثال ، كلها متتالية حيث ينفذ السطر الأول ثم الثاني فالثالث و هكذا ….. مما كان يجعل الأمر صعباً

و خصوصاً في حال وجود أي خطأ في البرنامج فيجب أن يقوم بتتبع للبرنامج ليصل إلى مكان الخطأ

 

كما تعلمنا في كل الدروس السابقة نقوم بإنشاء مشروع جديد و نختار Visual C# ثم Console Application و سنكتب اسم البرنامج هذه المرة ” Methods ”
و تكلمنا أنه يجب أن نقوم بالبدء بالكتابة بين قوسي الدالة void Main

لكن في هذا الدرس سنتعرف إلى طريقة جديدة و مفهوم جديد يمكننا بواسطته إنشاء دوال .

و الدالة يمكن شرحها بأنها قطعة برمجية  Block of Code تبدأ بقوس و تنتهي بقوس آخر ، و تحمل اسم , حيث يتم استدعاء هذا الاسم لتقوم بالعمل الخاص بها .

لاحظو الدالة الرئيسية void Main و هي الدالة التي يبدأ بها الـبرنامج

سنقوم الآن بكتابة دالة رئيسية و سنقوم بشرحها و شرح التركيبة الخاصة بها

هذه الدالة يمكن استخدامها و استدعاؤها في الدوال الأخرى كالتالي :

أخذ اسم الدالة (PrintMessage) ثم فتح القوس الخاص بها و اغلاقه و كتابة الفاصلة المنقوطة .

و لا ننسى أن نقوم بكتابة الدالة ReadLine

عند تشغيل التطبيق سيقوم بطباعة Hello World !

الفكرة من الدوال أنه يمكنك إضافة العديد من الأسطر البرمجية في وِحدة خاصة بها ، بحيث في حال الحاجة إلى تكرار الأسطر ، فيمكنك استدعاؤها عن طريق اسمها دون الحاجة لكتابة كافة الأسطر .

شرح الدالة

في البداية يجب أن تقوم بكتابة الدالة خارج الـ void Main  لأنه لا يمكن كتابة دالة داخل دالة

لذلك إذا أردت كتابة دالة فيجب كتابتها خارج الدوال الأخرى

الترتيب غير مهم هنا و هذا يعني أنه بإمكانك كتابتها قبل أو بعد الـ void Main

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

 

فوائد الدوال :

(1) : استدعاء أسطر برمجية يتم كتابتها أكثر من مرة ، بحيث تقوم بكتابتها مرة واحدة داخل الدالة ثم تقوم باستدعاء الدالة في كل مرة تحتاج إلها .

(2) : عدم تكرار الأسطر البرمجية نفسها

(3) : تقوم بتنظيم المشروع

(4) : في حال حصول أي مشكلة يمكن تعديلها بشكل بسيط في مكان واحد دون تتبع التطبيق بشكل كامل

 

هذه القضايا سنتكلم عنها في الدروس القادمة و سنتحدث الآن عن الدالة void

 

 

الـ void هي نوع من أنواع البيانات أو أنواع الـ Data مثل integer  و  string

لكنها لا تعود بقيمة و سنتعرف عليها بعد قليل

يمكننا نقل السطر ;()Console.ReadLine إلى الدالة التي قمنا بإنشائها

 

هذا التطبيق يعد بسيطاً ، لذلك سنأخذ برنامجاً قمت بكتابته سابقاً ، و هو يحتوي على تكرار للاسطر البرمجية و سنقوم بإضافة الدوال  لتحسينه و ترتيبه بشكل أفضل

 

هذا البرنامج يسأل المستخدم عن اسمه و اسم عائلته ، ثم يسأل عن المدينة التي ولد فيها ، ثم يقوم بإظهار رسالة تحتوي على العناصر السابقة بشكل معكوس كما تعلمنا في الدرس السابق ، و ذلك عن طريق الدالة Array.Reverse

لدينا الآن أسطر برمجية مكررة في هذا التطبيق ، حيث يقوم بطباعة جملة ثم يقوم بمطالبة المستخدم بعملية إدخال و يكرر هذا الأمر

ثم يقوم بتعريف Array من النوع char  ثم يأمر بتحويلها إلى مصفوفة ثم يقوم بعملية عكس لهذه المصفوفة

إذا لدينا ثلاث أسئلة و لكل سؤال 4 عمليات

و بالتالي لدينا تقريباً 12 سطر

و في النهاية يقوم بتعريف متغير جديد باسم result

و يقوم باستخدام الحلقة foreach ليقوم بأخذ هذه الأحرف و يجمعها ليعطي هذه النتيجة

نلاحظ عند تشغيل التطبيق أنه أخذ كلمة كلمة و لم يعكس الجملة كاملة ، حيث قمت بإدخال Osama  ثم  Deep ثم amman

فأخذ الاسم الأول و قام بعكسه ، ثم أضاف مسافة قبل الاسم الثاني ثم تابع أخذ الاسم الثاني و المدينة ،

عندها قام بإعطاء النتيجة كالتالي

Result : amaso peed namma

لنرى كيف نكتب دالة توفر علينا هذا الكم من الكتابة ، فبدلاً من كتابة 16 سطر سنقوم بكتابة 4 اسطر فقط و استدعاء هذه الدالة

 

الآن نقوم بتعريف دالة جديدة

ثم نكتب التالي ضم قوسي الدالة {   }

كما في المثال التالي :

 

في البداية سنقوم بالتطبيق على الـ firstName فقط ، سنستدعي الدالة ليقوم بعرض الموجود داخلها .

المتغير الأول هو السؤال و المتغير الثاني هو ناتج المدخل

الآن سيقوم بطباعة السؤال و ثم يكون بعملية عكس للأحرف المدخلة في الجواب

حيث يقوم بتحويله لمجموعة من character  و اسنادها في متغير جديد ثم يقوم بعكسها باستخدام الدالة Array.Reverse

و في النهاية سيقوم بطباعة firstNameArray

الآن لدينا الجزء المتكرر في كل المراحل السابقة و قد أصبح ضمن الدالة التي قمنا بإنشائها

الآن نقوم بعملية استدعاء للدالة التي قمنا بإنشائها

عندها سيسأل عن الاسم الأول و يطلب إدخاله ، و سيأخذ القيمة من المستخدم و يدخلها في متغير نصي  و يتابع

عند تشغيل التطبيق سيسأل عن الاسم و عند ادخال osama  يقوم بطباعة osama لكن بالشكل المعكوس … أي  amaso

 

الآن لنلاحظ أن هذه الدالة هي من النوع void و تقوم بتنفيذ الاسطر الموجودة بدون ارجاع أي قيمة أخرى

لاحظوا أنه سيكون لدينا مشكلة إذا قمنا بكتابة هذه الدالة للاسم الثاني و اسم المدينة

المشكلة هي أنه إذا قمت باستدعاء اسم الدالة فعندها سيقوم بطباعة الاسم الأول لوحده ، و نحن لا نريد هذا

نحن نريد أن يقوم بإرجاع القيمة الناتجة و استخدامها لاحقا

 

فقد تكلمنا أن الـ void لا يرجع أي قيمة ، لكن بإمكاننا استبدال هذا النوع بـ string

أي أن هذه الدالة ستقوم بعمليات معينة ثم ستعيد نصاً إلى مكان استدعائها

 

بما أن هذه الدالة أصبحت من النوع string  و ليس void  فيجب أن ترجع قيمة و بالتالي ستحتوي على return لشيء ما في نهايتها

و القيمة التي نريد ارجاعها هي النص الموجود لدينا  فيصبح السطر الأخير :

;Return string.concat(firstNameArray)

عندها سيكون هذا السطر راجعاً من الدالة DisplayResult

أي أنني في الأعلى يمكنني أن أقوم بتعريف

;()string firstName = DisplayResult

و النوع الموجود قبل إشارة المساواة من النوع string وبالتالي DisplayResult ذات الأمر ، لأن الدالة الموجودة في الأسفل من النوع string و النتيجة الراجعة من النوع string

نقوم بتشغيل التطبيق لنتأكد من صحة المعلومات و نلاحظ أنني لا اريد أن أقوم بطباعة الناتج داخل الدالة الثانية بل سأقوم بطباعته في الدالة void

 

فعلا قام التطبيق بطباعة osama  بشكل معكوس

سنلاحظ بعد قليل أن هذه الدالة قامت باختصار كاف الاسطر السابقة

 

و نتذكر أن الدوال من الممكن أن تكون int , string أو أي نوع من أنواع البيانات و يمكن أن تكون دالة لا ترجع قيمة مثل void

الشرط الأساسي أنه إذا لم تكن من النوع void فيجب عليك أن تقوم بإرجاع قيمة و هذه الدالة قامت بعمليات معينة و قامت بإرجاع الناتج النهائي
يمكننا الحصول على القيمة المرجعة عن طريق وضعها على الجانب الأيمن لإشارة المساواة في السطر الذي قمنا به باستدعاء الدالة و سيتم تخزينها مباشرة في firstName

الآن أريد استخدام هذه الدالة ليس فقط لطباعة الاسم الأول
بل لطباعة الاسم الأول و الأخير و السؤال عن المدينة التي ولد فيها

إذا في الدالة يمكنك أن تقوم بإرسال قيمة
لذلك سنقوم بتعريف متغير جديد

عندما نقوم باستدعاء الدالة يجب أن نرسل قيمة يتم ارسالها إلى الدالة

 

لذلك سنقوم بحذف السؤال في الدالة و نجعله قادماً من مكان استدعائها

إذا سنأخذ المتغير question و نضعه بعد string  بين قوسي الدالة (  )

الناتج كالتالي

سنقوم باستدعاء الدالة و نرفق معها السؤال بين القوسين ، عندها سيأخذ السؤال و يقوم بطباعته مباشرة و يقوم بعمليات معينة و يقوم بإرجاع القيمة النهائية إلى هذا المكان

 

الآن قمنا بإرسال هذا النص إلى الدالة و قام بطباعته و استخدام القيمة المرسالة مع هذه الدالة

نقوم بتعريف متغير جديد اسمه lastName ، و سأسأله سؤال ” ما هو اسمك الأخير” و القيمة الراجعة من الدالة سيقوم بإسناده للمتغير lastName
ثم نسأله عن مكان الولادة

لاحظو أن هذه الثلاث أسطر هي فعليا 12 سطر
لنتأكد أن القيمة الراجعة صحيحة

ثم نقوم بطباعة الناتج النهائي

بتشغيل التطبيق سيسأل عن الاسم الأول و الأخير و المدينة ، و سيقوم بعرض ذات النتيجة التي عرضها في التجربة الأولى

في حال حدوث مشكلة لا يجب تتبع الأسطر كلها ، بل نقوم بتتبع أسطر الدالة القليلة
حيث استخدمناها لتقليل عدد الأسطر

 

نصل الآن لنهاية هذا الدرس ، ألقاك في الدرس التالي إن شاء الله

 

ملخص الدرس :

السلامُ عليكم ورحمةُ اللهِ وبركاته، وأهلاً بكمْ في الدرسِ الرابع عشر من دروسِ سلسلةِ، تَعلُمِ البرمجةِ للمبتدئينَ كلياً بواسطةِ السي شارب، في هذا الدرس سنتعرف على  الدوال Methods أو ما يسمى Function في لغات أخرى، والتي تعتبر العصب الرئيسي الذي يقوم عليه أي تطبيق ولا يخلو منها.

الدوال Methods :

يمكن تعريف الدالة على أنها قطعة برمجية Code Block تبدأ بجملة تعريفية بإسمها ونوعها سواء كانت نصية string أو رقمية int أو لا ترجع أي قيمة void أو أي نوع آخر. والدوال لها العديد من الميزات أهمها:
– تقليل عدد التكرارات الموجودة في التطبيق، وبالتالي قلة عدد الأسطر الإجمالي.
– تنظم المشروع، بحيث تكون الأسطر البرمجية الخاصة بعملية معينة في مكان واحد.
– سهولة إيجاد المشاكل المنطقية في حال وجودها لاحقاً.
و طريقة كتابة الدالة هكذا :
Method_Type Method_Name ()
}
{

خصائص الدوال :

كما ذكرنا قبل قليل، إن كانت الدالة غير النوع void ( لا ترجع أي قيمة)، أي أنها من النوع int أو string أو float أو أي نوع آخر، فيجب أن تقوم بإضافة سطر return value في نهايتها ويمكن الحصول على العائد من الدالة بعملية الإسناد، أيضاً يمكن إرسال قيم عند مناداة الدالة لإستخدامها داخل الدالة وهي ما تدعى arguments أو parameters ، وهي متغيرات يتم إستخدامها داخل الدالة للقيام بالمهمة الموكلة لها.

مصطلحات الدرس :

Methods :

Block of Code :

return :

float :

arguments :

parameters :

الأسطر البرمجية التي تم إستخدامها في الدرس :

post

بناء نموذج ذو جودة عالية وإظهاره داخل محرك Unity

خطوات تحويل صور إلى مجسم ثلاثي الأبعاد لإظهاره داخل محرك Unity

 لمحة عن المقالة:

السلام عليكم ورحمة الله وبركاته، في الآونة الأخيرة ظهرت برامج تساعد المنمذجين 3D Modelers لبناء نماذج حقيقية Models تحتوي على تفاصيل كثيرة High Details بالإضافة إلى الخرائط الخاصة بها Textures ، ولعل من أشهرها تطبيق Reality Capture ، هذه النماذج غالباً تحتاج لإعادة تنقيح قبل إستخدامها في محركات الألعاب بسبب حجمها الكبير، وغالباً يتم ذلك بواسطة برامج النمذجة مثل 3Ds Max أو Maya، قامت شركة Unity بكتابة درس تفصيلي من 100 صفحة تقريباً خطوة بخطوة من تجهيز الأدوات إلى تجهيز النموذج لوضعهم داخل لعبتك، سنقوم بسرد أهم العمليات المستخدمة في المقالة ثم وضع رابط للنسخة المفصلة.

الأدوات والتطبيقات المستخدمة :

بالنسبة للأدوات، تتراوح حسب قدرتك وحسب إمكانياتك المتاحة، كل ما كانت أدوات التصوير أفضل كلما حصلت على جودة أعلى، يمكنك إستخدام كاميرا الموبايل لكن النتيجة بالتأكيد لن تكون كمن يقوم بإستخدام كاميرا متخصصة للتصوير الفوتوغرافي، الكاميرا المستخدمة في المقالة هي Canon 6D مع العدة الخاصة بها.
أما بالنسبة للتطبيقات التي سيتم إستخدامها للتعديل وللإخراج النهائي فهنا أهمها:

– Reality Capture : البرنامج الذي ستستخدمه لتحويل الصور إلى مجسمات ثلاثية الألعاب ، رابط موقع البرنامج هنا.
– Autodesk 3ds Max : البرنامج الذي ستقوم بتعديل النموذج الأولي Raw model وإعادة بناءه Retopology لكي يصبح جاهز للإستخدام، أيضاً سيستخدم لعملية فرد الخرائط Unwrap UV ، رابط موقع البرنامج هنا.
– Adobe Photoshop : البرنامج الذي ستستخدمه لعمل تعديل على الخرائط الناتجة من البرنامج الأول Textures بحيث تتناسب مع النتيجة النهائية، رابط موقع البرنامج هنا.
– Unity : بالتأكيد لا ننسى المحرك الذي سنقوم بإظهار النموذج النهائي عليه، محرك اليونيتي مجاني ويمكن تحميله من هنا.
هناك بعض التطبيقات التي ستحتاجها في بعض التعديلات البسيطة أيضاً.

ما قبل التصوير:

هناك بعض القواعد الأساسية التي يجب أن تأخذها بالحسبان قبل البدء بعملية التصوير، أهمها:
– الإجابة على The 3 W’s : الشيء الذي تود تصويره What،  أفضل موقع يمكن الحصول عليه Where، أفضل وقت تستطيع الحصول على جودة عالية عليه When.
– صور أم فيديو : في النهاية يجب الحصول على صور من كل الزوايا لإعطاء إمكانية لبرنامج Reality Capture الحصول على جودة عالية.
– إعدادات الكاميرا : النتيحة تختلف كلياً حسب إعدادات الكاميرا المختارة، يجب أن تكون على دراية تامة بهذه الإعدادات.

الحصول على الصور :

في هذا القسم ستذهب إلى الموقع المراد أخذ الصور منه، إن كان المجسم صغير يمكنك إلتقاط الصور له مباشرة، وإن كان كبير يمكنك الإستعانة بالطائرة drone لأخذ الصور له. أيضاً في حال كان المجسم صغير وفي متناول الأيدي يمكنك تصويره في بيئة تقوم بإعدادها أنت وبالتالي تحصل على نتائج أفضل، وإن كان الشيء المراد تصويره شيء حقيقي ستذهب وتقوم ببعض الخطوات لتضمن الحصول على نتائج مناسبة.

معالجة النموذج :

بعد الحصول على الصور ووضعهم داخل تطبيق Reality Capture سيقوم بمعالجتهم وتحويلهم إلى مجسم 3D Model ، يجدر الإشارة إلى أن النموذج الناتج غالباً يحتاج إلى تعديل، سواءاً بإعادة ترتيب الأوجه Polygons Retopology ، أو بإعادة تركيب طريقة فرد المجسمات على الخريطة Unwrap UV Texture ، ويتم ذلك بإستخدام تطبيق 3ds Max .

معالجة خرائط النموذج :

أو ما يسمى 3D Model Textures ، وهناك العديد من الخرائط التي يتوجب عليك العناية بها للحصول على جودة عالية في إظهار النموذج، حيث ستستخدم هذه الخرائط في إخراج المادة النهائية Material التي تتأثر بفيزيائية المادة، ويتم إستخدام تطبيقات للحصول على هذه الخرائط أشهرها Xnormal، وهنا لمحة عن أهم الخرائط Textures المهمة :

– خريطة الألوان الأساسية Albedo Map: أو تسمى Diffuse Map، هذه الخريطة أساسية وتحتوي على الألوان الحقيقية للمجسم.
– خريطة التفاصيل Normal Map : وتحتوي على معلومات يتم إستخدامها لإظهار تفاصيل إضافية على المجسم إستناداً إلى زاوية الضوء.
– خريطة الظل الغير مباشر Ambient Occlusion Map : وتحتوي على الظلال الخفيفة التي تتواجد في حال عدم وجود مصدر ضوء مباشر على المجسم.
هناك العديد من الخرائط الأخرى أيضاً منها : Height Map, Vertex color Map,Object space Normals Map.

تجميع النموذج النهائي :

بعد الحصول على نموذج نظيف يمكن تصديره كـ FBX ، وبعد الإنتهاء من الخرائط الأساسية يمكن تصديرها كـ TGA لجودة عالية أو يمكن تحويلها إلى PNG لحجم أقل، بعد السابق يتم تجميعهم وإضافتهم داخل محرك الألعاب Unity ، لتظهر كما في الصورة التالية:

الكتاب الإلكتروني الأصلي الذي يحتوي على التفاصيل تجده هنا.

post

وثيقة تطوير اللعبة Game Design Document

أهمية وثيقة تطوير اللعبة وكيف تقلل الوقت والجهد على فريق تطوير الألعاب

نبذة عن وثيقة تطوير اللعبة GDD :

السلام عليكم ورحمة الله وبركاته، كثر في الآونة الأخيرة إزدياد أعداد المطورين العرب، ومن المؤسف رؤية الكثير يقفز عن أهم مرحلة من مراحل تطوير اللعبة، ألا وهي المرحلة النظرية أو مرحلة كتابة مستند تطوير اللعبة المسمى Game Design Document ذو الإختصار GDD، حيث تكون في مرحلة قبل التطوير Pre-Production، فلازلنا نرى التوجه المباشر نحو محركات الألعاب، ولغات البرمجة وأدوات التصميم بشكل عشوائي وغير منظم، مما يضيع الكثير من الجهد والوقت خلال عملية تطوير الألعاب بحد ذاتها، لذلك كان لا بد من التطرق إلى مثال عملي عن هذه المرحلة، لكشف أهميتها لدى المطورين أنفسهم، ولتضفي خبرة كافية لهم لكي يقوموا بالإنتباه لها في مشاريعهم الحالية والمستقبلية.

إن كنت المسؤول عن عملية تصميم اللعبة Game Design ، فأنصحك بالإضطلاع على مهارات مصمم الألعاب عبر المقالة التالية : كيف تصبح مصمم ألعاب ناجح ، حيث تعتبر المقالة السابقة مقالة نظرية، وفي هذه المقالة سندخل تجربة تطبيق للعبة يتم تطويرها حالياً.

محتويات وثيقة تطوير اللعبة :

يمكن أن تحتوي هذه الوثيقة على خليط بين النصوص والصور والأشكال التعريفية Diagrams، أو سكيتشات أولية Concept Arts بالإضافة إلى أنها يمكن أن تحمل خوارزميات أو أسطر برمجية قياسية، أو ما يمكن تسميته Pseudocode يعطي إنطباع عن المهام الوظيفية التي ستكون داخل اللعبة، ويمكن تلخيص الأقسام الرئيسية التي تحويها كالتالي :

القصة Story : حيث يتم كتابة الفكرة الأولية للسيناريو وقصة اللعبة، ويمكن تفصيلها وتعديلها لاحقاً.
الشخصيات الرئيسية Characters : فكرة عن طبيعة شخصية اللاعب و الشخصيات المشاركة باللعبة، أو ما يعرف ب Non-Player Characters ذو الإختصار الشهير NPC.
تصميم المراحل Level/environment design : يتم وضع تصور عام عن بعض المراحل، ويمكن أن تكون عبارة عن رسومات أولية على أوراق حقيقية.
طريقة اللعبة Gameplay : وهي جوهر اللعبة لأهميتها، ويمكنك مراجعة مقالة كيف تصبح مصمم ألعاب ناجح ، للمزيد من المعلومات حول تصميم اللعبة.
الرسومات Art : السمة العامة المستخدمة داخل اللعبة، هل هي ثلاثية البعد أم ثنائية البعد، هل تصاميمها حقيقية أم كرتونية وهكذا، وتصورات مرسومة عن تفاصيل اللعبة.
الأصوات Sound and Music : نوع النمط الخاص بالصوتيات Genre ، ويمكن إرفاق ملفات أصوات سابقة مع الوثيقة.
الواجهات الرسومية User Interface : أو ما يعرف بال UI حيث يتم رسم المعلومات التي ستبقى على الشاشة خلال اللعب وماهيتها.
أزرار التحكم Game Controls : يمكن أيضاً كتابة كيفية التحكم في اللعبة، وما هي المنصة المستخدمة هل ستكون أحرف لوحة المفاتيح أم النقر كما في أجهزة الموبايل.

لعبة حرب القواعد – تطبيق عملي :

كما تعرفنا في المعلومات السابقة، أنه يمكن ضم عدد لا بأس به من الأقسام الرئيسية التي يجب أن تكون واضحة منذ بداية التطوير لكي تختصر الكثير من الوقت والجهد، في لعبة حرب القواعد تم كتابة 3 وثائق تفصيلية يمكن دمجهم معاً لتحصل على وثيقة تطوير اللعبة Game Design Document ، وهنا تم تفصيل 3 أقسام رئيسية يمكن تلخيصلهم بالشكل التالي :

1 – الوثيقة الأولية Game Concept Document :

حيث تم بروز فكرة لعبة في ذهن الأستاذ أسامة ديب ( صاحب المشروع ) لمحاكاة لعبة تحتوي على قلعتين متباعدتين، حيث يتسابقان لهدم قلعة الآخر من خلال بناء وحدات معينة، الفكرة السابقة كان لا بد من كتابتها في وثيقة ضمت المحاور التالية : شرح الفكرة، ميزات اللعبة، نوع اللعبة Genre، المنصة المستخدمة، وتطبيقات اللعبة. الوثقة تحتوي على 5 صفحات يمكن تصفحها مباشرة  هنا.

2 – الوثيقة الوظفية Functional Specification Document:

بعد الإنتهاء من الوثيقة الأولية يتم البدء بالتعمق في جوانب اللعبة التقنية ، حيث يتم تفصيل ميكانيكية اللعبة من خلال الكتابة عن نواة اللعبة وتسلسل الأحداث داخل اللعبة ، والعناصر الأساسية للعبة Game Units ، ثم التفصيل أكثر حول واجهات اللعبة الأساسية User Interface ، ومن ثم كتابة تخطيط بياني وخوارزميات لها ، إنتقالاً إلى التصاميم والرسوميات المستخدمة والسكيتشات إن وجد ذلك ، والأفلام البينية داخل اللعبة ، إنتقالاً للأصوات التي سيتم إستخدامها والموسيقى ، مروراً بسرد قصة للعبة حيث يتم إدخال اللاعب في قصة متسلسلة للعبة ككل ، والإنتقال إلى المراحل التي ستتكون منها اللعبة ، كل السابق قد تم كتابته بشكل عملي داخل هذه الوثيقة، تحتوي هذه الوثيقة على 8 صفحات يمكن تصفحها مباشرة هنا.

 

3 – الوثيقة التقنية Technical Specification Document :

بنفس الأقسام التي كانت في الوثيقة الوظيفية يتم التعمق أكثر حيث أن هذه الوثيقة ستكون مفهومة بشكل أساسي للمطورين و الرسامين المتواجدين ضمن الفريق ، حيث ستلاحظوا أنه في هذه الوثيقة سنناقش المنصة ونظام التشغيل بشكل مباشر من خلال إنتقاء مواصفات معينة ، وسيتم الإكثار من الخوارزميات الأساسية للعبة وتفصيلها برمجياً على شكل Pseudo Code بحيث يمكن للمبرمجين البدء الفعلي في كتابة الأكواد الخاصة باللعبة ، أيضاً يتم البدء في تحديد الأجزاء الأساسية التي ستظهر على الوجهات الرسومية المختلفة ، مروراً بالتصاميم ثنائية أو ثلاثية البعد ، وتحديد البرامح والمحركات التي سيتم إستخدامها خلال مراحل تطوير اللعبة ، إلى الأصوات والموسيقى ، وتفصيلاً أخيراً للمراحل، تحتوي هذه الوثيقة على 8 صفحات يمكن تصفحها مباشرة هنا.

 

  • يجدر بالذكر أن حرب القواعد تم تغيير إسمها إلى Get That Sheep ويمكن رؤية النتيجة الحالية للمشروع كما في الفيديو التالي :