دورة درس SDL 2.0: الدرس 4 - التعامل مع الأحداث

SDL2

من المترجم:

هذا استمرار لسلسلة من الترجمات الخاصة ببرنامج Twinklebear التعليمي ، وهو متاح أصلاً هنا . الترجمة مجانية جزئيا وقد تحتوي على تعديلات طفيفة أو إضافات من المترجم. تقع مسؤولية ترجمة الدرسين الأولين على InvalidPointer . يتم ترجمة الصور من المقال الأصلي مع الحفاظ على أقصى قدر من أسلوب المؤلف.

قائمة الدروس:



التعامل مع الحدث


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

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


المؤلف مان المحفوظة

أبسط حلقة رئيسية


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

while (!quit) //   ,  : { //       //  -   } 


قائمة انتظار حدث SDL


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


عندما نسمي SDL_PollEvent ، نحصل على حدث من بداية قائمة الانتظار ، وهو أقدم الأحداث المتبقية. تلقي الأحداث من قائمة الانتظار باستخدام SDL_PollEvent يزيلها من هناك ، لتجنب ذلك ، يمكنك "استكشاف" الحدث باستخدام وظيفة SDL_PeepEvents مع مجموعة إشارة SDL_PEEKEVENT. يمكنك قراءة المزيد حول هذه الوظيفة في الوثائق ، ولن تكون مطلوبة في إطار هذه المقالة (وعلى الأرجح ستفعل ذلك أيضًا) وبالتالي لن يتم النظر فيها.

التعامل مع الحدث


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

 // e -    SDL_Event,       while (SDL_PollEvent(&e)) { //      if (e.type == SDL_QUIT) { quit = true; } //       if (e.type == SDL_KEYDOWN) { quit = true; } //     if (e.type == SDL_MOUSEBUTTONDOWN) { quit = true; } } 


يجب وضع هذه الحلقة داخل الحلقة الرئيسية للتطبيق.
يحدث حدث من النوع SDL_QUIT عندما يغلق المستخدم النافذة ، ويحدث SDL_KEYDOWN عندما يتم ضغط المفتاح على لوحة المفاتيح (ويأتي عدة مرات أثناء احتجازه ، على غرار طريقة تكرار الحروف أثناء الضغط على المفتاح أثناء طباعة النص) ، ويحدث حدث من النوع SDL_MOUSEBUTTONDOWN عندما انقر بالماوس. هذه ليست سوى بعض الأحداث التي يمكن أن يتلقاها التطبيق الخاص بك - وإجمالاً ، يمكن أن تتلقى SDL أكثر من 20 نوعًا من الأحداث ، والتي لا يمكن أن تغطيها هذه المقالة ، بالطبع ، لذلك يجب أن تقرأ عنها في وثائق SDL_Event

الانتهاء من الدورة الرئيسية


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

 //   SDL_Event e; //   bool quit = false; while (!quit) { //   while (SDL_PollEvent(&e)) { if (e.type == SDL_QUIT) { quit = true; } if (e.type == SDL_KEYDOWN) { quit = true; } if (e.type == SDL_MOUSEBUTTONDOWN) { quit = true; } } //   SDL_RenderClear(renderer); renderTexture(image, renderer, x, y); SDL_RenderPresent(renderer); } 


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

إضافة من المترجم: سوف يستهلك البرنامج بالشكل الذي به على الأرجح جميع موارد المعالج المتاحة له ، مع تحميل نواة واحدة بالكامل. سيكون من المنطقي إضافة تأخير صغير (1-5 مللي ثانية) في نهاية الدورة الرئيسية باستخدام SDL_Delay ، بحيث في حالة عدم وجود أحداث يحرر البرنامج المعالج لبرامج أخرى. لا ينطبق هذا على الألعاب الثقيلة ، التي تتطلب بالفعل جميع الموارد المتاحة ، عندما تنفق 100 ثانية في الثانية كل ثانية على الانتظار ترفًا لا يُسمح به.

نهاية الدرس الرابع


لذلك انتهى الدرس التالي. نراكم جميعا في الدرس 5: أخذ عينات من أطلس الملمس

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

Source: https://habr.com/ru/post/ar437308/


All Articles