مرحبا بالجميع! هذا هو الدرس الثالث في SDL 2. المعلومات مأخوذة من 
هذا المصدر. لم يعجبني دروس التعامل مع حدث Lasy Foo ، لذا سأكتب تقريري الخاص ، لكن يمكن العثور على المواد 
هنا وهنا .
ونبدأ ، مرحبا بكم في الدرس
أحداث
اليوم سوف نعلم برنامجنا للرد على الأحداث بمساعدة 
جون .
لذلك دعونا نبدأ. ربط SDL 2 وإنشاء 3 المتغيرات العالمية والثوابت 2.
#include <SDL2/SDL.h> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Surface *scr = NULL; SDL_Surface *john = NULL; 
بعد ذلك ، نكتب 3 وظائف معروفة بالفعل من الدرس الأخير:
التهيئة int init() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { std::cout << "Can't init: " << SDL_GetError() << std::endl; system("pause"); return 1; } win = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { std::cout << "Can't create window: " << SDL_GetError() << std::endl; system("pause"); return 1; } scr = SDL_GetWindowSurface(win); return 0; } 
 حمل int load() { john = SDL_LoadBMP("john.bmp"); if (john == NULL) { std::cout << "Can't load image: " << SDL_GetError() << std::endl; system("pause"); return 1; } return 0; } 
 استقال int quit() { SDL_FreeSurface(john); SDL_DestroyWindow(win); SDL_Quit(); return 0; } 
 إنتباه (!) ، إذا قمت بنسخ الكود من الدرس السابق ، لا تنسَ تغيير 
الابتسامة إلى 
john .
كل ما يجب قوله: لقد قررت عرض الأخطاء في مرحلة التهيئة وتحميل الصور.
لذلك ، دعونا نستمر. فتح 
الرئيسي واستدعاء وظائف 
الأولية وتحميل .
 int main (int argc, char ** args) { if (init() == 1) { return 1; } if (load() == 1) { return 1; } } 
الآن دعونا نرى كيف يعمل أي تطبيق. يحتوي أي برنامج تقوم بتشغيله (Google Chrome و Paint و Minecraft) على حلقة رئيسية تدير عددًا كبيرًا من المرات. هذا ضروري للديناميكية. في السابق ، كتبنا برنامجًا أظهر فقط ابتسامة لمدة ثانيتين ، ولكن لكي يتعلم البرنامج كيفية الاستجابة لإجراءات المستخدم (أو على الأقل عرض الصورة إلى ما لا نهاية) ، فإنه يحتاج إلى حلقة 
While .
سيتم تكرارها باستمرار ويمكننا فعلها بالفعل ما نريد ، على سبيل المثال ، معالجة الأحداث. ولكن قبل أن تبدأ دورة glan ، دعونا نخلق بعض المتغيرات.
  bool run = true; SDL_Event e; SDL_Rect r; int x = 0; int y = 0; rx = x; ry = y; 
سنحلل كل شيء الآن. أولاً ، قم بإنشاء متغير 
تشغيل من النوع 
المنطقي . هذا المتغير مسؤول عن تنفيذ الحلقة: أثناء تشغيل البرنامج ، يكون 
صحيحًا ، إذا كنا نريد إيقاف التنفيذ ، فقم بتعيين هذا المتغير على 
خطأ . بعد ذلك ، قم بإنشاء كائن 
e من الفئة 
SDL_Event . سوف تحتوي خصائص هذا الكائن على بيانات الحدث المستلم ، وسيتم المزيد من التفاصيل. بعد ذلك نقوم بإنشاء كائن 
r من فئة 
SDL_Rect . هذا هو المستطيل المطلوب لرسم الكائن مع بعض الإحداثيات التي نحتاجها. ثم نقوم بإنشاء المتغيرات 
x و 
y من النوع 
int . قم بتعيين قيمهم على الفور إلى الصفر. هذه ستكون إحداثيات شخصيتنا. في البند التالي ، نقوم بتعيين المتغيرات 
rx و 
ry القيمتين 
x و 
y ، على التوالي. 
rx و 
ry هما إحداثيات المستطيل 
r .
حان الوقت لفتح الدورة الرئيسية.
  while (run) { while(SDL_PollEvent(&e) != 0) { if (e.type == SDL_QUIT) { run = false; } if (e.type == SDL_KEYDOWN) { if (e.key.keysym.sym == SDLK_UP) { y -= 1; } if (e.key.keysym.sym == SDLK_DOWN) { y += 1; } if (e.key.keysym.sym == SDLK_RIGHT) { x += 1; } if (e.key.keysym.sym == SDLK_LEFT) { x -= 1; } } } rx = x; ry = y; SDL_FillRect(scr, NULL, SDL_MapRGB(scr -> format, 255, 255, 255)); SDL_BlitSurface(john, NULL, scr, &r); SDL_UpdateWindowSurface(win); } 
دعونا تحليل هذا الرمز. لدينا دورتين. أول واحد هو الرئيسي ، والذي يعمل عن طريق تشغيل متغير ، كما ذكر سابقا. الحلقة الثانية هي المسؤولة عن التعامل مع الأحداث.
تقوم وظيفة 
SDL_PollEvent () بفتح قائمة انتظار الأحداث التي تم تلقيها في تنفيذ واحد للحلقة الرئيسية ، وحذف الحدث الأخير وكتابة البيانات حول هذا الحدث إلى متغيرات الكائن الذي انتقلنا إلى هذه الوظيفة ، لدينا هذه 
e . تقوم هذه الدالة بإرجاع 0 أو 
NULL أو 
false إذا تم حذف جميع الأحداث من قائمة الانتظار ، لذلك نكتب شرط 
الوقت (SDL_PollEvent (& e)! = NULL) .
نحن ننظر إلى أبعد من ذلك: الاختيار الأول لدينا هو النقر فوق الصليب في إطار النافذة. إذا 
نقرنا فوقه ، 
فسيتم تعيين قيمة متغير الكائن 
e القيمة 
SDL_QUIT . إذا حدث هذا ، فسنخصص 
خطأً لمتغير 
التشغيل وتنتهي الحلقة.
بعد ذلك ، كتبت اختبار ضغط لوحة المفاتيح. إذا تم الضغط على الزر ، فإن متغير 
e.type يساوي 
SDL_KEYDOWN . بعد ذلك ، تحقق من القيم الأساسية. المتغير 
e.key.keysym.sym يخزن قيمة الزر. نحن نقارن هذه القيمة مع المطلوب وننفذ إجراءات معينة. سوف نغير إحداثي جون. إذا تم الضغط على السهم لأعلى ، فسوف ينخفض 
y بمقدار 1 ، إذا انخفض ، يزيد ، إلخ. النقطة ، كما أعتقد ، تفهمها.
بعد معالجة الأحداث ، 
أعد تعيين 
rx و 
ry لتحديث إحداثيات Man. بعد ذلك ، نكتب الدالة المألوفة بالفعل 
SDL_FilRect ، لها دور كبير جدًا. إذا لم نكتبها ، لكان جون قد ترك أثرًا قبيحًا عندما يتحرك ، وهكذا ، كل إطار نرسمه خلفية بيضاء ونرسم فوقه. بعد ذلك ، نرسم بطلنا مع وظيفة 
SDL_BlitSurface . سنستخدم هنا المستطيل 
r ، أو بالأحرى متغيراته 
x و 
y ، ليس فقط في أعلى اليسار ، ولكن مع بعض الإحداثيات الضرورية. بعد ذلك ، فقط قم بتحديث النافذة.
بعد الحلقة الرئيسية ، اكتب 
return quit ()؛ لإكمال البرنامج.
هذا كل شيء ، هذا الدرس قد انتهى. هنا هو مثل هذا الرمز:
قانون #include <SDL2/SDL.h> #include <iostream> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Surface *scr = NULL; SDL_Surface *john = NULL; int init() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { std::cout << "Can't init: " << SDL_GetError() << std::endl; system("pause"); return 1; } win = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { std::cout << "Can't create window: " << SDL_GetError() << std::endl; system("pause"); return 1; } scr = SDL_GetWindowSurface(win); return 0; } int load() { john = SDL_LoadBMP("john.bmp"); if (john == NULL) { std::cout << "Can't load image: " << SDL_GetError() << std::endl; system("pause"); return 1; } return 0; } int quit() { SDL_FreeSurface(john); SDL_DestroyWindow(win); SDL_Quit(); return 0; } int main (int argc, char ** args) { if (init() == 1) { return 1; } if (load() == 1) { return 1; } bool run = true; SDL_Event e; SDL_Rect r; int x = 0; int y = 0; rx = x; ry = y; while (run) { while(SDL_PollEvent(&e) != NULL) { if (e.type == SDL_QUIT) { run = false; } if (e.type == SDL_KEYDOWN) { if (e.key.keysym.sym == SDLK_UP) { y -= 1; } if (e.key.keysym.sym == SDLK_DOWN) { y += 1; } if (e.key.keysym.sym == SDLK_RIGHT) { x += 1; } if (e.key.keysym.sym == SDLK_LEFT) { x -= 1; } } } rx = x; ry = y; SDL_FillRect(scr, NULL, SDL_MapRGB(scr -> format, 255, 255, 255)); SDL_BlitSurface(john, NULL, scr, &r); SDL_UpdateWindowSurface(win); } return quit(); } 
 وأقول وداعا لك ، وداعا للجميع!
<< الدرس السابق || الدرس القادم 
>>