Всем привет! Это мой второй урок по SDL 2. Информацию я всё ещё беру отсюда.

Итак, приветствую вас на уроке

Main не резиновый


На прошлом уроке я всё красиво расположил в функции Main(), но для больших программ это не есть хорошо. Именно по-этому появилась возможность писать функции. Сейчас мы ею и воспользуемся.

Начнем написание кода с подключения SDL и объявления нескольких глобальных переменных.

#include <SDL2/SDL.h>

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

SDL_Window *win = NULL;
SDL_Surface *scr = NULL;
SDL_Surface *smile = NULL;

Здесь мы вне Main() функции объявили объекты окна(win), поверхности экрана(scr) и изображение этого смайлика(smile).

Давайте напишем функцию для инициализации SDL, создания окна и поверхности для рисования. Выглядит она таким образом:

Init()
int init() {
    if (SDL_Init(SDL_INIT_VIDEO) != 0) {
        return 1;
    }

    win = SDL_CreateWindow("Main не резиновый", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
    if (win == NULL) {
        return 1;
    }

    scr = SDL_GetWindowSurface(win);

    return 0;
}

Этот код вам должен быть знаком из предыдущего урока. Здесь мы инициализировали видео систему, создали окно с именем “Main не резиновый”, незаданными координатами и с ранее заданными размерами, а так же получили поверхность окна, сохранив её в scr. При ошибке эта функция вернет 1, иначе 0.

Теперь можно написать функцию для загрузки необходимых медиафайлов. Вот она:

Load()
int load() {
    smile = SDL_LoadBMP("smile.bmp");

    if (smile == NULL) {
        return 1;
    }

    return 0;
}

Эта функция предельно проста. Мы загружаем .bmp изображение с помощью функции SDL_LoadBMP. Эта функция принимает путь к файлу с изображением(полный или относительный), а возвращает объект класса SDL_Surface. Также следует проверить, корректность выполнения: если были проблемы с загрузкой(файл не найден, битый файл), то функция SDL_LoadBMP вернет NULL.

Также напишем программу для завершения приложения.

Quit()
void quit() {
    SDL_FreeSurface(smile);
    smile = NULL;
    
    SDL_DestroyWindow(win);

    SDL_Quit();
}

Здесь появилась новая функция SDL_FreeSurface, которая просто очищает поверхность. После присваиваем переменной smile значение NULL. Все остальные функции были разобраны в предыдущем уроке.

На этом написание функций закончилось и можно приступить к Main().

Main()
int main (int argc, char ** args) {
    if (init() == 1) {
        return 1;
    }

    if (load() == 1) {
        return 1;
    }

    SDL_BlitSurface(smile, NULL, scr, NULL);

    SDL_UpdateWindowSurface(win);

    SDL_Delay(2000);

    quit();

    return 0;
};

Здесь мы сначала вызываем функцию init(), написанную ранее, потом функцию load(), которую мы тоже раньше написали. Далее отображаем smile в scr, с помощью функции SDL_BlitSurface. Эта функция принимает поверхность для рисования, прямоугольник, который следует вырезать из данной поверхности(это бывает нужным для анимации), если ничего вырезать не надо — передается NULL, поверхность, на которую рисуют и прямоугольник, координаты которого используются для рисования. Если координаты нулевые – мы передаем NULL.

Пришло время поговорить про координаты. В SDL используется другая система координат, не та к которой все привыкли. Здесь точка с координатами (0, 0) находится в левом верхнем углу. Это важно учитывать при отображении, чтобы избежать неприятных ситуаций.

Что ж, это было увлекательно, продолжаем. Далее мы обновляем окно уже знакомой функцией, заставляем программу застыть на 2 секунды, вызываем написанную нами функцию quit() и завершаем программу. На выходе у нас выходит программа которая 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 *smile = NULL;

int init() {
    if (SDL_Init(SDL_INIT_VIDEO) != 0) {
        return 1;
    }

    win = SDL_CreateWindow("Main не резиновый", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
    if (win == NULL) {
        return 1;
    }

    scr = SDL_GetWindowSurface(win);

    return 0;
}

int load() {
    smile = SDL_LoadBMP("smile.bmp");

    if (smile == NULL) {
        return 1;
    }

    return 0;
}

void quit() {
    SDL_FreeSurface(smile);
    
    SDL_DestroyWindow(win);

    SDL_Quit();
}

int main (int argc, char ** args) {
    if (init() == 1) {
        return 1;
    }

    if (load() == 1) {
        return 1;
    }

    SDL_BlitSurface(smile, NULL, scr, NULL);

    SDL_UpdateWindowSurface(win);

    SDL_Delay(2000);

    quit();

    return 0;
};

Надеюсь всё было понятно. Всем удачи!

Комментарии (2)


  1. akk0rd87
    02.06.2019 10:07

    Есть у кого реальные проекты на SDL для Android и iOS? В магазинах можно посмотреть?


  1. embden
    02.06.2019 12:33

    Спасибо даже не за перевод, а просто за то, что выкладываете это на хабр. Я забросил читать оригинал, потому что на сайте оригинала сильно уставали глаза.