الشبكة العربية لمطوري الألعاب

محترف مشرف عبد اللطيف حاجي علي مشاركة 21

ممكن جداً
إذ أنك تقوم بإنشاء Vector2 من أجل كل نداء لهذه الخاصيات (تقوم بذلك في أكثر من مكان بشكل عام)
هذا يعني أن 4 كائنات من نوع Vector2 سيتم إنشائها من أجل كل نداء للإجراء الأصل إضرب ذلك بعدد اللقطات في الثانية وبعدد الدبابات وأضف إلى ذلك الزمن الذي يأخذه الـ Garbage Collector وستجد أن هذا قد يشكل فرقاً كبيراً

أقترح أن تبحث عن كل مواضع إنشاء الكائنات في  الإجراءات التي يتم استدعائها في كل إطار وتحاول الاستغناء عنها.

بالنسبة لموضوع AddCollisionUnit، فإنه يستخدم الإجراء Contains لكي يتحقق إذا كان الكائن موجوداً أو لا
لكن فكر ماذا يفعل هذا الإجراء وكيف يتحقق من كون كائنين متساويين أو لا (أريدك أن تفكر بالجواب لأن فكرة المرجع فكرة مهمة في C# وقد يغفل عنها البعض)

عبد اللطيف حاجي علي
مبرمج
In|Framez

محترف  انس مشاركة 22

عدلت المشاركة استاذ ارجو الاطلاع عليها من فضلك

محترف  انس مشاركة 23

بالنسبة لسؤالك :

يقوم باخذ مرجع الكائن(ما يقابله مؤشر على حسب فهمي)، ثم يقوم بالبحث في اللائخة خانة خانة، مع مقارنة كل معلومة من معلومات الكائن أ مع المعلومة المقابلة لها في الكائن ب.

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

محترف  انس مشاركة 24

بعدما حذفت ندائات الانشاء، تحسن الاداء، الى 10-30 اطار في الثانية مع استعمال 12-25 بالمئة من طاقة المعالج

خبير مدير وسام البهنسي مشاركة 25

أطلّ برأسي كالعادة لأطرح تعليقاً سخيفاً:
 
النقطة التي ذكرها عبد اللطيف عن تفادي إنشاء الكائنات مهمة جداً، وأحببتُ أن أنتهز هذه الفرصة لأذكر بأهمية اعتماد هذه الفكرة في عبر السدم! وادي الملوك لا تقوم بإنشاء أية كائنات أثناء اللعب، مما ساعد على أن يكون أداؤها عالياً. والآن نودّ أن تكون عبر السدم بنفس النجاح ☺

وسام البهنسي
مبرمج في إنفيديا وإنفريمز

محترف مشرف عبد اللطيف حاجي علي مشاركة 26

وفي 16 كانون الثاني 2011 01:50 ص، قال انس متحمساً:

يقوم باخذ مرجع الكائن(ما يقابله مؤشر على حسب فهمي)، ثم يقوم بالبحث في اللائخة خانة خانة، مع مقارنة كل معلومة من معلومات الكائن أ مع المعلومة المقابلة لها في الكائن ب.

ليس تماماً. لمقارنة كائنين فإن الإجراء Equals يتم نداءه على كل كائن مع كل كائن آخر. والذي يرجع قيمة إيجابية إذا كان الكائنان متساويين.
الآن أنشئ كائنين بنفس المعلومات وجرب أن تنادي الإجراء Equals على أحد منهما مع تمرير الآخر كمعامل. ستجد أن Equals يعيد false!
أي أن الكائنين ليسا متساويين. السبب هو أن Equals في الحالة الافتراضية تقوم بالتحقق ما إذا كان المرجعان متساويان (أي أن عملية المقارنة تكون بين المراجع وليس بين الكائنات من ناحية المعلومات). بمعنى آخر أنظر الكود التالي (لا أستطيع تجربته لكن أظنه صحيحاً)

class MyClass
{
    public int Number;
    public MyClass(int i)
    {
         Number = i;
    }
}

void Test()
{
      MyClass a = new MyClass(1);
      MyClass b = new MyClass(2);
      MyClass c = new MyClass(1);
      MyClass d = a;

      Console.WriteLine(a.Equals(b));   // Prints false
      Console.WriteLine(a.Equals(c));   // Prints false!
      Console.WriteLine(a.Equals(d));   // Prints true
}

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

عبد اللطيف حاجي علي
مبرمج
In|Framez

محترف  انس مشاركة 27

السلام عليكم.
احببت ان اشير انه تم حل المشكلة و بطريقة مختلفة تماما (ابسط بكثير) ، ساضع الكود هنا ، اذا واجهت احد اعضاء الشبكة نفس المشكلة فاتمنى ان يساعده هذا الكود :
        static public void Update ( ) 
        {

            /*
             * We use maximumXDistance to define the limite betwen the sprite on the X axi
             * the Sprite are sorted on the X axie, by Ascending, this mean that the result of
             * : Sprite[j].X-Sprite[i].X will never be negative
             * 
             * We use maximumYDistance to define the limite betwen the sprite on the Y axi
             * We use maximumYDistanceSquared, because the sprite are not sorted on 
             * the Y axie(because they are alredy sorted on the X axie
             * and the diffirence betwen to sprite Y coordinate, can be negative
             */
            float maximumXDistance;
            float maximumYDistance;
            float maximumYDistanceSquared;

            // Sort all Entity on the X axis
            m_GameEntityList.SortXInsertionAscending( 0, m_GameEntityList.Count );

            // reset all colors outside of the collision loop : just for coloration
            for ( int i = 0 ; i < m_GameEntityList.Count ; i++ )
                {
                m_GameEntityList[ i ].Sprite.Green = 0;
                }

            int j;

            float xDistance;
            float yDistance;


            for ( int i = 0 ; i < m_GameEntityList.Count - 1 ; i++ ) 
            {
                    maximumXDistance = m_GameEntityList[ i ].Sprite.ScaleX * 2;
                    maximumYDistance = m_GameEntityList[ i ].Sprite.ScaleY * 2;
                    maximumYDistanceSquared = maximumYDistance * maximumYDistance;


                for (j = i + 1 ; j < m_GameEntityList.Count ; j++ ) 
                {

                    xDistance = m_GameEntityList[j].Position.X - m_GameEntityList[i].Position.X;
                    if (xDistance < maximumXDistance)
                        {
                            // The two are close enough on the X to perform collision, so check the
                            // distance between the two.
                            yDistance = m_GameEntityList[j].Position.Y - m_GameEntityList[i].Position.Y;

                            if( yDistance*yDistance < maximumYDistanceSquared )
                            {
                                // to see that the collision is On     
                                m_GameEntityList[i].Sprite.Green = 1;
                                m_GameEntityList[j].Sprite.Green = 1;
                            }
                        }
                    else
                        {
                          // the two are too far away, so move on to the next Sprite
                          break;
                        }

                    }
                }

         }

 هذه الطريقة تعتمد على المسافة، نقارن المسافة بين الكائن 1 و الكائن 2، اذا كانت ضمن مجال معين نقوم بحسابات كشف التصادم.اولا نرتب الكائنات في اللائحة حسب قيم X. ثم نقارن المسافات اذا كان الكائنان متقاربان على هذا المحور، نقارنهما على المحور الثاني.
اتمنى ان يفيد هذا الكود شخصا ما يوما ما . سلام

محترف مشرف عبد اللطيف حاجي علي مشاركة 28

وما هي حسابات كشف التصادم؟
حساب ما إذا صندوقان Bounding Boxes يتداخلان؟ أم حسابات معقدة أكثر؟

لا أظن حساب المسافة أسرع من حساب تداخل صندوقين.

عبد اللطيف حاجي علي
مبرمج
In|Framez

محترف  انس مشاركة 29

السلام عليكم.

بتاريخ 02 فبراير 2011 05:23 م، قطب عبد اللطيف حاجي علي حاجبيه بشدة وهو يقول:

وما هي حسابات كشف التصادم؟
 حساب ما إذا صندوقان Bounding Boxes يتداخلان؟ أم حسابات معقدة أكثر؟
هاهي :
                    xDistance = m_GameEntityList[j].Position.X - m_GameEntityList[i].Position.X;
                    if (xDistance < maximumXDistance)
                        {
                            // The two are close enough on the X to perform collision, so check the
                            // distance between the two.
                            yDistance = m_GameEntityList[j].Position.Y - m_GameEntityList[i].Position.Y;

                            if( yDistance*yDistance < maximumYDistanceSquared )
                            {
                                // هناك تصادم   
                            }
                        }

هذه الطريقة تستغني كليا على حسابات التقسيم، و الاضافة الى الخانات. بعد ترتيب الكائنات حسب قيم ال : X نقارن بين فرق القيمة ذاتها للكائن 1 و 2...اذا كانت اقل من عرض الكائن 1 (فرضا اننا نقارن الكائن 1 مع 2) هنا و فقط هنا نقوم بالتحقق من الفرق في قيم الترتيبات(Y).



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