Уроки по SDL 2: Урок 2 — Main не резиновый

habr.png

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

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

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

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

#include 

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 

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;
};

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

© Habrahabr.ru