Возрождение Framework-а (часть 1)

от автора

В процессе работы над арканоидом, стало становиться понятным, чего именно не хватает Marmalade Framework-у, разработанному ранее, в процессе создания значительно более простой игры. Выяснилось, что не хватает ему практически всего (именно поэтому я не смог его как либо использовать, работая над арканоидом).

Теперь, когда я готов начать обобщать полученный опыт, я приступаю к работе над следующей версией Framework-а. Как и прежде, цель этой разработки — облегчение выполнения рутинных операций при разработке 2D-игр с использованием инструментальной среды Marmalade, но теперь, основной упор будет сделан на декларативность. В идеале, в коде не должно оставаться никакой конкретики в отношении используемых ресурсов, позиционирования объектов на экране, локализации и т.п.

В этой статье не будет кода (именно поэтому я не помещаю ее в хабы разработки под iOS и Android). Сегодня, по совету crmMaster, я займусь проектированием.

Сердцем нашего проекта будет JSON-описание. Вообще говоря, с тем парсером, который мы интегрировали в проект, мы могли-бы использовать YAML, но JSON мне нравится больше.

Итак, первое, что будет делать приложение после старта — это загрузка описания из файла main.json. Ниже мы рассмотрим, как будет выглядеть содержимое этого файла.

{ load: state.json,   ... } 

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

Используя директиву load мы сможем добавить файл в очередь загрузок. Я специально не стал использовать слово include, поскольку оно подразумевает включение некоего ресурса непосредственно в той точке где находится по описанию. В нашем случае, файлы указанные директивой load, в корневой секции описания, будут загружены после завершения загрузки main.json. Также можно будет использовать динамическую загрузку описаний, о которой я расскажу позже.

Файл state.json, упомянутый нами в примере, обеспечит нашему приложению персистентность. Он будет содержать последовательность присвоений переменным, содержащим основные настройки игры (таким как собственно пользовательские настройки, достигнутый в процессе игры уровень и т.п.). Откуда возьмутся эти переменные, я также расскажу ниже. Сейчас важно понимать, что отсутствие этого файла при загрузке — это вполне штатная ситуация, не ведущая к ошибке выполнения. Такое возможно, например, при первом запуске приложения или после удаления игровых настроек в Android.

   templates: { some_template: { ...                                }               }    ...    template: some_template,    ... 

Эта конструкция позволит нам эффективно бороться с копипастом. Используя ее мы сможем определить повторяющиеся именованные шаблоны, чтобы впоследствии использовать их в любом месте описания. Единственным условием такого использования является то, шаблон может быть использован только если он определен ранее в описании (парсер будет однопроходным).

Шаблоны можно будет определять не только в корневом, но и во вложенных разделах. Для чего могут понадобиться подобные локальные шаблоны — отдельная тема. Я собираюсь затронуть ее когда мы перейдем к реализации загрузчика.

  display:    { width:         720,                 orientation:   portrait               } 

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

Можно задать значения width и height, но, как правило будет задаваться только одна из них. В этом случае, все размеры и позиции будут пересчитываться так, чтобы пиксел оставался квадратным при любом соотношении сторон. Также, договоримся, что отрицательные размеры позиций будут означать координаты от правой и нижней сторон экрана, в сторону уменьшения.

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

  devices:  [ { default:     Y,                 width:       720,                 height:      1280,                 path:        1280               }             ] 

В этом разделе мы описываем соотношения сторон, для которых имеются ресурсы не требующие масштабирования. Строка path будет автоматически добавятся в начало имени любого графического ресурса. Задачей Framework-а будет выбор из имеющегося набора ресурсов того, который обеспечит наименьшие искажения при отображении.

  langs:     [ { id:          16,                  path:        ru,                  default:     Y                }              ] 

Аналогичным образом описываются доступные локализации. Значение id должно соответствовать используемому в Maramalade. Строка path добавляется в имя любого локализованного ресурса (графического или звукового). Framework должен будет определить локализацию, исходя из текущих настроек устройства и приложения.

  resources:  { logo:        { localized:        Y,                                file:             backgrounds/logo.png                              },                 ball:        { x:                0,                                y:                0,                                width:            10,                                height:           10,                                left_margin:      3,                                                          right_margin:     3,                                                          top_margin:       3,                                                          bottom_margin:    3,                                file:             game/atlas.png                              }               } 

Таким образом мы будем описывать графические ресурсы. Обязательная настройка file определяет имя файла, в котором содержится ресурс. Настройки x, y используется при работе с текстурными атласами. Они, также как настройки width и height должны соответствовать размеру экрана, определенному в разделе display.

Настройки xxx_margin будут использоваться для изображений с прозрачными фрагментами на краях. Например, стреляющая платформа в арканоиде отрисовывается с двумя пушками по бокам. Фрагмент между пушками — прозрачный и в него может заходить шарик. Используя top_margin, мы можем определить его высоту.

В следующей части я планирую рассказать о разделах scopes и regions, определяющих блоки, из которых будет строиться приложение.

Исходные тексты Framework-а будут выкладываться на GitHub, по мере разработки.

ссылка на оригинал статьи http://habrahabr.ru/post/170189/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *