دورة درس SDL 2.0: الدرس 3 - مكتبات تمديد SDL

SDL2

من المترجم:

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

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


مكتبات تمديد SDL


حتى تلك اللحظة ، استخدمنا فقط صور BMP ، لأن هذا هو نوع الصورة الوحيد المدعوم من المكتبة الأساسية SDL 2 ، وهو غير مناسب للغاية. لحسن الحظ ، هناك العديد من مكتبات امتداد SDL التي تضيف ميزات مفيدة ، على سبيل المثال ، يسمح لك SDL_image بتحميل أنواع كثيرة من الصور ، ويضيف SDL_ttf دعمًا لتقديم النص باستخدام خطوط TTF و SDL_net لدعم الشبكة ذات المستوى المنخفض و SDL_mixer لإخراج الصوت متعدد القنوات.

تثبيت التمديد


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

  • Windows (MinGW أو Visual Studio): ضع ملفات الامتداد التي تم تنزيلها من صفحة مشروع الامتداد في مجلد به SDL2. أيضًا ، ستحتاج إلى نسخ SDL2_image و zlib وملفات .dll الأخرى (على سبيل المثال ، libpng) إلى المجلد الذي يحتوي على الملف القابل للتنفيذ (أو في C: \ Windows \ system32 - تقريبًا. لكل. ) بحيث يتم تحميلها عند بدء تشغيل التطبيق.
  • Linux : قم بتثبيت الامتداد باستخدام مدير الحزم الداخلي الخاص بك ، أو قم بالبناء من المصدر. إذا كان لديك Linux - على الأرجح ، فأنت تعلم بالفعل كيفية القيام بذلك ©.
  • Mac : قم بتنزيل .dmg من الموقع الرسمي واتبع الإرشادات الموجودة في الملف التمهيدي.

أيضًا ، لاستخدام الامتداد ، ستحتاج إلى تحديث قائمة ملفات الرأس المستخدمة ومكتبات المكونات الإضافية ، تمامًا مثلما تم ذلك بالنسبة إلى SDL2 نفسها.

قبل أن تبدأ العمل مع الامتداد ، تحتاج إلى توصيل ملف <SDL2 / SDL_image.h> ، أو الملف المطابق لاسم الملحق المطلوب ، بعد ملف رأس SDL نفسه بملفات .c و .cpp التي تستخدمه.

تهيئة SDL_image (اختياري)


عند التحميل الأول للصورة من كل نوع ، يقوم SDL_image تلقائيًا بتهيئة النظام الفرعي اللازم لهذا النوع ، ومع ذلك ، سوف يتسبب ذلك في تأخير بسيط. لتجنب ذلك ، يمكنك تهيئة الأنظمة الفرعية اللازمة مسبقًا باستخدام وظيفة IMG_Init. تقوم IMG_Init بإرجاع قناع بت مع قائمة بجميع الأنظمة الفرعية التي تمت تهيئتها بنجاح في الوقت الحالي ، لذلك للتحقق من نجاح المكالمة ، يجب عليك التحقق من أنه تم تعيين البتات لجميع الأنظمة الفرعية المشار إليها للتهيئة ، على سبيل المثال ، تطبيق قناع على نتيجة bitwise I. ، نحن بحاجة إلى نظام فرعي واحد فقط. PNG. من المهم تنفيذ هذه العملية بعد SDL_Init.

if ((IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG) != IMG_INIT_PNG) { logSDLError(std::cout, "IMG_Init"); SDL_Quit(); return 1; } 


ضبط الأبعاد


في هذا الدرس ، سننظر في كيفية تحميل الصور باستخدام SDL_image ، وكيفية قياس القوام عند التقديم ، وتجانب الخلفية بالبلاط بطريقة أكثر عقلانية من الدرس السابق - دورة تستند إلى أحجام النافذة والبلاط.

لكن أولاً ، دعنا نضبط ثابتًا لحجم التجانب ، أسفل الثوابت لحجم النافذة.

 const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; //     const int TILE_SIZE = 40; 

تحميل الصور باستخدام SDL_image


يتيح لك SDL_image تحميل عدة أنواع من الصور ، وكذلك تحويلها على الفور إلى SDL_Texture مع وظيفة IMG_LoadTexture. تحل هذه الوظيفة محل جميع التعليمات البرمجية الخاصة بوظيفة loadTexture تقريبًا من الدرس السابق ، والآن فقط اتصل بـ IMG_LoadTexture ، وتحقق مما إذا كانت هناك أية أخطاء أثناء التحميل ، ثم الخروج من الوظيفة. نظرًا لأن الدالة IMG_GetError المعرفة في SDL_image ليست أكثر من مرادف لـ SDL_GetError ، فيمكننا استخدام أي منها لعرض رسائل الخطأ.

 /** *       * @param file    * @param ren ,        * @return  ,  nullptr   . */ SDL_Texture* loadTexture(const std::string &file, SDL_Renderer *ren) { SDL_Texture *texture = IMG_LoadTexture(ren, file.c_str()); if (!texture) { std::cout << IMG_GetError(); //    SDL_GetError() } return texture; } 

حدد الطول والعرض للتقديم


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

 /** *  SDL_Texture  SDL_Renderer   x, y,   * @param tex    * @param ren  * @param x  * @param y * @param w     * @param h */ void renderTexture(SDL_Texture *tex, SDL_Renderer *ren, int x, int y, int w, int h) { SDL_Rect dst; dst.x = x; dst.y = y; dst.w = w; dst.h = h; SDL_RenderCopy(ren, tex, NULL, &dst); } /** *  SDL_Texture  SDL_Renderer   x, y,   * @param tex  * @param ren  * @param x  * @param y */ void renderTexture(SDL_Texture *tex, SDL_Renderer *ren, int x, int y) { int w, h; SDL_QueryTexture(tex, NULL, NULL, &w, &h); renderTexture(tex, ren, x, y, w, h); } 

تحميل القوام


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

سوف نستخدم هذه الصور:

بلاط لملء الخلفية:



صورة المقدمة (كما هي مكتوبة عليها ، مع خلفية شفافة ، وكذلك مرة أخرى مع الرموز التي تنتهك قواعد هبر):



تحميل الصور:

 SDL_Texture *background = loadTexture("background.png", renderer); SDL_Texture *image = loadTexture("image.png", renderer); //  if (!background || !image) { //  ,      cleanup(),   PS   ,     ,  ,    . SDL_DestroyTexture(background); SDL_DestroyTexture(image); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); IMG_Quit(); SDL_Quit(); return 1; } 

خلفية البلاط


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

يمكننا معرفة عدد البلاط المطلوب في العرض عن طريق قسمة عرض النافذة على حجم البلاط ، وبالمثل بالنسبة للارتفاع.

 //   ,      //  :     ceil(float(SCREEN_WIDTH) / TILE_SIZE),    ,       ,      ; ,        ,     . int xTiles = SCREEN_WIDTH / TILE_SIZE; int yTiles = SCREEN_HEIGHT / TILE_SIZE; //   for (int i = 0; i < xTiles * yTiles; ++i) { int x = i % xTiles; int y = i / xTiles; renderTexture(background, renderer, x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE); } 

رسم الصورة الأمامية


كما كان من قبل ، يتم وضع الصورة الأمامية في منتصف النافذة.

 int iW, iH; SDL_QueryTexture(image, NULL, NULL, &iW, &iH); int x = SCREEN_WIDTH / 2 - iW / 2; int y = SCREEN_HEIGHT / 2 - iH / 2; renderTexture(image, renderer, x, y); 

يبقى فقط عرض النتيجة على النافذة وانتظر بضع ثوان ، تمامًا كما في الدرس الثاني.

 SDL_RenderPresent(renderer); SDL_Delay(2000); 

التنظيف


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

 SDL_DestroyTexture(background); SDL_DestroyTexture(image); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); IMG_Quit(); SDL_Quit(); 

بعد التجميع والإطلاق الناجحين ، إذا فعلت كل شيء بشكل صحيح ، فستظهر النافذة على النحو التالي:



نهاية الدرس الثالث


لذلك انتهى الدرس التالي. نراكم في الدرس 4: التعامل مع الأحداث.

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


All Articles