Хочешь беспорядочных связей? Книга-игра – свобода выбора!

 
Во всех бочках затычка

Разработчикам игр на Atril
Часть 6: Лист персонажа

Актуально для: Atril 2.1.1

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

Для поддержки работы с листом персонажа, атрил заранее пытается получить доступ к его шаблону и в дальнейшем работать с ним. В примере из GDK, это происходит в событии ‘jsiq_init_start’:
jsIQ.addEventHandler('jsiq_init_start', function(params, vars, process)   {
...
   this.containers.charsheet = $('#charsheet');
...
});

Здесь #charsheet это HTML-элемент определёный в разметке. После инициализации движка работать с листом персонажа возможно через jsIQ.containers.charsheet используя чистый jQuery, это первый вариант, он является практически эквивалентом реализации "магазина" из example.xml:
var items = getItemList(); // вызываем глобальный скрипт
var html = $&#40;'<ul></ul>'&#41;;
for &#40;var i = 0; i < items.length; i++&#41;&#123;
&nbsp; &nbsp; html.append&#40;'<li>' + items&#91;i&#93; + '</li>'&#41;;
&#125;
jsIQ.containers.charsheet
&nbsp; &nbsp; .html&#40;''&#41;&nbsp; &nbsp; &nbsp; &nbsp;// очищаем его содержимое
&nbsp; &nbsp; .append&#40;html&#41;;&nbsp; // вставляем инвентарь

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

Для этого познакомимся с "линкованными переменными" (красивого названия не придумано Smile ). Суть их проста: в текст параграфа и/или в шаблон листа персонажа (параграф charsheet) добавляем код вида:
<span class="linked" name="name"></span>
Теперь, движок в случае обнаружения переменной this.name (т.е. локальной для параграфа), либо vars.name (т.е. глобальной) при отображении параграфа сразу вставит содержимое.
Единственная проблема, что содержимое вставляется "как есть", а потому массивы и объекты так просто отобразить не получится. Но есть решение – создадим специальную функцию-знчение, для этого, в некотором скрипте-инициализирующем игровые параметры пишем:
jsIQ.linkValue&#40;'inventory', function&#40;&#41;&#123;
&nbsp; &nbsp;if &#40;!vars.inventory&#41; return '';
&nbsp; &nbsp;var list = $&#40;'<ul></ul>'&#41;;
&nbsp; &nbsp;for &#40;var name in vars.inventory&#41;&#123;
&nbsp; &nbsp;&nbsp; &nbsp; if &#40;!vars.inventory.hasOwnProperty&#40;name&#41;&#41;&#123;&nbsp; &nbsp;continue;&nbsp; &nbsp;&#125;&nbsp; &nbsp;&nbsp; &nbsp;
&nbsp; &nbsp;&nbsp; &nbsp; if &#40;vars.inventory&#91;name&#93; > 0&#41;&#123;
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; list.append&#40;'<li>' + vars.inventory&#91;name&#93; + '</li>'&#41;;
&nbsp; &nbsp;&nbsp; &nbsp; &#125;
&nbsp; &nbsp;&#125;
&nbsp; &nbsp;return list.html&#40;&#41;;
&#125;&#41;;

Как видите, функция всегда возвращает строку (а не html-элементы). Я сознательно не ре-использовал скрипт getItemList как в примере выше, по двум причинам: из экономии производительности и особенностей вызова скриптов.

Тему производительности пока трогать не будем, а вот с особенностями вызова скриптов познакомиться надо. Дело в том, что linkValue-функции и обработчики событий выполняются "вне параграфа", а в этой области напрямую вызвать ни локальные ни глобальные скрипты нельзя, их просто не существует.

Для вызова скриптов "извне" необходимо использовать команду
jsIQ.articleScript( scriptline, extargs, parentEnv )
где

  • scriptline – название скрипта, либо "скрипт-запрос" (вида ‘скрипт?параметр1=значение,параметр2=значение’)
  • extargs – ассоциативный массив параметров, передаваемых в скрипт
  • parentEnv – объект-описание окружения, здесь рассматриваться не будет

Одновременное использование "скрипт-запроса" и передача extargs не предусмотрена, либо то, либо то. Таким образом, в нашем пример, для вызова getItemList можно использовать:
var list = jsIQ.articleScript&#40; 'getItemList' &#41;;

Теперь познакомимся с обработкой события обновления листа персонажа. Это может пригодиться для реализации особых случаев или сложных действий с листом персонажа.
Событие ‘update_charsheet’ происходит в момент после окончания "рендеринга" текущего параграфа, а оно происходит по времени между preload и onload вызовами скриптов.

Добавление обработчика события можно сделать следующим образом:
jsIQ.addEventHandler&#40;'update_charsheet', function&#40;params, vars, process&#41;&nbsp; &nbsp;&#123;
&nbsp; &nbsp;// произошло обновление листа персонажа
&nbsp; &nbsp;if &#40;vars.hp < 1&#41; &#123;
&nbsp; &nbsp;&nbsp; &nbsp;// персонаж проиграл, лист персонажа отображать не нужно
&nbsp; &nbsp;&nbsp; &nbsp;this.containers.charsheet.hide&#40;&#41;;
&nbsp; &nbsp;&#125;
&nbsp; &nbsp;process.next&#40;&#41;;
&#125;&#41;;

На этом пока всё.

ps. Требуется небольшое пояснение относительно лучшей методики создания шаблона листа персонажа. Дело в том, что явно вытекает минимум два life-style игры на движке Atril:

  • standalone
  • игровой модуль
Принципиальная разница между ними в том, что stanalone (самостоятельная игра) может быть настроена абсолютно любым способом, можно изменить дизайн и т.д. В этом случае, шаблон листа персонажа лучше сразу "вшивать" в разметку index.html. А вот в случае игрового модуля, изначальную разметку менять не планируется, поэтому лучше всего использовать предопределённый параграф "charsheet": все его текстовые блоки будут использованы как единый шаблон листа персонажа.



Последний раз редактировалось: Jumangee (Ср Июн 11, 2014 16:48), всего редактировалось 1 раз