Common Lisp — отличный язык, но статей по нему катастрофически мало.
Думаю этого вполне достаточно, для того чтобы написать этот цикл статей.
Почему я выбрал общелисп? Что ж, на вкус и цвет как говорится.
Впрочем, причины есть:
Фактически эта серия — адаптация туториалов от Lazy Foo:
http://ift.tt/1qKCTaT
В этой статье я не буду детально объяснять как ставить все необходимое ПО, но
если это кому-то действительно интересно, пожалуйста, напишите об этом
в комментариях.
Для установки SDL2, воспользуйтесь советами Фу: http://ift.tt/1YhcznL.
Что касается лиспа, я пользуюсь реализацией www.sbcl.org и www.quicklisp.org.
На данный момент работоспособность проверялась только в ней.
Дальше я использую библиотеку cl-sdl2: http://ift.tt/1ndd6tf.
Так уж вышло, что поддержка некоторого функционала из SDL2, например
surfaces, в ней реализована не полностью. Но это не беда, я дописываю
нужный функционал по мере продвижения по туториалам. Поэтому не
ставьте версию из quicklisp’а, а сразу клонируйте мастер ветку в ~/quicklisp/local-projects
.
Предполагается, что вы минимально понимаете синтаксис лиспа и не пугаетесь от обилия скобок.
В качестве основного средства взаимодействия с лисповым окружениям я буду использовать slime.
Вы еще не пробовали spacemacs? Тогда мы идем к вам!
Тем кому не нужна лирика, а нужен код: http://ift.tt/1Qp6hk7
Белый экран жизни
Начнем с того, что просто заставим SDL2 показать нам окошко, залитое белым цветом.
Очевидно, нам понадобится сам библиотека cl-sdl2. Подключим её:
CL-USER> (ql:quickload :sdl2)
Не будем усложнять себе задачу и создадим окошко фиксированного размера.
Для этого объявим глобальные (и более того специальные) переменные для ширины и высоты нашего окошка, ведь магические числа — зло.
(defparameter *screen-width* 640)
(defparameter *screen-height* 480)
Теперь создадим функцию, которая будет открывать нам окно, заливать
его белым цветом ждать некоторое время, и закрываться.
Незатейливо обзовем нашу функцию main и добавим ей опциональный
именованный параметр, чтобы мы могли регулировать время через которое
окно будет закрываться. По умолчанию двух секунд нам за глаза.
(defun main (&key (delay 2000))
Затем нам нужно инициализировать sdl2, сказав библиотеки какие
подсистемы мы хотим использовать. Для этого cl-sdl2 предоставляем нам удобный макрос:
(sdl2:with-init (:video)
Мы хотим использовать только подсистему вывода графики, поэтому
передадим символ :video. Вы спросите: «как я должен был догадаться,
что передать нужно именно :video?» Отвечаем: cl-sdl2 преобразовывает
SDL_ константы в соответствующие символы. Например,
мы можем открыть документацию по методу SDL_Init и посмотреть
доступные флаги: http://ift.tt/1ndd7h0
Чтобы получить необходимый символ отрежем от имени константы SDL_INIT_ и
преобразуем флаг в нижний регистр.
Прелесть with- макросов в том, что они в обязательном порядке
освобождают все выделенные ресурсы, освобождая нас от необходимости
следить за этим самостоятельно.
Отлично, дальше создадим окно:
(sdl2:with-window (window :title "SDL2 Window" :w *screen-width* :h *screen-height*)
Это очередной with макрос. В этот раз первым элементом списка
аргументов макроса будет символ window, через который в теле
макроса мы и будем обращаться к созданному окну. Именованные
параметры :title, :w, :h думаю вполне очевидны и не нуждаются в
объяснения.
С окном все понятно, но теперь мы хотим залить получившееся окно белым
цветом. Одним из вариантов реализации задуманного будет использование
«поверхностей», они же surfaces. По сути, поверхность это структура
содержащая пиксели некоторой области, используемая при программном
рендеринге. Например, мы можем получить поверхность нашего окна:
(let ((screen-surface (sdl2:get-window-surface window)))
и залить его белым цветом:
(sdl2:fill-rect screen-surface
nil
(sdl2:map-rgb (sdl2:surface-format screen-surface) 255 255 255))
Первый аргумент — прямоугольник, который мы хотим залить. Если его не
передать, будем заливать всю область. Зачем несчастный #fff
записывать таким сложным образом? Все дело в разнообразии форматов
пикселей, экранов и тому подобного. А так как SDL2 библиотека
кросcплатформенная, для применения всех необходимых преобразований
используются различные функции, как например map-rgb в данном случае.
Залить окно залили, но этого недостаточно. Теперь нам нужно вежливо попросить библиотеку обновить наше окошко:
(sdl2:update-window window)
Учитывая что весь так долго описанный процесс пройдет за доли секунды,
а мы все-таки хотим насладится полученным результатом, попросим sdl подождать немного:
(sdl2:delay delay)
Ну и самое главное:
)))
Вот собственно и все. Осталось запустить наше творение, и надеятся, что мы не вылетим в отладчик:
CL-USER> (main)
На всякий случай,
(defparameter *screen-width* 640)
(defparameter *screen-height* 480)
(defun main (&key (delay 2000))
(sdl2:with-init (:video)
(sdl2:with-window (window :title "SDL2 Window" :w *screen-width* :h *screen-height*)
(let ((screen-surface (sdl2:get-window-surface window)))
(sdl2:fill-rect screen-surface
nil
(sdl2:map-rgb (sdl2:surface-format screen-surface) 255 255 255))
(sdl2:update-window window)
(sdl2:delay delay)))))
Честно говоря, я планировал в одной статье рассказать сразу про первых три туториала, но как-то уже и так много текста вышло.
Для нетерпеливых, еще раз ссылка на код туториалов (на момент написания статьи 16 штук):
http://ift.tt/1Qp6hk7
Надеюсь это было интересно и познавательно.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.
Комментариев нет:
Отправить комментарий