Наступает зима, красивые узоры на окнах, белое покрывало на земле. Обычно зимой хочется греться дома, сидеть за компьютером, неспешно работать и читать различные статьи. Правда у нас за окном пока слякоть, а падающий снег тает уже к утру... Но я, впадая в зимнюю спячку, решил немного размяться, почитать про всякого рода вкусности в области игр, попрограммировать какие-нибудь мелочи, одним словом - отдохнуть! И в своих поисках "интересных вещей" я снова и снова натыкаюсь на кроссплатформенную разработку: здесь запустили игру под Android, там злые птицы аннонсируют свой апдейт под iOS, да и в казуальном мире игры под Mac уже не новость. Что же делать со всем этим практически бунтом против PC? На ум приходит одна фраза: "если не получается подавить бунт, то нужно стать его предводителем".
|
В итоге я решил немного размяться, вспомнить паскалевидные языки и попробовать собрать какую-нибудь демку под ZenGL+Lazarus+Windows. Да, пока вот такая простенькая связка, но ведь начинать нужно всегда с простого, верно?
Итак, создаем новое приложение, без формы, только код, в Lazarus'е такой проект можно создать вот так: Файл->Создать...->Программа (в папке Проект). Теперь все удаляем и начинаем накручивать ZenGL. В секции begin-end добавляем регистрацию своих функций:
zgl_Reg( SYS_LOAD, @Init ); zgl_Reg( SYS_DRAW, @Draw ); zgl_Reg( SYS_EXIT, @Quit );
Эти первые три строчки кода регистрируют наши функции за сообщениями движка. В принципе удобно, так что поехали дальше.
wnd_SetCaption( 'Lampogolovii demo: Simple explosion' ); wnd_ShowCursor( TRUE ); scr_SetOptions( 500, 400, REFRESH_MAXIMUM, FALSE, FALSE );
Вроде все прозрачно. Установили надпись заголовка окна, показываем курсор и устанавливаем размеры и стиль самого окна. Круто? Ну тогда вызываем:
zgl_Init();
И в путь! Конечно, такое у нас не скопилируется, ведь мы не описали функции Init, Draw, Quit. Сегодня не будем зацикливаться на этом, а просто абстрактно подумаем над тем, что вообще здесь происходит. В принципе понятно, что сначала мы что-то регистрируем, затем устанавливаем параметры приложения и в конце запускаем нашу программу "крутиться" в цикле.
Но давайте разберем все это более детально.
Регистрация обработчиков
Подобный подход используется повсеместно, но вот оборачивание всего кода в функции OnInit, OnDraw и т.д. - лично для меня ново. Но мне это нравится, потому что таким образом я снимаю с себя ответственность за многие вещи... Например, в обработчике SYS_LOAD я точно знаю, что окно уже создано, разрешение окна и его состояние заданы, графика проинициализирована, да и вообще все хорошо. Удобно!
Если заглянуть в zgl_main.pas, то можно увидеть довольно большое количество событий, на которые можно подписаться с помощью функции zgl_Reg(), вот некоторые из них:
// несколько базовых SYS_LOAD SYS_DRAW SYS_UPDATE SYS_EXIT // а вот некоторые для работы с мышью INPUT_MOUSE_MOVE INPUT_MOUSE_PRESS INPUT_MOUSE_RELEASE // о-о-о, и айОС не обошли стороной INPUT_TOUCH_MOVE INPUT_TOUCH_PRESS INPUT_TOUCH_RELEASE
То есть все нормально, можно добраться до большинства необходимых событий.
Установка параметров окна и приложения в целом
В модуле zgl_screen.pas есть несколько полезных функций, позволяющих установить необходимые нам параметры окна. Что обычно делают игры? Ну, разворачиваются в полноэкранный режим, разрешая при этом сворачиваться в окно да и устанавливают необходимое разрешение. Еще хорошо бы отлавливать сворачивания окна и уход фокуса, чтобы ставить игровой процесс на паузу. В общем-то играм больше и нечего делать со своими окнами. При инициализации приложения, достаточно вызвать scr_SetOptions(), объявление которого выглядит вот так:
function scr_SetOptions( Width, Height, Refresh : Word; FullScreen, VSync : Boolean ) : Boolean;
и установить необходимые нам параметры. Насчет минимизации окна, в zgl_application.pas я нашел глобальную переменную appMinimized, но никаких связанных с ней сообщений, на которые можно было бы подписаться, я не нашел, что очень жаль, ведь это довольно важная вещь.
Запуск на инициализацию
Ну вот и все, теперь со спокойной совестью можно выполнить
zgl_Init();
В этой функции установятся все наши ранее выбранные параметры окна, проинициализируется лог, а также звуковой драйвер Vorbis (для проигрывания ogg-файлов), создасться контекст OpenGL и много чего другого. В общем, стартует наша программа! Там же зукручивается наш бесконечный цикл жизни приложения.
Разобрав основы, самые азы ZenGL, я немного напишу о своих эмоциях, возникших при знакомстве с ним. Постараюсь их систематизировать и выразить в плюсах и минусах.
Недостатки
Начну с минусов.
- Мне показалось жутким написание всяких zgl_ или scr_ вначале каждой функции... Первое желание - обернуть однотипные функции в классы. Я так и не понял, почему автор не пожелал этого сделать.
- Очень мало саппорт-классов и функций. Вроде текстуры есть, а вот библиотеки текстур нет. Вернее она есть, но назвать ее "библиотекой" язык не поворачивается. Даже сказав "список", я сильно преувеличу возможности zglTTextureManager'а. Звуки есть, а вот звуковой менеджер такой же, как и с текстурами - минималистичный, урезанный, "лишь бы был". Конечно, это не главное, но все же.
- Как я ни крутил исходники, пока от меня скрылась тайна - как пользоваться загрузкой текстур в отдельном потоке? То есть аргументы вроде resUseThreaded присутствуют, а вот как с этим быть на деле - не ясно. В вики тоже не нашел (правда я и искал недолго). Хотя в достоинствах движка это указано как фича, значит нужно искать дальше. Непрозрачность некоторых решений - довольно значительный минус.
На самом деле ругать бесплатную кроссплатформенную библиотеку на Pascal'е не хочется. Это также, как если бы вы увидели пегаса (лошадку с громадными крыльями, позволяющими летать) на улице и, отвернувшись, пробурчали "всю дорогу перегородил, негодник"...
Достоинства
Перейдем к положительным сторонам!
- Кроссплатформенность... даже не знаю, что и добавить! Это чудо какое-то, что на Lazarus'е можно собрать игру под разнообразное количество девайсов!
- Движок изначально затачивается под игры. То есть мы тут же можем найти поддержку бесплатного ogg-формата звуков, частицы, спрайты со слоями, поддержку мультиязычности текстов, джойстик, отзывчивость на тапы в айОС.
- Множество демок. Как еще изучать движок? Конечно, рассматривая демонстрации его работы. Хотя сами демки могли бы быть и покрасочнее, но и то, что идет в стандартной поставке с сайта - уже замечательно!
- Минималистичность во всем. Сомнительный плюс, согласен, но все же. Вы, наверно, удивитесь, но даже exe-шник, собранный в Lazarus'е весит всего 300-400Kb! Минимальные демки с GlScene весят в три-четыре раза больше!
- Если я пойму, как пользоваться многопоточной загрзкой текстур (я уверен, что это уже имеется, просто я никак не догоню, как этим пользоваться), то этот плюс станет весомым достоинством движка для меня!
- Выпущенные игры! Да-да, этот плюс перекрывает любые недостатки, замеченные в ZenGL. Именно выпущенные игры на BigFishGames говорят о том, что движок стоящий и к нему следует приглядеться всеми имеющимися глазами!
Итого
Вот и все, начало положено... Теперь осталось собрать несколько демок и разобраться, насколько просто делать игры на ZenGL.
Поздравляю всех с зимой!
И тебя с зимой)
ОтветитьУдалитьне тяни с демками, уже жду)
ок, постараюсь в начале следующей недели подготовить первую :)
УдалитьРаз уж я наткнулся на сей пост в гугле, то пожалуй отвечу :)
ОтветитьУдалить- ZenGL изначально разрабатывался for fun в духе C style, аки процедурное программирование. В классы всё это оборачивает уже каждый как хочет(например MondoZenGL со странички extra, а некоторые проекты используют свои внутренние наработки скрещивая с PhoenixLib)
- саппорт классы и функции действительно сведены к разумному минимуму, и библиотека предоставляет собой больше ядро, чем решение на все случаи жизни для ленивых
- многопоточная загрузка ресурсов описана в стандартной демке "02 - Resources". Wiki, к сожалению, наполнять жутко скучно и сейчас уже некогда...
- appMinimized исключительно для внутреннего пользования. Словить можно только потерю фокуса(что происходит и при сворачивании) посредством SYS_ACTIVATE(регистрируется процедура с параметром activate : Boolean). Ну и приложение само уйдёт на паузу, отключить это можно флагом APP_USE_AUTOPAUSE с zgl_Disable
ух ты! невероятно, что ты наткнулся на этот пост!
Удалитья сейчас себя чувствую как старушка, на кухню к которой зашел президент... все ли убрано? чем накормить? я нормально выгляжу?
большое спасибо за развернутые ответы! конечно, я понимаю, что времени на все не хватает! просто я описываю со своей стороны, размышляя над тем, что уже готово, а что придется допиливать под себя...
отдельное спасибо за напутствие ко второй демке! разобрался, все шикарно! в одном из следующих сообщений обязательно распишу об этом!
планируешь какие-то доработки/усовершенствования движка? или ближайшее время расписано по часам?
еще раз спасибо!
Иногда гуглю от скуки, и попадаю на перлы, вроде недавних корейских статей по совмещению Pascal с Android и в частности ZenGL( http://blog.naver.com/simonsayz/120174013310 ), так что ничего невероятного, коммунити у Pascal'я подходит под фразу "мир тесен" больше остальных.
Удалить>> просто я описываю со своей стороны, размышляя над тем, что уже готово, а что придется допиливать под себя...
да это понятно. Да и библиотеку есть за что ругать, так что feel free, демагогию я в блоге устраивать не буду и надеюсь никак не повлияю тутошним появлением на дальнейшие посты :)
>> планируешь какие-то доработки/усовершенствования движка?
Эх, всех интересует этот вопрос, всё чаще и чаще... :) В движке много моментов просится на переделку или полировку, но в этом году по возможности буду только поддерживать stable версию исправлениями критических/мелких проблем, если таковые объявляются(кое-чего накопилось в svn'е, всё никак релиз не соберу). А там посмотрим.
только хотел сказать, что Андрей вполне может найти сей пост и оставить комментарии, как пролистал к комментам и понял что это уже случилось!
ОтветитьУдалить...интересно это =)
Как там твой квадратик-нинзя?
ОтветитьУдалить