مرحبا بالجميع! هذا هو الدرس الرابع في SDL 2. قررت دمج الدرسين في واحد ، حيث أنهما في الأصل صغيران. ولكن يمكن العثور عليها
هنا وهنا . حسنًا ، لنبدأ الدرس.
أولاً ، سنقرر ما سنفعله. اليوم سوف نتعلم كيفية تحميل الصور من ملحق آخر (وليس BMP) ، وهي: PNG. قم بإعادة الصورة بتنسيق مختلف لتسريع العمل وتغيير حجم الصورة. سوف نعمل مع هذه الصورة:
تركيب
لذلك ، أولاً نتعلم كيفية تنزيل PNG. لا تقوم مجموعة ميزات SDL 2 القياسية بتحميل صور بتنسيق غير BMP. لتنزيل تنسيق مختلف ، تحتاج إلى تثبيت الامتداد.
فيما يلي التعليمات:
نوافذتذهب إلى هذه
الصفحة وتنزيل أرشيفات ZIP أو TAR.GZ من قسم
مكتبات التنمية . قم بفكها ورميها في المجلد باستخدام برنامج التحويل البرمجي.
لينكسإذا كان نظامك يستخدم دبيان ، فأنت بحاجة إلى إدخال هذه الأوامر:
apt-cache search libsdl2-image apt-get install libsdl2-image-dev
إذا تم استخدام Yellowdog Updater ، تم التعديل ، فأنت تدخل هذه الأوامر:
yum search SDL2_image-devel yum SDL2_image-devel
نظام التشغيل Mac OSقم بتنزيل ملف DMG وقراءة الملف التمهيدي.
كتابة رمز
بعد إعداد
SDL_image ، نبدأ في كتابة التعليمات البرمجية. أولاً ، كما هو الحال دائمًا ، سنقوم بتوصيل المكتبات ، وتعيين أحجام النوافذ وإنشاء 3 متغيرات عامة.
#include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <iostream> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Surface *scr = NULL; SDL_Surface *flower = NULL;
لاحظ أنني قمت بتوصيل
SDL_image.h بشكل منفصل ، حيث إنها مكتبة منفصلة.
بعد ذلك ، نكتب 3 وظائف ، معروفة لنا ، والتي سنقوم بإضافة شيء وتغييره ، كالمعتاد.
أولي () bool init() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { std::cout << "Can't init video: " << SDL_GetError() << std::endl; return false; } int flags = IMG_INIT_PNG; if ( !( IMG_Init( flags ) & flags ) ) { std::cout << "Can't init image: " << IMG_GetError() << std::endl; return false; } win = SDL_CreateWindow(" PNG", 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; return false; } scr = SDL_GetWindowSurface(win); return true; }
أضفنا هنا تهيئة وحدة SDL_image. لتهيئته ، قم أولاً بإنشاء متغير
int ، ولدينا
إشارات ، وحفظ كل العلامات التي تريد استخدامها للتهيئة.
قائمة بجميع الأعلامSDL_INIT_PNG - تهيئة برنامج تنزيل صور PNG ؛
SDL_INIT_JPG - تهيئة برنامج تنزيل صور JPG ؛
SDL_INIT_TIF - تهيئة برنامج تنزيل الصور TIF ؛
بعد ذلك ، نكتب هذا الشرط:
if ( !( IMG_Init( flags ) & flags ) )
ترجع الدالة
IMG_Init () الإشارات التي تمكنت من التهيئة. إذا أعادت الأعلام ، لكن العلامة التي أردناها كانت مفقودة ، سنرجع خطأً. بسيط جدا لاحظ أيضًا أنني أستخدم
IMG_GetError بدلاً من
SDL_GetError ، نظرًا لأننا نبحث عن خطأ في وظيفة الوحدة النمطية
SDL_image ، وليس
SDL .
أريد أيضًا أن أشير إلى أنني قررت استخدام نوع
منطقي لإرجاع - هذه طريقة أكثر عقلانية.
دعنا نواصل كتابة برنامجنا ، وكتابة وظيفة
Load () ، التي نحمل فيها صورة PNG ونحولها.
حمل bool load() { flower = IMG_Load("flower.png"); if (flower == NULL) { std::cout << "Can't load: " << IMG_GetError() << std::endl; return false; } flower = SDL_ConvertSurface(flower, scr->format, NULL); if (flower == NULL) { std::cout << "Can't convert: " << SDL_GetError() << std::endl; return false; } return true; }
نحن هنا نقوم بتحميل الصورة باستخدام وظيفة
IMG_Load الجديدة. وظيفتها هي نفسها وظيفة
SDL_LoadBMP والنتيجة هي نفسها - تقوم بإرجاع مثيل لفئة
SDL_Surface . للعثور على أخطاء أثناء التحميل ، نستخدم أيضًا
IMG_GetError .
حان الوقت لتحويل. أولاً ، نظرية صغيرة. قلة من الناس يعرفون ، لكن عند تنزيل صورة ، يتم تنزيلها بتنسيق 24 بت ، ومعظم شاشات العرض الحديثة بتنسيق 32 بت. وفي كل مرة نعرض فيها الصورة على الشاشة ، تمت إعادة بنائها لأول مرة بتنسيق 32 بت. بالنسبة للبرامج البسيطة ، لا يهم هذا الأمر ، ولكن عند إنشاء نوع من المشاريع الكبيرة ، سيؤثر ذلك بشكل كبير على الأداء ، لذلك سنتخذها وفي مرحلة تحميل الصور ، سنقوم بإعادة تشكيلها بتنسيق العرض. سوف تساعد وظيفة
SDL_ConvertSurface . يستغرق 3 قيم: السطح الذي نريد تنسيقه ، التنسيق الذي نريد تنسيقه ، والأعلام. نريد تنسيق صورة
الزهرة ، ونمرّرها المعلمة الأولى. المعلمة الثانية هي شكل سطح النافذة ، ونحن لن نستخدم الأعلام. هذه الوظيفة تقوم بإرجاع نسخة من السطح ، والتي نقوم بتعيينها على الفور
للزهرة . للبحث عن الأخطاء ، نأخذ وظيفة
SDL_GetError () ،
لأننا نعمل بالفعل مع الأسطح ، وهم من
SDL ، وليس من
SDL_image .
بعد ذلك نكتب وظيفة Quit ، أضف وظيفة واحدة فقط إليها.
استقال void quit() { SDL_FreeSurface(flower); SDL_FreeSurface(scr); SDL_DestroyWindow(win); SDL_Quit(); IMG_Quit(); }
أضفنا
IMG_Quit لإلغاء تهيئة وحدة SDL_image.
رئيسي
الآن يبقى أبسط شيء - الوظيفة
الرئيسية .
int main (int argc, char ** args) { if (!init()) { system("pause"); quit(); return 1; } if (!load()) { system("pause"); quit(); return 1; }
للبدء ، تهيئة وإنشاء كل ما تحتاجه وتحميل الملفات الضرورية. لن نتوقف هنا.
SDL_Rect bg_flower; bg_flower.w = SCREEN_WIDTH; bg_flower.h = SCREEN_HEIGHT; bg_flower.x = 0; bg_flower.y = 0;
بعد ذلك ، قم بإنشاء كائن للفئة
SDL_Rect . سنحتاجه لتمديد الصورة. إذا لاحظت ، تكون صورة الزهرة أصغر من حجم النافذة بأربعة أضعاف (أرق مرتين وأقل مرتين) ، ونحن بحاجة إلى مدها إلى حجم النافذة. حتى في عرض المستطيل
bg_flower اكتب قيمة عرض النافذة ، وفي الارتفاع - ارتفاع النافذة. اضبط الإحداثيات على 0 ، بحيث يتم عرض الصورة في الزاوية اليسرى العليا.
لعرض الصور مع تغيير حجمها ، هناك وظيفة خاصة. يبدو مثل هذا:
SDL_BlitScaled(flower, NULL, scr, &bg_flower);
يستغرق 4 معاني. الأول هو الصورة التي نريد عرضها ، والثاني هو المستطيل الذي نريد قصه من هذه الصورة (إذا أردنا التقاط الصورة بأكملها ، نكتب NULL) ، والثالث هو السطح الذي نريد أن نعرض عليه الصورة ، والرابع هو نفس المستطيل ، الأبعاد والإحداثيات التي نأخذها لتمديد أو ضغط وعرض الصورة.
بعد ذلك ، فقط قم بتحديث سطح الشاشة ، واضبط التأخير والخروج والعودة 0.
SDL_UpdateWindowSurface(win); SDL_Delay(2000); quit(); return 0; };
هذا هو المكان الذي ينتهي فيه برنامجنا. من أجل ترجمة هذه المعجزة ، تحتاج إلى إضافة -lSDL2_image ، كخيار تجميع آخر.
وعلى هذا سننتهي لهذا اليوم. إليك الكود الذي حصلنا عليه:
#include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <iostream> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Surface *scr = NULL; SDL_Surface *flower = NULL; bool init() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { std::cout << "Can't init video: " << SDL_GetError() << std::endl; return false; } int flags = IMG_INIT_PNG; if ( !( IMG_Init( flags ) & flags ) ) { std::cout << "Can't init image: " << IMG_GetError() << std::endl; return false; } win = SDL_CreateWindow(" PNG", 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; return false; } scr = SDL_GetWindowSurface(win); return true; } bool load() { flower = IMG_Load("flower.png"); if (flower == NULL) { std::cout << "Can't load: " << IMG_GetError() << std::endl; return false; } flower = SDL_ConvertSurface(flower, scr->format, NULL); if (flower == NULL) { std::cout << "Can't convert: " << SDL_GetError() << std::endl; return false; } return true; } void quit() { SDL_FreeSurface(flower); SDL_FreeSurface(scr); SDL_DestroyWindow(win); SDL_Quit(); IMG_Quit(); } int main (int argc, char ** args) { if (!init()) { system("pause"); quit(); return 1; } if (!load()) { system("pause"); quit(); return 1; } SDL_Rect bg_flower; bg_flower.w = SCREEN_WIDTH; bg_flower.h = SCREEN_HEIGHT; bg_flower.x = 0; bg_flower.y = 0; SDL_BlitScaled(flower, NULL, scr, &bg_flower); SDL_UpdateWindowSurface(win); SDL_Delay(2000); quit(); return 0; };
وداعا للجميع!
<< الدرس السابق || الدرس القادم
>>