Найти в Дзене
МорковкаGPT

Hello SDL: создаем пустое окно

Оглавление

Здравствуйте, дорогие друзья.

Ранее мы уже рассматривали, как установить CodeBlocks и как подключить к нему SDL. Настала пора создать пустое окно, в котором в будущем мы будем писать игру. Давайте сделаем это.

Предполагается, что вы уже создали проект и подключили к нему библиотеку. Если нет - почитайте по ссылкам, как это сделать.

Заголовочная часть

Весь код будет расположен в нашем главном файле main.c. Это не идеально, но для первой небольшой программы сойдет. Сначала подключим заголовочные файлы:

-2

Первый - сама библиотека SDL, а второй понадобится для printf().

Создадим глобальные переменные, в которых будем хранить ширину и высоту создаваемого окна. Вообще так делать не стоит (увлекаться глобальными переменными), но в целях обучения так пока проще.

-3

изменять размеры мы не планируем, поэтому пометим их квалификатором const.

Создаем функцию main()

Осталось написать главную функцию main(). Держать весь код в одной функции - разумеется, антипаттерн. Позволим это себе опять же для простоты в обучающих целях.

-4

Функцию main() можно написать и без аргументов командной строки. Но сделаем все по правилам.

Создание окна SDL

Для начала нам понадобится указатель на структуру SDL_Window, который будет содержать в себе адрес главного окна будущей игры. Его нужно обнулить сразу после создания:

-5

И еще понадобится адрес поверхности (surface), на которую будет отрисовываться графика (картинки или примитивы):

-6

Загрузим видеомодуль SDL при помощи функции SDL_Init():

-7

Функция возвращает отрицательное значение, если загрузка видеомодуля не удалась. Воспользуемся этим и немного сократим код, положив его сразу в if. Если загрузка не удалась, то напечатаем сообщение об ошибке и выйдем из программы. Если удалась - идем дальше.

Пробуем создать окно. Ранее созданному указателю присвоим значение, которое вернула функция SDL_CreateWindow():

-8

Первый аргумент - название будущего окна. Оно будет отображаться в шапке. Второй и третий - координаты x и y левого верхнего угла. Мы инициализируем их константой SDL_WINDOWPOS_UNDEFINED. Окно появится, тем не менее, примерно посередине. Вы можете указать там любые цифры. Третий и четвертый говорят сами за себя - это наши константы ширины и высоты окна из самого начала туториала. И последний, пятый - это комбинация флагов запуска. Можно, например, указать SDL_WINDOW_HIDDEN - и окно будет скрыто. Нам это не нужно, поэтому оставляем как есть.

После попытки создания окна нужно проверить, получилось ли? Это делается уже знакомым образом:

-9

Мы сравниваем указатель с NULL, и если он нулевой, то окно создать не получилось. Выведем сообщение об ошибке и выйдем из программы.

Закрашиваем окно бирюзовым

Время немного порисовать. Поскольку это наше первое окно, то мы не будем вдаваться в тонкости - для этого будут отдельные статьи. Просто закрасим фон бирюзовым.

Получаем адрес поверхности окна в объявленный ранее указатель
Получаем адрес поверхности окна в объявленный ранее указатель
-11

Эта сложная конструкция представляет из себя вызов функции SDL_FillRect(), в которую передается:

  • поверхность окна
  • координаты отрисовки
  • цвет отрисовки

Координаты можно задать, передав во второй параметр вместо NULL экземпляр структуры SDL_Rect, в которой задать координаты левого верхнего угла, ширину и высоту. NULL означает рисование на весь экран.

Цвет отрисовки задается функцией SDL_MapRGB(), которую мы вызываем прямо в аргументах SDL_FillRect(). Она принимает формат изображения (забираем его запросом к полю format нашей поверхности окна) и цвет в виде известного всем RGB. Мы записали его в шестнадцатеричном виде, чтобы вам вдруг не стало скучно :) по сути это цвет (0, 255, 255), то есть бирюзовый.

Выводим рендер на передний план и ставим на паузу

Итак, окно создано и нарисовано. Но перерисовку вы пока не увидите, потому что она делается на заднем плане, так называемый back buffer. Чтобы увидеть бирюзовое окно, а не белое, нам нужно обновить экран функцией SDL_UpdateWindowSurface(), которая перекинет подготовленное изображение на front buffer, то есть на передний план:

-12

Зачем это делается? Чтобы избежать многоступенчатости при отрисовке изображения. Дело в том, что при подготовке кадра на него может последовательно навешиваться много спрайтов, выполняться какие-то преобразования графики и т.д. Чтобы видеть не слайдшоу, а ровный и красивый кадр, применяется такая технология.

Кто-то мог уже раньше времени скомпилировать проект... и увидеть вместо окна будущей игры просто мигнувшую консоль. Где же оно? Все нормально: окно создалось и сразу исчезло. В будушем мы будем разбирать красивый способ задержки - так, как это делается в реальных играх. А пока просто воспользуемся функцией из библиотеки SDL:

-13

Можно вместо нее использовать Sleep() из Windows, но мы же собираемся делать кроссплатформенно! Поэтому почему бы не воспользоваться встроенной функцией из SDL. Задержка задается в миллисекундах.

Осталось сделать всего одну вещь. Для корректного завершения работы программы на SDL нужно корректно закрыть окно и деинициализировать ее. Для этого напишем:

-14

Здесь мы уничтожаем окно и выходим из SDL, как легко догадаться из названий.

Ну и финальный штрих, куда без этого.

Конец функции main()
Конец функции main()

Результат

Ну все, вот теперь с чистой совестью жмякайте по компилу или нажимайте F9. Результат должен быть таким:

Супер-игра на SDL
Супер-игра на SDL

На фоне еще выскочит консоль, так как мы ее не убирали. В будущем ее можно будет убрать, а пока она остается для чтения сообщений об ошибках, которые в процессе обучения неизбежно случаются.

Итак, мы создали первое окно на SDL. В будущем именно на этой базе будут строиться игры. Исходный код примера можете скачать тут.