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

محرك الألعاب - الأندلس- : الأدوات و خطة العمل والتطوير

رائج
بدأه Abdullah.Alshammeri في 18 سبتمبر 2009 · 78 رد · 6,838 مشاهدة · في قسم برمجة الألعاب و الرسوميات العام
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

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

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

Al-Andalus Game Engine

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

الأدوات المستخدمة :

  • النسخة 0.1
  • لغة السي بلس بلس
    • سيتم الاعتماد على مكتبات السي بلس القياسية بما فيها STL وذلك فيما يخص هياكل البيانات + الملفات + النصوص std::string .. الخ .
    • نظام ويندوز اكس بي - فيستا :
      • Visual C++ 2008 Professional
      • OpenGL 1.1 تأتي مع المترجم بشكل تلقائي
      • سيتم استخدام Win32 API في انشاء النافذة وربطها مع المكتبة الرسومية
      • مبدئيا سنستخدم Win32 APIs لاستقبال المدخلات من الكيبورد والماوس اذا لم توجد طريقة أفضل
      • Direct3d 9.c ولن تأتي مع المشروع .. على من يريد دعم الدايركت ثري دي أن يقوم بتحميل النسخة المناسبة وربطها مع المحرك ووضع شرح لرقم النسخة المستخدمة من sdk وطريقة الربط

      [*]نظام لينكس :

      • لا أعرف ماهي المكتبات والأدوات المطلوبة , من يريد التطوير على لينكس المساعدة في شرح المطلوب
      • في الغالب سيتم استخدام SDL + OpenGL

      [*]يمكن استخدام المكتبة QT لمن أراد دعمها , وتستخدم لانشاء النافذة وربطها مع OpenGL واستقبال المدخلات من الكيبورد والماوس وغير ذلك .. وهذا كاضافة للمحرك وليس ركن أساسي فيه .

    [*]لغة الجافا:

    • JDK 6 Update 16 with NetBeans 6.7.1
    • مكتبة OpenGL للرسوميات وسيتم استخدام المكتبة LWJGL لدعم OpenGL :
      لتثبيت المكتبة وتطبيق درس أساسي بسيط انظر :
      /index.php?showtopic=165722
      لاتحتاج الى اتقان OpenGL , يمكنك تجنبها والمساهمة في تطوير الاجزاء التي لاتعتمد على المكتبة OpenGL .
    • سيتم استخدام مكتبات الجافا القياسية في التعامل مع الملفات + هياكل البيانات+أي شيء اخر

    [*]لغة السي شارب

    • يمكن لأي شخص أن ينشئ مشروع خاص بهذه اللغة ويختار أحد الخيارين التاليين:
      1. Visual C# 2005 + XNA 2
      2. Visual C# 2008 + XNA 3

      [*]تسمية المتغيرات والدوال والأصناف

      • في لغة السي بلس , أرى أن نعتمد طريقة الجافا في كتابة الكود .. أجد أنها الافضل , مثال :


        namespace Andalus
        {
        namespace Gfx
        {
        class Graphics
        {
        virtual void drawPoint(int x,int y ,Color color)=0;
        };
        class D3dGraphics : public Graphics
        {
        private:
        Color pointColor;
        int xPos;
        int yPos;
        void _privateFunction();
        public:
        void drawPoint(int x,int y,Color color)
        {
        const int MAX_XPOS = WINDOW_WIDTH ;
        int tempVariable = 0;
        int i,j,k;// counters
        this->pointColor = color;
        this->xPos = x;
        this->yPos = y;
        .
        .
        .
        }
        };
        }//gfx
        }//andalus


      • كل كلاس class يكون في ملف مستقل ( ملف header للتعريف فقط وخالي من أي implementation قدر الامكان وملف source لكتابة الكود ) , ويكون اسم الملف مطابق تماما لاسم الكلاس حتى بحالة الاحرف.
      • يتم حراسة ملف الهيدر بالـ preprocessor بهذا الشكل :
        #ifndef GFX_Graphics_H
        #define GFX_Graphics_H
        .
        .
        #endif


      • الجافا والسي شارب تتبعان أسلوب كتابة الأكواد الأصلي في اللغة :

      [*] اسماء الفئات و الـ strcut و enum و union كلها تبدأ بحروف كبيره و بدون استخدام بادئة , وجميعها تكون داخل namespace معين.

      [*] اسماء المتغيرات تبدأ بحروف صغيره و اى كلمه تليها بدأ بحروف كبيره.

      [*] اسماء الدوال تبدأ بحروف صغيرة و اسماء المعاملات تكون بحروف صغيره دائما.

      [*] يتم تعريف المتغيرات قبل استخدامها و يتم كتابة ملاحظات فوقها لسبب تعريف هذا المتغير و فيما استخدامه

      [*] التوثيق ( شرح واجهة المحرك وذلك من أجل انشاء ملف تعليمات للمحرك ) يكتب فوق كل انواع البيانات و سيتم استخدام مايلي :

      doxygen في كتابة شرح الكود , للغة السي بلس , ابحث عن أمثلة وشرح لهذه الاداة , هذا مثال :

      /**
       * @file tutorial.h
       * @author Chris Olsen
       * @date 2-26-04
       */
      #ifndef __TUTORIAL__
      #define __TUTORIAL__
      
      
      
      /**
       * An example class for the Doxygen tutorial
       */
      class Tutorial
      {
      public:
        /// The Constructor
        Tutorial();
      
        /** The Destructor */
        virtual ~Tutorial();
      
        /**
      	 Takes three inputs and does something
      
      	 @param a A float paramater
      	 @param b An int paramater
      	 @param c A char paramater
      	 @return Returns an integer
        */
        int Method1(float a, int b, char c);
      
        int var;  ///< This was commented after declaration
      };
      
      #endif

      javadoc للغة الجافا , مثال :

      /**
       * Returns an Image object that can then be painted on the screen. 
       * The url argument must specify an absolute {@link URL}. The name
       * argument is a specifier that is relative to the url argument. 
       * <p>
       * This method always returns immediately, whether or not the 
       * image exists. When this applet attempts to draw the image on
       * the screen, the data will be loaded. The graphics primitives 
       * that draw the image will incrementally paint on the screen. 
       *
       * @param  url  an absolute URL giving the base location of the image
       * @param  name the location of the image, relative to the url argument
       * @return	  the image at the specified URL
       * @see		 Image
       */
       public Image getImage(URL url, String name) {
      	try {
      		return getImage(new URL(url, name));
      	} catch (MalformedURLException e) {
      		return null;
      	}
       }

      السي شارب , سيتم استخدام وسم xml ( انظر المشاركة رقم 7 ) .

      أما فيما يتعلق بكتابة تعليقات على الكود الداخلي للمحرك , فيتم بطريقة عادية ( مثل // أو /* */ )

      [*] يتم تنظيم الكود و يتم استخدام الأقواس { } دائما مع for او if حتى لو كان الكود مكون من سطر واحد و ذلك لوجود ملاحظات فوق الكود و ايضا لتسهيل قرائة الكود، ايضا يمكنك استخدام تلك الأقواس فقط مع بعض الأكواد لتجميعها و ذلك لتنظيم الكود.

      [*]للغة السي بلس :سيتم استخدام الكلمة interface للدلالة على الواجهات , والكلمة pure للدلالة على pure funcion , هكذا :

      #define interface struct
      #define pure = 0
      
      .
      .
      .
      interface X
      {
      virtual void pureFoo() pure;
      }

      كما سيتم اعتماد Alias معين لبعض الانواع .. سيتم شرحه أثناء مراحل المشروع

      [*]طريقة اكتشاف الأخطاء ومعالجتها :

      ماهي أفضل طريقة ؟!!

      اقترح استخدام الاستثناءات Exceptions , في اقتناص الاخطاء خصوصا عن التعامل مع الملفات أو عمل أمور حرجة , في الامور البسيطة مثل الموجودة في الحزمة core الخاصة بالدوال الرياضية مثلا .. لاحاجة الى الاستثناءات حتى لايؤثر على اداء المحرك .

      أيضا سنستخدم log (كتابة الى الملف ) وهو على مستويين .. DEBUG لتتبع اي عملية حجز أو الغاء للكائن أو في أي مكان حرج مثل تحميل صورة من ملف هل نجحت العملية أم لا ؟

      .. المستوى الاخر INFO لكتابة معلومات عن المحرك والعتاد الذي يعمل عليه .. وفي الغالب ستكون معلومات بسيطة عن كرت الشاشة والعتاد الذي يستخدمه المستخدم النهائي .

      [*]الطريقة التي سنسير عليها في المشروع + مثال :

      • كل حزمة package من المشروع سيفرد لها موضوع خاص - تقريبا - ( سنأخذ مثال , على حزمة الصور image . )
      • في كل موضوع سيكون الحديث عن أربع نقاط بالترتيب :
        • التحليل الأولي للموضوع : ( لايوجد علاقة للغة البرمجة هنا )
          - هنا نعرف فائدة هذه الحزمة , في حالتنا هذه image , وهي تضم واجهات interfaces و فئات Classes لتحميل صورة من ملف وتخزينها في كائن موجود في الذاكرة مصمم لهذا الغرض .
          - يأتي مبرمج , ويقترح ان ندعم نسقين من الصور BMP - TGA .
          - يأتي مبرمج اخر , ويقترح أن تكون الصور المدعومة غير مضغوطة Uncompressed , وتكون من نوع 32Bits و 24Bits فقط .
          - يأتي مبرمج ثالث , ويقترح اضافة ميزة امكانية تغيير أبعاد الصورة بعد تحميلها واضافة تاثيرات عليها مثل ازالة الألوان الغير مرغوبة من الصورة .
          - هنا تبدأ تتضح معالم Classes و Interfaces و Enumerations التي سنحتاجها .. والعلاقات بين الكلاسات Classes :

          - ImageBuffer <class>


          {
          int width,height,bpp;
          bytes color[] ;
          ImageFormat format;
          }
          - ImageUtil .
          - ImageReader <interface>
          - ImageWriter <interface>
          - BmpImageReader <class that implements ImageReader>
          - BmpImageWriter <class that implements ImageWriter>
          - ImageFormat
          {
          IF_RGBA,IF_RGB .....
          }


        • كتابة مواصفات Specification للكلاسات Classes التي سيستخدمها المستخدم النهائي . ( لايوجد علاقة للغة البرمجة هنا )
          هنا .. الكلاسات التي سيستخدمها المستخدم النهائي هي ImageReader و ImageWriter و ImageBuffer و ImageUtil ، فنكتب مواصفاتها :

          // Interface that read an image from specific file into ImageBuffer


          ImageReader <interface>
          {
          /// @Purpose : load an image from specific file and create new object of ImageBuffer
          /// that holds image info .
          /// @Parameters:
          /// - fileName : image file name ( full path ) .
          /// @return :
          /// on success :new ImageBuffer object holds image info
          /// on failure : NULL;
          /// @Exception :
          /// FileNotFoundException if the image does not exist .
          /// FileFormatNotSupportedException if the image format is not supported.
          [byRef] ImageBuffer read( [iN] string fileName) ; <pure virtual method >
          };


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

        • اسناد مهمة تحويل هذه الكلاسات الى كود أي عمل Implementation لواجهة المحرك المذكورة في هذا الموضوع
          - الان كل شخص يتحمل جزء من مسؤولية تحويل بعض الواجهات والكلاسات الى كود .. قد نواجه مشاكل .. نبحث .. ونتساعد حتى نحل الاشكال , في الغالب المشاكل ستخص المفاهيم وليس مشاكل بسبب عدم معرفة في لغة البرمجة المستخدمة .. نفرض أن المشاركين , يتقنون اللغات المستخدمة .
          طبعا كل لغة برمجية .. سيكون لها ملفاتها الخاصة دون وجود تعارض بينها .. كل شخص يركز على اللغة التي يريد لتحويل ما سبق من نقاش الى كود .
        • عمل اختبارات للناتج النهائي ثم تجميع الأكواد في حزمة واحدة وضمها للمحرك
          حيث يتم تجميع كل ماقام به الاعضاء واضافتها للمشروع ( ملفات السي بلس تضاف الى مشروع السي بلس و ملفات الجافا تضاف الى مشروع الجافا , كل مشروع مستقل عن الاخر ولكن واجهة المحرك واحدة وان اختلف الكود الداخلي ) .. ونختبر الكود لتحميل صورة معينة وعرض بيانتها .
          ثم نغلق هذا الموضوع لننتقل الى الحزمة التالية .
        • في بعض الحزم - بعض أجزاء المشروع - نحتاج الى أكثر من موضوع , وذلك بسبب اختلاف بنية الكود بشكل جذري من لغة الى أخرى .. وفي هذه الحالة يتم مايلي .
          1- الموضوع الرئيس , وهو كما تم وصفه في النقطة السابقة .. يناقش ويحلل الحزمة بغض النظر عن اللغة البرمجية ثم يتم كتابة كود الحزمة باستخدم لغة السي بلس
          2- في موضوع منفصل يتم مناقشة كيفية تحويل المناقشات التي وردت في الموضوع الرئيس .. الى كود في الجافا
          3- يتم فتح موضوع منفصل للغة السي شارب يتم مناقشة كيفية تحويل المناقشات التي وردت في الموضوع الرئيس .. الى كود في السي شارب

تم تعديل هذه المشاركة بواسطة الشمري في 23 سبتمبر 2009 في 04:12

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#2

السلام عليكم,

هل يجب ان اكون ملماً بالـ OpenGL او الـ DirectX كي اناقش, الا يكفي ++C :unsure: ؟؟؟

If Games Are Fun.....So Making Games Making Fun

#3

هناك الكثير من الحزم لاتحتاج الى خبرة بهما , مثل :

image

kernel ( جزء منها ) .

core

وبشكل عام .. تستطيع المشاركة في المرحلة الأولى والثانية ( التحليل وكتابة المواصفات ) في الأمور التي تتعلق بالرسوميات GL - D3D , حيث كل مانحتاج اليه مفاهيم في برمجة الالعاب + هندسة وتصميم الكود ... لان النقاش والتحليل سيكون بشكل منعزل عن أي مكتبة رسومية أو غير رسومية ..

لذلك لايوجد شخص ملم بكل شيء , فنشارك بالأمور التي نعرفها ونتعلم الاشياء الجديدة خاصة في مسألة تصميم المشروع .. أي تصميم المحركات ..

تم تعديل هذه المشاركة بواسطة الشمري في 19 سبتمبر 2009 في 04:01

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#4

الحزمة LWJGL جديده علي

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

تحياتي

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

#5

كلام جميل اخى الشمرى و لكن لماذا حرف الـ X قبل اسماء الفئات لماذا نتركها بدون بادئه، عموما لدى اقتراح

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

1 - بالنسبه لأدوات العمل اوافقك على ما قلت و لكنك لم تأتى على ذكر Assembler فى حال احتياجنا له ايضا الفيجوال ستديو 2008 له sp1 يفضل تثبيتها لتلاشى حدوث مشاكل.

2 -بالنسبه للكود يفضل على مستوى المحرك ان تكون كل الفئات private بمعنى ان المستخدم سيتعامل مع interfaces فقط و بالتالى تصبح الفئات غير متاحه للمستخدم ايضا لابد من وجود فئه Manager لتقوم بعمل initialize للمكتبه بالـ API المستخدمه مثل OpenGL او DirectX ايضا كل الدوال تعود بنسخه من interface و ليس فئه معينه.

3 - سنحتاج لإستخدام source safe او team foundation حتى اذا اردنا الحصول على كود معين بمرحله معينه تكون متاحه. حيث ان المشروع سيكون مفتوح المصدر لماذا لا نستخدم codeplex حيث انه يوفر اكثر من code source safe و لكنه يعطيك مدة شهر لإنهاء برنامجك.

4 - يمكن بدء المشروع لويندوز فقط و بعد اكتمال اول اصدار منه نقوم فى الإصدار الثانى بوضع انظمة تشغيل اخرى فى الإعتبار و ذلك للإنتهاء من الإصدار الأول كبدايه ثانيا كى نخطط له جيدا.

5 - بالنسبه للكود فلى بعض الإقتراحات

1 - يتم عمل Aliasing لكل أنواع البيانات المستخدمه مثل التالى

#ifndef DATA_TYPES_H

#define DATA_TYPES_H

// signed 8-bit integer

typedef signed char int8;

// unsigned 8-bit integer

typedef unsigned char uint8;

// signed 16-bit integer

typedef signed short int16;

// unsigned 16-bit integer

typedef unsigned short uint16;

// signed 32-bit integer

typedef signed int int32;

// unsigned 32-bit integer

typedef unsigned int uint32;

// signed 64-bit integer

typedef signed long long int64;

// unsigned 64-bit integer

typedef unsigned long long uint64;

// unicode character

typedef wchar_t uchar;

// ascii character

typedef uint8 achar;

// object block

typedef void* blob;

// signed 8-bit integer pointer

typedef int8* int8ptr;

// unsigned 8-bit integer pointer

typedef uint8* uint8ptr;

// signed 16-bit integer pointer

typedef int16* int16ptr;

// unsigned 16-bit integer pointer

typedef uint16* uint16ptr;

// signed 32-bit integer pointer

typedef int32* int32ptr;

// unsigned 32-bit integer pointer

typedef uint32* uint32ptr;

// signed 64-bit integer pointer

typedef int64* int64ptr;

// unsigned648-bit integer pointer

typedef uint64* uint64ptr;

// null pointer

#define nulldata 0

// interface defination

#define interface struct

// pure virtual function defination

#define pure = 0

#endif // DATA_TYPES_H

و السبب فى ذلك اولا لتوحيد اسماء انواع البيانات داخل المشروع ثانيا عند محاولة عمل تصدير للمشروع لأى نظام تشغيل اخر و كانت انواع البيانات تختلف فى احجامها (افتراضا) كل ما سنحتاج إليه هو تغيرها هنا.

2 - اسماء مجال الأسماء يبدأ بحروف كبيره و بدون استخدام بادءات فلا داعى لها (سأذكر السبب فى الأخر) مثل

namespace Core

3 - ملف الـ header الذى سيحتوى على فئات او struct يكون الـ pre-processor الخاص به يكون كالتالى

#ifndef CORE_MATH_H

#define CORE_MATH_H

nameapce Core

{

class Math

{

};

}

#endif // CORE_MATH_H

كما ترى بدأنا بإسم مجال الأسماء يليه اسم الفئه و بالتالى اسم الـ pre-processor لن يتكرر و سيصبح ذات معنى.

4 - اسماء الفئات و الـ strcut و enum و union كلها تبدأ بحروف كبيره و بدون استخدام بادئه و السبب مره اخرى انه لا داعى له(و سأذكر السبب لاحقا).

5 - اسماء المتغيرات تبدأ بحروف صغيره و اى كلمه تليها بدأ بحروف كبيره.

6 - اسماء الدوال تبدأ بحروف كبيره و اسماء المعاملات تكون بحروف صغيره دائما.

7 - يتم تعريف المتغيرات قبل استخدامها و يتم كتابة ملاحظات فوقها لسبب تعريف هذا المتغير و فيما استخدامه

8 - الملاحظات تكتب فوق كل انواع البيانات و تأخذ شكل xml (سنتبع نظام الـ C# فى الملاحظات و ذلك لوجود ادوات تحول تلك الملاحظات إلى ملفات مساعده بسهوله و ايضا لسهولة قرائتها).

و لمن لا يعرف نظام ملاحظات الـ C# سأقوم بوضع مشاركه لشرح مكوناتها بشكل سريع.

9 - يتم تنظيم الكود و يتم استخدام الأقواس { } دائما مع for او if حتى لو كان الكود مكون من سطر واحد و ذلك لوجود ملاحظات فوق الكود و ايضا لتسهيل قرائة الكود، ايضا يمكنك استخدام تلك الأقواس فقط مع بعض الأكواد لتجميعها و ذلك لتنظيم الكود.

10 - قلنا من قبل ان المستخدم سيتعامل مع واجهات هذه الواجهات يتم تعريفها بالكلمه struct او interface (كما هو موجود بالأعلى و هى إعادة تعريف للكلمه struct) و دائما ما ستحتوى على pure virtual function.

11 - الفئات الـ templates (حيث انها فئات لن تكون مرئيه للمستخدم كما ذكرنا) لابد من وجود الكود الخاص بها داخل ملف header و لكننا لا نكتب اكواد داخل ملفات الـ header و الحل يتكون من قسمين اولهم قم بعمل فئه تأخذ نفس اسم الفئه الـ template و لكنها تحتوى على الكود التنفيذى و الذى كان سيكتب داخل الفئه الـ template و بالطبع كل دوال الفئه الجديده ستأخذ معاملات من نوع void* و ستعود بنفس النوع و داخل الفئه الـ template سيتم عمل casting لها ، و بالنسبه للكود البسيط الذى سيكتب داخل الملف الـ header لن يتم كتابته و سيتم وضعه فى ملف inl و هو اختصار لـ inline file و سيتم عمل include له فى اخر ملف الـ header.

بالنسبه لنقطة عدم كتابة بادئه لأنواع البيانات هو ان كل انواع البيانات التى ستظهر للمستخدم ستكون abstarct و ايضا موجوده داخل مجال اسماء و الملف الـ header يحتوى على pre-processor بشكا خاص بالمحرك.

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 19 سبتمبر 2009 في 15:22

مدونتي: C++ Tips and Tricks

#6
علاء الصالحي كتب:
الحزمة LWJGL جديده علي

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

تحياتي

هذه مكتبة تمكنك من استخدام مكتبة OpenGL الرسومية في الجافا ..

مثلها مثل المكتبة jogl اذا تعرفها ... سأكتب مقال سريع عنها في قسم OpenGL , اليوم باذن الله .

سنستخدم هذه المكتبة في الجزء الرسومي من المشروع , يعني لن نستخدم java2d .

سأقوم ان شاء الله بعمل هذا الجزء اذا لم يتطوع أحد .. حيث سأعمل interface تغنيك عن التعامل مع OpenGL , وهذا هدف المحرك , عزل المستخدم النهائي عن أي مكتبة .

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

الاخ محمد علاء , شكرا لك على الرد المفيد .. سأرد بالتفصيل لاحقا بحول الله .

تم تعديل هذه المشاركة بواسطة الشمري في 19 سبتمبر 2009 في 15:06

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#7

سأتكلم عن نظام الملاحظات داخل الـ C# بشكل سريع:

كل الأوسمه التالى ذكرها يتم كتابتها بحروف صغيره

1 - كل انواع البيانات و الدوال تشترك فى وسم summary و الذى يأخذ الشكل التالى

 

[color= #007f00;]/// <summary>

[color= #007f00;]/// my commant here

[color= #007f00;]/// </summary>

هذا الوسم يتم كتابة به ملخص سريع عن ماهية صاحبه. مثال

 

[color= #007f00;]/// <summary>

[color= #007f00;]/// represent a abtract device to draw in

[color= #007f00;]/// </summary>

[color= #0000ff;]struct Device

[color= #000000;]{

[color= #007f00;]/// <summary>

[color= #007f00;]/// daw data to device

[color= #007f00;]/// </summary>

[color= #0000ff;]void draw[color= #000000;]([color= #000000;]) pure;

[color= #000000;]};

 

[color= #007f00;]/// <summary>

[color= #007f00;]/// represent a 2d device to draw in

[color= #007f00;]/// </summary>

[color= #0000ff;]struct Device2D [color= #000000;]: Device

[color= #000000;]{

[color= #000000;]};

2 - الوسم remark و يستخدم لكتابة معلومات اضافيه و يستخدم مع كل انواع البيانات و الدوال و دائما ما يكتب اخر وسم بمعنى فى حالة وجود اوسمه يكتب بعدهم جميعا

 

[color= #007f00;]/// <remark>

[color= #007f00;]/// my remark here

[color= #007f00;]/// </remark>

مثال:

 

[color= #007f00;]/// <remark>

[color= #007f00;]/// note that this interface depends on interface Device don't alter it

[color= #007f00;]/// </remark>

[color= #0000ff;]struct Device2D

[color= #000000;]{

[color= #000000;]};

3 - الوسم param يستخدم مع معاملات الدوال و يأخذ معامل واحد فقط و هو اسم المعامل

 

[color= #007f00;]/// <param name="parameter-name">

[color= #007f00;]/// small description here

[color= #007f00;]/// </param>

مثال:

 

[color= #007f00;]/// <param name="msg">

[color= #007f00;]/// a message to show

[color= #007f00;]/// </param>

[color= #0000ff;]void ShowMessage[color= #000000;](std[color= #000000;]::[color= #808000;]string* msg[color= #000000;]);

4 - الوسم الأخير هو returns و كما هو واضح من اسمه يستخدم مع الداول التى تعود بقيمه

 

[color= #007f00;]/// <return>

[color= #007f00;]/// small description here

[color= #007f00;]/// </return>

مثال:

 

[color= #007f00;]/// <return>

[color= #007f00;]/// return the maximum number

[color= #007f00;]/// </return>

[color= #0000ff;]int Max [color= #000000;]( [color= #0000ff;]int n1, [color= #0000ff;]int n2[color= #000000;]);

قبل التطرق لمثال شامل احب ان انوه ان كل الأوسمه السابقه يمكن كتابتها على اكثر من سطر كما رأيت بالعلى او على سطر و احد كالتالى:

 

[color= #007f00;]/// <summary>your summary here</summary>

 

[color= #007f00;]///<summary>

[color= #007f00;]///your

[color= #007f00;]///summary

[color= #007f00;]///here

[color= #007f00;]///</summary>

 

[color= #007f00;]///<remark>your remark here</remark>

 

[color= #007f00;]///<remark>

[color= #007f00;]///your

[color= #007f00;]///remark

[color= #007f00;]///here

[color= #007f00;]///</remark>

 

[color= #007f00;]///<param name="parameter-name">small description here</param>

 

[color= #007f00;]///<param name="parameter-name">

[color= #007f00;]///small

[color= #007f00;]///description

[color= #007f00;]///here

[color= #007f00;]/// </param>

 

[color= #007f00;]///<return>small description here</return>

 

[color= #007f00;]///<return>

[color= #007f00;]///small

[color= #007f00;]///description

[color= #007f00;]///here

[color= #007f00;]///</return>

نأخذ الأن مثال شامل

 

[color= #007f00;]/// <summary>get natural logrithm of a number</summary>

[color= #007f00;]/// <param name="num">

[color= #007f00;]/// number to get its logrithm

[color= #007f00;]/// </param>

[color= #007f00;]/// <returns>valid logrithm number</returns>

[color= #007f00;]/// <remark>

[color= #007f00;]/// input number must be zero or positive 

[color= #007f00;]/// number or an error will occure

[color= #007f00;]/// </remark>

[color= #0000ff;]double ln [color= #000000;]( [color= #0000ff;]double num [color= #000000;]);

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

#8

كلام جميل أخي محمد علاء

ولكن بالنسبه إلى نقطة كتابت البادئة

اقتباس
# البادئة X أو اي بادئة أخرى تقترحونها تكون في بداية جميع الكلاسات التي ستظهر للمستخدم النهائي .. وذلك حتى يسهل معرفة الكلاس الذي ينتمي لمحركنا بمجرد النظر .. هذا مجرد اقتراح .

أعتقد أن أخي عبدالله يقصد تسهيل تصنيف الكود

مثلا إذا أستخدم مكتبه إضافيه داخل نفس المشروع (اللعبه) المستخدم فيه المحرك , البادئة هنا ستمكننا من معرفت الأسطر اللتي تستخدم المحرك بدون قرائة كام السطر البرمجي

هذا ما فهمته والله أعلم

#9
اقتباس
أعتقد أن أخي عبدالله يقصد تسهيل تصنيف الكود

مثلا إذا أستخدم مكتبه إضافيه داخل نفس المشروع (اللعبه) المستخدم فيه المحرك , البادئة هنا ستمكننا من معرفت الأسطر اللتي تستخدم المحرك بدون قرائة كام السطر البرمجي

السؤال الذى يطرح نفسه فى هذه النقطه ما الهدف من معرفتك ان هذه الفئه تنتمى لمحرك الأندلس او لا تنتمى له ؟

عندما اقول انه لا داعى من البادئه فإن هدفى هو تسهيل الكود إنظر هذا المثال

 

Device2D device [color= #000000;]= Manager.[color= #808000;]CreateDevice[color= #000000;]([color= #000000;]);

Device2DParameters params [color= #000000;]= device.[color= #808000;]GetDeviceParameters[color= #000000;]([color= #000000;]);

و انظر لهذا الكود

 

XDevice2D device [color= #000000;]= XManager.[color= #808000;]CreateDevice[color= #000000;]([color= #000000;]);

XDevice2DParameters params [color= #000000;]= device.[color= #808000;]GetDeviceParameters[color= #000000;]([color= #000000;]);

سأسلكم سؤال و سأترك الإجابه عليكم:

اى كود اسهل فى القرائه و التنقيح الأول ام الثانى؟؟

و الله ولى التوفيق

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 20 سبتمبر 2009 في 11:58

مدونتي: C++ Tips and Tricks

#10

خلاص نشيل البادئة .. أنا أصلا غير مقتنع بها :D .. لو كانت حرف اخر غير X ممكن .. لكن كان تفكيري في ماقال الاخ عبدالله hunter , لمنع أي التباس داخل المحرك , مثلا .. في الكلاس Image .. ستجده في كل مكتبة وفي كل مكان .

لكن تجاوزنا هذه النقطة .. لن نضع بادئة .

أخ محمد , هل نستخدم برنامج doxygen لانشاء ملف المساعدة ؟

بقية النقاط سأعلق عليها الليلة ان شاء الله ..

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#11

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

يسعدني المشاركة في النقاش الأولي. :)

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

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

الأدوات:

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

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

خطة العمل:

حسناً، لقد تم تقسيم المشروع إلى أجزاء ومراحل، ما رأيكم في تعيين قائد أو مبرمج رئيس لكل مشروع فرعي؟ مثلاً قائد لمشروع Java وهو المسؤول عن سير المشروع وتوزيع المهام واتخاذ القرارات بخصوص Java إضافة بالطبع للبرمجة الفعلية. كذلك الأمر بالنسبة لـ ++C و #C.

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

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

إعتبروا الأمر مشابه تماماً للإشراف في هذا المنتدى.

بشكل أولي نحتاج مشرفاً على المشروع ككل، والشمري يقوم بهذه المهمة بأكمل وجه الآن (Project Lead).

نحتاج مشرفاً على التصميم وشخص ينسق بين اللغات والتقنيات ويتابع المشروع باستمرار، ممكن أن يقوم بهذا المشرف على المشروع أيضاً (هذا عمل القائد التقني Lead Technical).

لكل لغة برمجة قائد يقوم بمهام البرمجة الرئيسية ويستطيع تعيين المهام للمبرمجين المتطوعين والإشراف على سير العملية والمساعدة بخبراته. (Lead Developer)

عدد من المطوّرين أتمنى أن أكون انا أحدهم إن سمح لي الوقت، يمثل هؤلاء القوة العاملة الرئيسية للمشروع.

ما رأيكم بتجربة الموضوع؟

التطوير:

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

لذلك أفضّل التصميم المرن الذي يترك فرصة للتغيّر مستقبلاً.

بالطبع كل ما ذكرته هنا هو إقتراحات وآراء مطروحة للنقاش ولا تعتبروها أكثر من ذلك رجاءاً.

#12

يا أخوان , سنستمر في النقاش ان شاء الله حتى ننتهي من استيعاب جميع النقاط والاتفاق عليها .. قد نبدأ بعد 3 أيام تقريبا , الان بدأ العيد , لذلك ليس من المناسب البدء في التطوير ..

-------------------------------------------

مرحبا سلوان :) ,

سأرد على مسألة قائد المشروع , والرد التالي سيكون عن الجوانب الأخرى ,

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

لذلك أفضّل أن نترك الأمور تظهر على شكل تعاون وتفاهم .. دون أن يتعطّل المشروع .

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

لا أدري اذا كنت فهمت بشكل سليم ,

لكن في الغالب , أننا سنتبع أسلوب معروف وشبه مجمع عليه في مجال تطوير المحركات .. مثل : كيف يتم دعم أكثر من OS , كيف يتم دعم أكثر من APIs , مفهوم Scene Graph , الخ .. كلها مشاكل معروفة ومحلولة مسبقاً , نتبعها ( ان لم نجد أفضل ) .. في المرحلة التالية من المشروع 0.2 , قد يتغير أسلوب التطوير .. ولكن لنصل الى تلك المرحلة وبعدها نفكر :) ..

هل فهمتك بشكل سليم ؟!

بقية النقاط التقنية في الرد التالي .

تم تعديل هذه المشاركة بواسطة الشمري في 19 سبتمبر 2009 في 22:26

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#13

اقتراحات الأخ محمد :

  • موضوع البادئة X في أسماء الكلاسات نلغيه
  • نظام التعليقات المقترح من الأخ محمد علاء نعتمده في لغة السي بلس اذا كان يمكن تحويله الى ملفات help باستخدام برامج أخرى
  • نظام لينكس نقوم بتعليقه اذا لم يتطوّع أحد بتطوير نسخة من المحرك عليه
  • كما قال الاخ محمد , نعتمد أسلوب الواجهات في المحرك , أي أن المحرك سيتكوّن من طبقتين , الطبقة العلوية تمثل واجهة المحرك والطبقة السفلية implementation للمحرك , سنعزل المستخدم النهائي تماما عن الطبقة الثانية , ولن يصل إليها الا عن طريق طرف اخر مثل كلاس باسم Factory أو Manager مثال :
    Device *device = Manager.createDevice(DT_WIN32_OPENGL);
    ImageReader imgReader = Manager.createImageReader();
    Graphics *gfx = device->createGraphics();
    Texture *texture = gfx->createTexture();
    Log log = Manager.getLog();


    الفوائد :
    - المستخدم النهائي سيتعامل فقط مع المحرك .
    - ثبات المحرك في المستقبل , حيث التغييرات ستكون في لب المحرك وليس واجهته .
    - اتاحة الفرصة لأي مبرمج بدعم ميزات اضافية plugin للمحرك , مثلا , يمكن أن يصنع ImageReader خاص به عوضاً عن الموجود في المحرك.

  • Aliasing نعتمده في لغة السي بلس ولكن لا أظن أنه من الافضل أن نعيد تسمية حتى المؤشرات .. نكتفي بالمتغيرات أفضل .. وذلك لأن كتابة :
    int16 *pointer
    أسهل من
    int16ptr pointer
    وأكثر وضوحاً , لا أرى داعي لاختصار حتى المؤشرات .
    أيضا , نستخدم NULL أفضل من nulldata الا اذا كان هناك سبب ما ؟
  • لذلك القائمة النهائية تكون بهذه الصورة , ما رأيكم ؟
    #ifndef DATA_TYPES_H
    #define DATA_TYPES_H
    
    // signed 8-bit integer
    typedef signed char int8;
    // unsigned 8-bit integer
    typedef unsigned char uint8;
    
    // signed 16-bit integer
    typedef signed short int16;
    // unsigned 16-bit integer
    typedef unsigned short uint16;
    
    // signed 32-bit integer
    typedef signed int int32;
    // unsigned 32-bit integer
    typedef unsigned int uint32;
    
    // signed 64-bit integer
    typedef signed long long int64;
    // unsigned 64-bit integer
    typedef unsigned long long uint64;
    
    // unicode character
    typedef wchar_t uchar;
    // ascii character
    typedef uint8 achar;
    
    // null pointer
    #define NULL 0
    
    // interface defination
    #define interface struct
    
    // pure virtual function defination
    #define pure = 0
    
    #endif // DATA_TYPES_H


  • أو أن تكون بهذه الصورة .. أيها تفضلون ؟
    #ifndef DATA_TYPES_H
    #define DATA_TYPES_H
    
    // signed 8-bit integer
    typedef signed char s8;
    // unsigned 8-bit integer
    typedef unsigned char u8;
    
    // signed 16-bit integer
    typedef signed short s16;
    // unsigned 16-bit integer
    typedef unsigned short u16;
    
    // signed 32-bit integer
    typedef signed int s32;
    // unsigned 32-bit integer
    typedef unsigned int u32;
    
    // signed 64-bit integer
    typedef signed long long s64;
    // unsigned 64-bit integer
    typedef unsigned long long u64;
    
    // unicode character
    typedef wchar_t uchar;
    // ascii character
    typedef uint8 achar;
    
    // null pointer
    #define NULL 0
    
    // interface defination
    #define interface struct
    
    // pure virtual function defination
    #define pure = 0
    
    #endif // DATA_TYPES_H


    شخصيا .. أميل مع الطريقة الثانية.. اذا كان هناك من يوافق .. والا نعتمد الاولى .. ليست مشكلة ..

  • بالنسبة لطريقة كتابة الكود .. أوافق في كل شيء الا مسألة كتابة الدوال .. فأفضل أن تبدأ بحرف صغير والكلمة التالية حرف كبير
    testFunction()
    هذا مستخدم في كثير من المشاريع والمحركات مثل
    ogre - irrlicht - java ... etc
    مارأي الأعضاء؟
  • اخر نقطة :
    اقتباس
    11 - الفئات الـ templates (حيث انها فئات لن تكون مرئيه للمستخدم كما ذكرنا) لابد من وجود الكود الخاص بها داخل ملف header و لكننا لا نكتب اكواد داخل ملفات الـ header و الحل يتكون من قسمين اولهم قم بعمل فئه تأخذ نفس اسم الفئه الـ template و لكنها تحتوى على الكود التنفيذى و الذى كان سيكتب داخل الفئه الـ template و بالطبع كل دوال الفئه الجديده ستأخذ معاملات من نوع void* و ستعود بنفس النوع و داخل الفئه الـ template سيتم عمل casting لها ، و بالنسبه للكود البسيط الذى سيكتب داخل الملف الـ header لن يتم كتابته و سيتم وضعه فى ملف inl و هو اختصار لـ inline file و سيتم عمل include له فى اخر ملف الـ header.
    لم أفهم ما تقصد .. هل يمكن التفصيل أكثر أخي .
  • أما مسألة مشاركة الملفات , لا أعرف عنها شيء اطلاقا .. لذلك ليتطوّع أحد الأخوة .. ويختار الطريقة الأفضل :
    طريقة الاخ محمد
    اقتباس
    3 - سنحتاج لإستخدام source safe او team foundation حتى اذا اردنا الحصول على كود معين بمرحله معينه تكون متاحه. حيث ان المشروع سيكون مفتوح المصدر لماذا لا نستخدم codeplex حيث انه يوفر اكثر من code source safe و لكنه يعطيك مدة شهر لإنهاء برنامجك.
    طريقة الاخ سلوان
    اقتباس
    النقطة الوحيدة التي لم يتكلم عنها هو نظام مشاركة الملفات، أقترح إستخدام SVN مع برنامج Tortoise (مجاناً بالكامل)، واستناداً إلى ذلك أود أن أقترح تسجيل مستضيف للمشروع وملفاته كخطوة عملية أولى، وأقترح بالطبع Sourceforge أو ما شابه.

مسألة مشاركة الملفات مهمة .. أتمنى حسمها ممن يملك الخبرة فيها ... لدينا وقت حاليا .. حوالي ثلاثة أيام (حتى انتهاء العيد ) , ان شاء الله .

تم تعديل هذه المشاركة بواسطة الشمري في 19 سبتمبر 2009 في 23:39

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#14

أخ علاء , وبقية الاخوة المهتمين , لتثبيت المكتبة LWJGL :

/index.php?showtopic=165722

يمكن فقط تنفيذ أول تطبيق ... لايجب فهم OpenGL .. كما سبق وأن شرحت السبب .

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#15

سأعطي رأيي بشكل سريع

بالنسبة لل Aliasing

أرى الطريقة الأولى التي كتبتها مألوفة أكثر من الطريقة التانيه بالرغم من سهولة الثانية.

بالنسبة للبادئة، الملاحظ أن غالبية المشاريع من محركات أو مكتبات أيضا تستعملها، و هي مفيدة في تمييز مكتبات المحرك عن غيره من المكتبات ...

نظام التعليقات المقترح جيد جدا (مع التأكيد على وجود برامج تحول هذه التعليقات إلى ملفات مساعدة)

بالنسبة لل

اقتباس
كما قال الاخ محمد , نعتمد أسلوب الواجهات في المحرك , أي أن المحرك سيتكوّن من طبقتين , الطبقة العلوية تمثل واجهة المحرك والطبقة السفلية implementation للمحرك , سنعزل المستخدم النهائي تماما عن الطبقة الثانية , ولن يصل إليها الا عن طريق طرف اخر مثل كلاس باسم Factory أو Manager مثال :

لا فكرة لدي عن الموضوع أصلا..

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

طريقة كتابة الكود أتفق مع الأخ الشمري فيها..

لو يستطيع أحد الأخوة رسم شكل يوضع علاقة المحرك مع مكتبة الرسوميات و مع لغة البرمجة و ما يتعلق بهما...

#16
اقتباس
لا فكرة لدي عن الموضوع أصلا..

ببساطة , نجعل كل شيء ( ليس كل شيء .. أشياء محددة ) عبارة عن interface , وليس class , المستخدم النهائي سيعمل Import للباكيج namespace التي تحوي هذه interfaces .. هذه أحد مفاهيم OOP الأساسية ( الكبسلة encapsulation و تعدد الواجهات polymorphism ) .

في XNA ستبدو الأمور هكذا :

- Window

----- XnaWindow // كلاس سينشئ نافذة عادية ويربطها في اكس ان اي

-Graphics

-----XnaGraphics // كلاس سيغلّف المهام الشائعة في اكس ان اي مثل رسم صورة وتطبيق الشفافية .. الخ

-Image

-----XnaImage//

سنعتمد على اكس ان اي في تحميل الصور

من المثال السابق .. أنت كمستخدم نهائي ستكتب شيء شبيه بالتالي في xna

Window win = Manager.CreateWindow(800,600,32,false,Manager.XNA_MODE); // CreateWindow will return XnaWindow
Graphics gfx = win.CreateGfx();// CreateGfx will return XnaGraphics 
Image	  img = Manager.CreateImage("img.bmp");// CreateImage will return XnaImage

while(win.run())
{
	   gfx.begin();
	   gfx.draw(img,x,y);
	   gfx.end();
}

لاحظ .. المستخدم النهائي لم يستدعي أي كائن يتعلّق بالـXNA بشكل مباشر , فقط أخبر المحرك أنه يريد استخدام XNA كمكتبة رسومية .

لنفرض أن ميكروسوفت أعلنت فشل XNA , وأنها كانت فكرة سيئة , وأنها ستعود الى Managed Directx وتلغي XNA , في هذه الحالة , لاتوجد مشكلة عند خلدون خالد , لأنه لن يغير سطر واحد في البرنامج النهائي , حيث سيعيد كتابة المحرك الداخلي وتبقى الواجهة دون تغيير , هكذا :

- Window

----- D3dWindow // كلاس سينشئ نافذة عادية ويربطها في دي ثري دي

-Graphics

-----D3dGraphics // كلاس سيغلّف المهام الشائعة في دي ثري دي مثل رسم صورة وتطبيق الشفافية .. الخ

-Image

-----D3dImage// سنعتمد على دي ثري دي في تحميل الصور

من المثال السابق .. أنت كمستخدم نهائي ستكتب شيء شبيه بالتالي في D3d

Window win = Manager.CreateWindow(800,600,32,false,Manager.D3D_MODE); // CreateWindow will return D3dWindow
Graphics gfx = win.CreateGfx();// CreateGfx will return D3dGraphics 
Image	  img = Manager.CreateImage("img.bmp");// CreateImage will return D3dImage

while(win.run())
{
	   gfx.begin();
	   gfx.draw(img,x,y);
	   gfx.end();
}

واضح ؟

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

هذه أحد وظائف المحرك .. هناك أمور أخرى أكثر امتاع مثل Scene Graph - نظام لاكتشاف التصادم - Resource Management - Particles System - Font Rendering - Physics - AI .....

لذلك , المرحلة الأولى ستكون مملة .. ولكن ضرورية للانتقال الى المرحلة التالية :)

تم تعديل هذه المشاركة بواسطة الشمري في 20 سبتمبر 2009 في 09:35

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#17

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

مدونتي: C++ Tips and Tricks

#18

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

بعد قرائتى للردود توجد بعض النقاط التى رأيت انها تحتاج للتوضيح و هم

1 - موضوع الملاحظات و الأداوت الخاصه بتحويلها لملفات مساعده

يوجد برنامج اسمه SandCastle و هو يقوم بتحويل ملفات الملاحظات الخاصه بالـ C# إلى ملفات مساعده و يمكنك زيارة هذا الرابط لمزيد من المعلومات.

إذا قرأت النقطه السابقه بعنايه (و كلامى موجه لمن سيعمل داخل مشروع الـ C++ و ليس الـ C#) ستجد انى قلت ملفات الملاحظات و السبب فى ذلك انه على خلاف الـ C++ فإن كومبيلر الـ C# يقوم بفصل ملفات المساعده خارج المشروع و يقوم بوضعها داخل ملفات XML و بنظام معين يتيح حتى يتسنى تحويلها لأى ملف مساعده فيما بعد و هذا غير متوفر لنا (مبرمجى الـ C++) و بالتالى سنحتاج لفصل الملاحظات خارجا.

و لكن لا تحزن فقد قام احد المبرمجين بعمل Add-ins للفيجوال ستديو لإضافة نظام الملاحظات للـ Managed C++ و لكنى لم اجربه حتى الأن يمكنك الدخول على هذا الرابط بموقع CodeProject لقراءة الموضوع.

بعد البحث وجدت بعض الأدوات و هى

Doc-O-Matic : و موقعها هو http://www.doc-o-matic.com/index.html

Doxygen : و موقعه هو http://www.stack.nl/~dimitri/doxygen/

2 - عمل Aliasing لأسماء انواع البيانات و كذلك المؤشرات

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

بالنسبه لأسماء انواع البيانات فالإسم s16 او u16 هو مبهم بالنسبه إلى int16 او uint16 فكما ترى ان اسم نوع البيانات بحد ذاته يدل على ماهيته.

بالنسبه لموضوع عمل alias للمؤشرات فهى للتسهيل فى الكتابه ايضا للتسهيل فى البحث عنها إذا اردت يوما ما ان اغيرها بكائن خاص بالـ GC (إذا صنعته).

3 - استخدام NULL بدلا من nulldata

الهدف من استخدام nulldata بهذا الإسم هو ان ويندوز يستخدم اللفظ NULL و بالقيمه 0 كما نستخدمها نحن و هذا سيجعل كومبيلر ميكروسوفت يظهر ان الإسم موجود من قبل و لكن إذا حدث و قمنا بتطوير المشروع ليتعامل مع c++0x فسنجد انه يوجد المؤشر الخالى nullptr و هنا إذا قمنا بتغيير الصفر إلى nullptr فستحدث مشكلة التعارض حيث ان ميروسوفت تستخدم صفر لـ NULL و نحن نستخدم nullptr لـ NULL لذا كما ترى سيضطرنا هذا الإمر لإعادة تنقيح الكود من جديد و لهذا فقد اخترت اللفظ nulldata حيث انه غير مستخدم بأى مترجم ايضا يمكننى تغيير قيمته باى قيمه اشاء.

4 - الـ Interfaces كواجهه للمحرك

لا يوجد اى اعتراض على اى ما قلتموه و لكن توجد نقطه واحده اذكركم بها و هى ان الـ Interfaces لأابد من ان تبدأ بحرف الـ I حتى لا تسبب تعارض مع الـ implementation وايضا حتى نعرف ان الكائن الذى نتعامل معه هو interface و ليس object من class.

5 - جزئية الـ templates

داخل المحرك الخاص بى قمت بصناعة الفئه Array<T> لتعمل كبديل للمصفوفات الإفتراضيه باللغه و لكن المشكله التى واجهتنى ان الـ template تحتاج لأن يكون الكود بأكمله داخل ملف الـ header و هذا امر لا افضله حيث انى لا احبذ اعطاء مستخدم المحرك كود يعتبر من الأسس التى يعتمد عليها المحرك و ذلك فقد قمت بصناعة الفئه ArrayNative و هى فئه عاديه جدا و لكنها تحتوى على الكود الفعلى الذى كان سيتم كتابته داخل الفئه Array.

الفئه ArrayNative شكلها يشبه هذا

 

[color= #007f00;]#ifndef NATIVE_ARRAY_H

[color= #007f00;]#define NATIVE_ARRAY_H

 

[color= #0000ff;]enum SortDirection [color= #000000;]{ Asc, Desc [color= #000000;]};

 

[color= #0000ff;]class NativeArray

[color= #000000;]{

[color= #0000ff;]public[color= #000000;]:

    [color= #0000ff;]static [color= #0000ff;]void Copy[color= #000000;](blob pSource, blob pDest, uint32 iElementSize, 

                     uint32 iSourceFrom, uint32 iSourceTo, uint32 iDestFrom[color= #000000;]);

 

    [color= #0000ff;]inline

    [color= #0000ff;]static [color= #0000ff;]void Copy[color= #000000;](blob pSource, blob pDest, uint32 iElementSize,

                     uint32 iSourceFrom, uint32 iSourceTo[color= #000000;])

	[color= #000000;]{ Copy[color= #000000;](pSource, pDest, iElementSize, iSourceFrom, iSourceTo, [color= #ff0000;]0[color= #000000;]); [color= #000000;]}

 

    [color= #0000ff;]static [color= #0000ff;]bool Exists_Hash[color= #000000;](blob pArray, uint32 iArraySize,

                            blob pElement, uint32 iElementSize[color= #000000;]);

 

    [color= #0000ff;]static [color= #0000ff;]bool Exists_Byte[color= #000000;](blob pArray, uint32 iArraySize,

                            blob pElement, uint32 iElementSize[color= #000000;]);

 

    [color= #0000ff;]static [color= #0000ff;]void Sort[color= #000000;](blob pArray, uint32 iArraySize,

                     uint32 iFrom, uint32 iTo, SortDirection eSort[color= #000000;]);

 

    [color= #0000ff;]static [color= #0000ff;]void Reverse[color= #000000;](blob pArray, uint32 iArraySize, uint32 iElementSize[color= #000000;]);

 

    [color= #0000ff;]static [color= #0000ff;]void Resize[color= #000000;](blob pArray, uint32 iArraySize, uint32 iNewSize, [color= #0000ff;]bool KeepData[color= #000000;]);

 

    [color= #0000ff;]static [color= #0000ff;]void ShrinkRemoveFront [color= #000000;](blob pArray, uint32 iArraySize, uint32 iCount[color= #000000;]);

 

    [color= #0000ff;]static [color= #0000ff;]void ShrinkRemoveLast  [color= #000000;](blob pArray, uint32 iArraySize, uint32 iCount[color= #000000;]);

 

    [color= #0000ff;]static [color= #0000ff;]void ShrinkRemoveMiddle[color= #000000;](blob pArray, uint32 iArraySize, uint32 iCount[color= #000000;]);

 

    [color= #0000ff;]static int64    IndexOf    [color= #000000;](blob pArray, uint32 iArraySize,

                                blob pElement, uint32 iElementSize[color= #000000;]);

 

    [color= #0000ff;]static int64    LastIndexOf[color= #000000;](blob pArray, uint32 iArraySize,

                                blob pElement, uint32 iElementSize[color= #000000;]);

 

    [color= #0000ff;]static int64ptr IndexOfAll [color= #000000;](blob pArray, uint32 iArraySize, blob pElement,

                                uint32 iElementSize, int64ptr NumOfElements[color= #000000;]);

[color= #000000;]};

 

[color= #007f00;]#endif // NATIVE_ARRAY_H

كما ترى دوال هذه الفئه تقبل نوع بيانات وحيد وهو blob اى void* و بعدها عدد العناصر و حجم المصفوفه و ما إلى ذلك الأن و داخل ملف الفئه Array<T> كل ما احتاجه هو استدعاء الداله التى احتاجها و اقوم بتمرير المعاملات اللازمه و فى حالة وجود قيم معاده اقوم بعمل تحويل من void* إلى T.

بالنسبه للكود الذى سيتم كتابته داخل ملف الـ Header فسوف اضعه داخل ملف بإمتداد inl و سأقوم بعمل Include لهذا الملف بعد تعريف الفئه كما يلى

 

[color= #007f00;]#ifndef XCORE_ARRAY_H

[color= #007f00;]#define XCORE_ARRAY_H

 

[color= #0000ff;]template[color= #000000;]<[color= #0000ff;]class T[color= #000000;]>

[color= #0000ff;]class [color= #0000ff;]Array

[color= #000000;]{

[color= #0000ff;]public[color= #000000;]:

  .

  .

  .

  .

[color= #000000;]};

 

  [color= #007f00;]#include "Array.inl"

 

[color= #007f00;]#endif // XCORE_ARRAY_H

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

6 - موضوع مشاركة الملفات

لا أستطيع التكلم فى هذه النقطه حتى نحدد الخادم الذى سيوضع عليه الكود و ذلك حتى نحدد الـ source safe الذى سنتعامل معه.

و الله ولى التوفيق

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 20 سبتمبر 2009 في 11:24

مدونتي: C++ Tips and Tricks

#19

بالنسبة للبادئة اتفقنا على أن نزيلها :) .. سواء I أو X , ونختار أسماء بحيث لاتتعارض ,

لن نحتاج الى I لأن كل الكلاسات التي سنتعامل معها عبارة عن واجهات , باستثناء تلك الموجودة في core مثلا .. لذلك نستطيع بسهولة أن نحصر الكلاسات التي تعتبر ليست واجهة .

عموما .. هذا الموضوع ليس مشكلة .. ممكن يتغير الحال أثناء المشروع .. الأمر سهل ان شاء الله .

ملف التعليمات , استخدم Doxygen فهو المشهور لدى مبرمجي السي بلس , اذا لم تجد أفضل .. لم أجرب شيء .

- سنستخدم Sourceforge .

- بالنسبة لأسماء الدوال لنحسم المسألة .. حرف صغير ثم حرف كبير , أظن الاخ خالد وافقني :D

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

الا اذا كانت هناك أصوات أخرى ,

- أخي محمد , نحن سنستخدم STL في السي بلس , std::vector و std::list و std::string .. مهما فعلنا لن نصنع كود أفضل ولا أوضح منها .. وحتى يبقى تركيزنا على مشروع المحرك ,

بقية النقاط التي ذكرتها نعتمدها اذا لم يوجد رأي اخر .. نتمنى من الاخوة المشاركة لأن الحاصل الان هو صوت مقابل صوت ونحتاج ترجيح .

لنتجاوز الان مايتعلق بالأعراف التي سنسير عليها .. ونناقش مسألة مشاركة الملفات

تم تعديل هذه المشاركة بواسطة الشمري في 20 سبتمبر 2009 في 12:06

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#20

لقد اعطيت مثال الـ Array ليس لنطبقه و لكن كأحتمال وارد حدوثه فقط

اقتباس
لنتجاوز الان مايتعلق بالأعراف التي سنسير عليها .. ونناقش مسألة مشاركة الملفات

كما قلت سنستخدم sourceforge و هو كما اعتقد يتيح استضافة المشاريع، صحح لى إن كنت مخطئا.

مدونتي: C++ Tips and Tricks

#21

هذا موقع جميل لأمشاركة الأكواد

http://www.assembla.com/

أذكر أني إستخدمته لفتره قصيره, أحد الميزات اللتي أعجبتني أنه يضهر النسخه القديمه من الملف و أيضا النسخه المعدله

المبرمجين الذين عملت معاهم كانوا يستخدموه لمشاركة الملفات والتعديل عليها, بينما كانوا يستخدموا موقع لعبتهم(مشروعهم) للمشاركه الأفكار.

ولكن الموقع غير مجاني

#22

كل عام و أنتم بخير...

اقتباس
واضح ؟

نعم :happy:

بالنسبة للتوثيق لا مشكلة إذا.

اقتباس
- بالنسبة لأسماء الدوال لنحسم المسألة .. حرف صغير ثم حرف كبير , أظن الاخ خالد وافقني

فعلا لأني أراها طريقة جيدة و مقروئة بسهولة

هناك بعض الغموض بشكل عام في بعض الأمور بالنسبة لي ولكن أعتقد الموضوع سوف يتضح أكثر عند البدء العملي

#23
الشمري كتب:
أنا لست قائد للمشروع , سأستخدم بعض صلاحياتي كمشرف , مثل غلق موضوع وفتح موضوع اخر ونقل موضوع .. الخ .. للتحكم في سير المشروع .. لأن مسألة قيادة المشروع تحتاج لخبير .. وهي مسألة محرجة لي .. أعرف أنه من المهم وجود قائد .. ولكن أظن أنه في هذا المشروع لايوجد قائد فعلي .. لأن أغلب المشاركين زملاء , ومتفاهمين بدرجة جيدة جدا .. سننظر (كأعضاء ) في الأمر أثناء سير المشروع بحول الله ..

لذلك أفضّل أن نترك الأمور تظهر على شكل تعاون وتفاهم .. دون أن يتعطّل المشروع .

حسناً، كان الأمر مجرد إقتراح لإنشاء والتعوّد على تسلسل مسؤولية محدد.

الشمري كتب:
لا أدري اذا كنت فهمت بشكل سليم ,

لكن في الغالب , أننا سنتبع أسلوب معروف وشبه مجمع عليه في مجال تطوير المحركات .. مثل : كيف يتم دعم أكثر من OS , كيف يتم دعم أكثر من APIs , مفهوم Scene Graph , الخ .. كلها مشاكل معروفة ومحلولة مسبقاً , نتبعها ( ان لم نجد أفضل ) .. في المرحلة التالية من المشروع 0.2 , قد يتغير أسلوب التطوير .. ولكن لنصل الى تلك المرحلة وبعدها نفكر :) ..

هل فهمتك بشكل سليم ؟!

أعتقد إنك فهمتني بشكل صحيح، هذه النقاط التي ذكرتها كلها مشاكل محلولة، ولكن فيما بعد من المحتّم أن نصل إلى أجزاء ليس لها تصميم ثابت معروف، رأيي أن لا نحاول حل تلك المشاكل مقدّماً لأننا إما سنجد إن الواقع في تلك اللحظة يجعل من التصميم الموضوع مسبقاً غير مناسب، أو إننا لن نحتاج لحل تلك المشكلة أساساً، هذه إحدى توصيات البرمجة من نوع Agile المسماة Extreme Programming، وهي بذل الجهد والوقت فقط في الأشياء التي هي أمامنا الآن وليس شيء نتوقع إننا سنحتاجه فيما بعد مع إننا لن نحتاجه الآن (هذه الفكرة لها إسم أيضاً! YAGNI)، الفكرة تنطبق على عملية التصميم والتطبيق بشكل متكافئ في حالتنا هنا.

بالطبع لكل مطوّر مبادئه الخاصة، فانا فقط أقترح إعتماد هذا المبدأ لتلافي ضياع الجهد.

#24
اقتباس
- بالنسبة لأسماء الدوال لنحسم المسألة .. حرف صغير ثم حرف كبير , أظن الاخ خالد وافقني

انا افضل اسلوب التسميه داخل الدوت نت و لكن إذا كان هذا رأى الأغلبيه فلا مشكله

مدونتي: C++ Tips and Tricks

#25

إسمحولي أن أتكلم قليلاً حول SVN.

عندما تنشئ مشروعاً في Sourceforge تحصل معه على خادم ملفات SVN متكامل، تحتاج لكي تتعامل مع الخادم برنامج Client، أكثر برنامج مستخدم لسهولته وعمليته هو TortoiseSVN.

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

TortoiseSVN.gif

العمليات الرئيسية التي يمكن لبرنامج SVN Client القيام بها:

  • Checkout: الخطوة الأولى وهي تحميل المشروع بأحدث نسخ من الملفات من خادم SVN، يكون المشروع في شكل مجلّد إعتيادي على القرص الصلب لديك، تستخدم Checkout لأنشاء المجلّد أول مرة فقط.
  • Update: الحصول على أحدث وآخر نسخة من جميع الملفات، برنامج SVN يعرف أوتوماتيكياً أي من الملفات تغيّر.
  • Commit: عندما تود رفع التغييرات التي قمت بعملها إلى خادم SVN، مثلاً كتابة كود جديد، تستخدم Commit وتحدّد الملفات التي تود تقديمها.
  • Log: يمكنك عرض تاريخ المشروع بالكامل والتغييرات التي حصلت في كل إصدار (كل مرة يجري أي أحد تغييراً يزيد رقم الإصدار بواحد).
  • Branch/Tag: إنشاء نسخة جديدة منفصلة (أو تفرّع) من المشروع، أي تغييرات تجري على التفرّع لا تؤثر على المشروع الأصلي.
  • Merge: تعطي إمكانيات دمج ملفات مختلفة.

وهنالك عدد آخر من العمليات المفيدة، ولكن هذه هي الأساسية منها.

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

قد يبدو الإستخدام معقداً للوهلة الأولى ولكن في حقيقة الأمر فإن إستخدامه سهل جداً، كل شيء يمكن الدخول إليه عن طريق قائمة TortoiseSVN والتي تظهر كجزء من قائمة الزر الأيمن للماوس (Context) تعتمد على الملف أو المجلد الحالي الذي تضغط عليه/فيه الزر الأيمن.

التعارض Conflict:

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

عندما تنتهي من عملية الدمج، تعلم برنامج SVN بذلك عن طريق استخدام Resolved.

عمليات الملفات:

- عندما تود إضافة ملف جديد للخادم، يجب عليك إضافته عن طريق Add من قائمة TortoiseSVN.

- لحذف ملف من الخادم يجب عليك حذفه عن طريق Delete من قائمة TortoiseSVN.

- لتغيير إسم ملف من الخادم نستخدم Rename من قائمة TortoiseSVN.

- لنسخ ملف أو مجلد في الخادم يجب استخدام Relocate من قائمة TortoiseSVN.

- تستطيع أيضاً "قفل" ملف معين تود تغييره بشكل جذري لمنع أي تغييرات قد يجريها مبرمج آخر عليه أثناء عملك ثم فتح القفل عندما تنتهي (Get Lock و Release Lock).

طريقة العمل:

- تبدأ عادة بتحديث ملفات المشروع لآخر إصدار باستخدام Update.

- تعمل على المشروع بشكل إعتيادي جداً.

- عندما تنتهي إن كان هنالك ملفات تود تحديثها في المشروع تقوم بعمل Commit لها، ولكن بالطبع توخى الحذر أن يكون المشروع قابل للترجمة والبناء والعمل بالكامل من دون مشاكل لكي لا يقع المبرمجين الآخرين في مشكلة عند تحديثهم للإصدار الأخير.

ذلك كان عرض سريع لكيفية التعامل مع SVN، لمعلومات أخرى:

SVN on Wikipedia

TortoiseSVN

من بحث سريع لم أجد دروساً عربية، ولكن الكثير من الدروس الإنكليزية بالطبع، هذا أحدها:

Tutorial

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

تم تعديل هذه المشاركة بواسطة SandHawk في 20 سبتمبر 2009 في 17:16

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

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…