المساعد الشخصي الرقمي

مشاهدة النسخة كاملة : [درس] الوراثه في Game Maker



Elkfrawy
14-11-2008, 07:53 PM
بسم الله الرحمن الرحيم


السلام عليكم ورحمة الله وبركاته، كيفكم أعضاء أحلي منتدي ^^ .
سوف أقدم لكم في هذا الدرس -إن اشاء الله- كيفية تطبيق مبدأ الوراثة -Inheritance- في Game Maker ومزايا تطبيقه، كما سأسرد مثالاً بسيطاً مطبق عليه مبدأ الوراثه (Inheritance.gmk) -وسيتم الشرح عليه- ومثالاً آخر لنفس اللعبه ولكن مع عدم إستخدام مبدأ الوراثه (None_Inheritance.gmk) لإظهار الفرق بينهما،والأمثله ضروريه لفهم الدرس -then Download them xD- والمثالين في المرفقات.
مستوي الدرس: للمتوسط و المتقدم .
التوافقيه: تتوافق جميع الدوال والإجراءات الموجوده في هذا الدرس مع Game Maker 6,7 ولا يحتاج أن تكون النسخه كامله ، ولكن يجب أن يكون البرنامج في الوضع المتقدم File>Advanced Mode .

مقدمه:
الوراثه من المبادئ الهامه جداً في البرمجه الكائنيه، وجيم ميكر كبرنامج يعتمد في الأساس علي الكائنات فهو لحسن الحظ يدعم الوراثه فيها بشكل جيد.
- والسؤال هنا يطرح نفسه: كيف ستفيدني الوراثه ؟ الجواب: أنها سوف توفر عليك الكثير والكثير من الجهد والتعب المهدر في تعريف العديد من الكائنات التي تختلف في أمور بسيطه عن كائنات أخري، وسوف تغنيك عن الكثير من عمليات النسخ واللصق للكائنات والإجراءات، كما أنها سوف تساعدك وبقوه في تسهيل تطوير لعبتك أو أثناء عملية تصحيح الأخطاء Debugging .
الخلاصة أنه إن كنت تريد صناعة لعبه قويه أو كبيره فلا غني عن إستخدام الوراثه.
- إذاً ماهي الوراثه؟ الوراثه بشكل مبسط هي: أن يكون هناك كائن أب (Parent) وكائن آخر إبن (Child) وهنا يرث الإبن جميع صفات الأب، وقد يزيد الإبن في صفاته أو تتغير إحدي صفات الأب لديه، كما يمكن أن يكون للإبن أبناء وللأب أجداد ........ .
- مثلاً إذا أردنا أن نصنع لعبة Hit the ball -كما في المثال الذي معنا-، ويكون في اللعبه أكثر من كره وكل كره لها بعض الخصائص المختلفه، إلا أنها جميعاً تشترك في بعض الخصائص والأحداث، فمثلاً عند الإصطدام بالجدار فإنها سوف تقوم جميعها بالإرتداد، وعندما يتم الضغط عليها بزر الفأره فإنها سوف تنتقل إلي مكان عشوائي ..... ، كما أنها تختلف في بعض الأحداث مثل سرعة تحركها والرصيد الذي يضاف عند الضغط عليها وهكذا ........ .

الإستخدام في جيم ميكر:
- لتطبيق الوراثه في جيم ميكر تقوم في البدايه بتعريف الكائن الأب -وهو في مثالنا obj_ball_base- بطريقه عاديه جداً، ثم تقوم بإنشاء الكائن الإبن -obj_ball1- وأثناء إنشاءه تقوم بتحديد الكائن الأب له من خانة Parent -وهو obj_ball_base- ، وهذا كل شئ فالآن أصبح الكائن obj_ball1 إبناً للكائن obj_ball_base .
- وهنا يأتي سؤال مهم: ما الذي يرثه الكائن الإبن من الأب ؟! الإجابه: يرث الكائن الإبن من الأب جميع الأحداث -Events- والإجراءات - Actions- الخاصه بالكائن الأب، ولكنه لا يرث صورة الكائن الأب -Sprite- ولا قناعه -Mask- ولا أي من خصائصه :Visible , Solid , Depth or Persistent ، بمعني آخر هو يرث أفعاله وليست صفاته.
- وبنفس الطريقه نقوم بتعريف كل من obj_ball2 & obj_ball3 كأبناء للكائن obj_ball_base.

- الأن الإهتمام الأكبر لابد ان يكون بالكائن obj_ball_base حيث نري ما الأشياء المشتركه بين كلاً من obj_ball1,obj_ball2 and obj_ball3 ونقوم بوضعها في الكائن obj_ball_base .
الأحداث المشتركه وإضافتها:

1- بالطبع نحن نريد في حدث الإنشاء للكرات أن تتحرك في إتجاه عشوائي، وهذا ما وضعناه في حدث الإنشاء Create للكائن obj_ball_base ووضعنا سرعة التحرك 5 .
الآن سوف ترث جميع الكائنات الإبن هذا الحدث بما فيه من إجراءات Actions، فأنت لست بحاجه إلي إضافة هذا الحدث في الكائنات التي ترغب في أن تتصرف بنفس الكيفيه، وهذا ما حدث مع الكائن obj_ball1 ، فنحن نريده أن يتحرك في إتجاه عشوائي وبسرعه 5 في حدث الإنشاء، ولهذا لم نضيف حدث الإنشاء Create له لأنه سوف يرثه من الأب.
ولكن ماذا لو أردنا أن تتحرك الكرات بسرعه أخري ؟ الحل موجود في كل من الكائنين obj_ball2 & obj_ball3 حيث قمنا بإعادة تعريف حدث الإنشاء وأضفنا إجراء التحرك في إتجاه عشوائي بسرعه 2 و 8 علي التوالي.
ولاحظ أنه عند إعاده تعريف حدث في الكائن الإبن فإنه سوف يتم إلغاء حدث الكائن الأب وسيتم تنفيذ الأجراءات الموجوده في حدث الإبن فقط.
2- وهناك حدث مشترك أيضاً بين جميع الكائنات ألا وهو حدث التصادم مع الجدار، ولذلك نقوم بإضافته في الكائن الأب obj_ball_base، ونقوم بإضافة الإجرائين: الإرتداد وإصدار صوت في هذا الحدث، وبذلك سوف ترث جميع الكرات هذا الحدث بما فيه من إجراءات، ولأننا نريد أن تتفاعل جميع الكرات بنفس الإسلوب في هذا الحدث فلن نقوم بإعادة تعريفه لأي من الكائنات الإبن.
وهنا تتضح لنا أهميه الوراثه في عملية التعديل والتطوير، حيث أن أي تعديل تقوم به في حدث الكائن الأب سوف يرثه جميع أبناءه، فمثلاً في مثالنا إذا أردنا أن نغير صوت التصادم فإننا سوف نغيره في في الكائن الأب فقط -obj_ball_base- مما يسهل علينا عملية التعديل والتنقيح بشكل كبير.

3- هناك أيضاً حدث ضغط رز الفأره الأيسر علي الكرات، وكالعاده نقوم بإضافة هذا الحدث -mouse left button- في الكائن الأب obj_ball_base، ونقوم بإضافة الإجراءات -actions- الخاصه بهذا الحدث وهنا نتوقف قليلاً ونسأل أنفسنا: ما الإجراءات المشتركه للكرات في هذا الحدث ؟
بالطبع نحن نريد أن يتم تشغيل صوت الإصابه وهذا مشترك لجميع الكرات، ولذلك نقوم بإضافة الإجراء Play sound في هذا الحدث لكي يرثه جميع الكائنات، وكذلك بالنسبه للإنتقال إلي مكان عشوائي Jump to a random position .
أما زيادة الرصيد -Score- فإنه سوف تختلف قيمة الزياده علي حسب كل كره، إذاً فنحن لدينا في هذا الحدث بعض الإجراءات -Action- التي تشترك فيها جميع الكرات والبعض الآخر التي تختلف كل كره عن الأخري..... إذاً فما الحل ؟
الحل ببساطه هي أن نقوم بإضافة الإجراءات المشتركه بين الكائنات الأبن في الكائن الأب -obj_ball_base- وعدم إضافة تلك التي تختلف فيها كل كره عن الأخري، ثم نقوم بوراثة الإجراءات المتشابهه للكرات في كل كره علي حده ونضيف إليها الإجراءات المختلفه أيضاً.
وتتم هذه العمليه عن طريق إضافة الحدث -mouse left button- لكل من الكرات obj_ball1,obj_ball2&obj_ball3 ثم نقوم بإضافة الإجراء "وراثة الحدث" الموجود في مجموعة التحكم Control>other>Call event أو الداله event_inherited(); عند إستخدام الأكواد ، ثم نقوم بعد ذلك بإضافة إجراء زيادة الرصيد لكل كره علي حده وهو 1 و 5 و 10 علي التوالي.
ونلاحظ أن فائده الإجراء Call event هي تنفيذ الإجراءات الموجوده في الكائن الأب مع إمكانية الإضافه عليها، بعكس ما فعلناه سابقاً من إضافة الحدث للإبن وإلغاء حدث الأب، والفرق بينهم هام وجوهري.
وهنا تجدر الإشاره إلي ملاحظه هامه وهي ترتيب وراثة حدث الأب وكتابة الإجراءات الأخري في هذا الحدث (مع العلم أنه لن يؤثر في مثالنا هذا) ولتوضيح ذلك نسرد المثال البسيط الآتي: نفترض وجود كائن أب ووضعنا في حدث ما له الكود التالي:

startx=50;
starty=100;
ونريد في نفس الحدث للكائن الإبن الإنتقال إلي هذ المكان، فمن الخطأ كتابة الكود التالي:

x=startx; // Error x undefined
y=starty; // // Error y undefined
event_inherited(); // Useless
أم الصواب فهو:

event_inherited(); // Get data from parent
x=startx; // ok x now 50
y=starty; // ok y now 100
نلاحظ مما سبق أن الداله event_inherited() تقوم بتنفيذ الإجراءات الموجوده في الحدث الأب كلها أولاً ثم تقوم بإكمال الكود.

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

obj_ball_base.x+=10;
فهذا ليس معناه أنك تحرك الكائن الأب فقط (والذي في الغالب لايستخدم ككائن في الغرفه) بل أنك تعطي الأوامر لجميع أبناءه أيضاً -وأحفاده حتي- للتحرك لليمين بمقدار 10 خطوات، وهذه نقطه هامه جداً وتوفر الكثير من الجهد فهي تغنينا مثلاً عن كتابة الكود التالي:

obj_ball1.x+=10;
obj_ball2.x+=10;
obj_ball3.x+=10;
وبذلك فإن تطبيق أي داله أو حدث علي إسم الكائن الأب سوف يؤثر في جميع الكائنات الإبن، ويجب الحظر هنا أيضاً عن الإستخدام.
وأمثله للتوضيح فقط :

obj_ball_base.speed+=5; // speed up all balls
with(obj_ball_base) instance_destroy(); // Destroy all balls
num=instance_number(obj_ball_base); //num now has the number of all balls
if (collision_circle(x,y,sprite_width,obj_ball_base,true,true)) // To check collision with all balls
وهلم جراً ........ .

ونعود إلي مثالنا فنجد تطبيق لهذه النقطه في إضافة حدث التصادم Collision with obj_ball_base ومعني هذا الحدث:إذا تصادم هذا الكائن (أو أبناءه لأنهم سيرثوه) مع نفسه أو مع أي من أبناءه فنفذ الإجراءات التي بداخله، وهي الإرتداد وإصدار صوت التصادم.
وهذا بالطبع يغنيينا عن إضافة ثلاثة أحداث تصادم لكل كائن من الكائنات الأبن كما هو الحال في المثالي الذي لم نطبق فيه الوراثه.

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

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

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

وشكراً.

اسود الرافدين
14-11-2008, 08:14 PM
بالحقيقه خبرا جدا مؤسف والمنتدى راح تكون فيه ثغره بعد غيابك مواضيعك تميزه وانت مميز دائما بالدروس .. يبقى نتمنالك كل التوفيق ان شاء الله تعالى حبيبي باذن الله التخرج والنجاح..

اسود الرافدين
14-11-2008, 08:17 PM
يا سلالالام عليك يا ايمن على الابداع والتمييز في طريقة الشرح مشكور حبي ..:biggthump

XORO
14-11-2008, 08:55 PM
دائما ما تكون دروسك مميزة في محتواها وشرحها

لكن حتى اذا غبت عن المنتدى تبقى دروسك بصمة على وجود عضو خبير في الجيم ميكر

وبالتوفيق في دراستك

Elkfrawy
14-11-2008, 10:22 PM
مشكورين جداً أخي علي و XORO علي تفهمكم لموقفي ، وكلامكم ده شهاده أعتز بيها شخصياً .