GUI-скриптинг
Для управления логикой GUI и анимацией нод используются Lua-скрипты. GUI-скрипты работают так же, как и обычные скрипты игровых объектов, но сохраняются как файл другого типа и имеют доступ к другому набору функций: функциям модуля gui .
Добавление скрипта в GUI
Чтобы добавить скрипт в GUI, сперва создайте файл GUI-скрипта, кликнув ПКМ в каком-либо расположении в браузере Assets и выбрав New ▸ Gui Script и выпадающего контекстного меню.
Редактор автоматически открывает новый файл скрипта. Он основан на шаблоне и оснащен пустыми функциями времени жизни, как и скрипты игровых объектов:
function init(self) -- Добавьте здесь код инициализации -- Удалите эту функцию, если она не нужна end function final(self) -- Добавьте здесь код инициализации -- Удалите эту функцию, если она не нужна end function update(self, dt) -- Добавьте здесь код обновления -- Удалите эту функцию, если она не нужна end function on_message(self, message_id, message, sender) -- Добавьте сюда код обработки сообщений -- Удалите эту функцию, если она не нужна end function on_input(self, action_id, action) -- Добавьте сюда код обработки ввода -- Удалите эту функцию, если она не нужна end function on_reload(self) -- Добавьте сюда код обработки ввода -- Удалите эту функцию, если она не нужна end
Чтобы прикрепить скрипт к компоненту GUI, откройте файл компонента GUI и выделите его корень в Outline, чтобы вызвать свойства GUI. Задайте свойству Script требуемый файл скрипта.

Если компонент GUI был добавлен к игровому объекту где-либо в игре, скрипт будет запущен.
Пространство имен в “gui”
GUI-скрипты имеют доступ к пространству имен gui и всем gui-функциям. Пространство имен go недоступно, поэтому необходимо отделить логику игрового объекта в компоненты Script и осуществлять связь между GUI и скриптами игрового объекта. Любая попытка использовать функции go приведет к ошибке:
function init(self) local id = go.get_id() end
ERROR:SCRIPT: /main/my_gui.gui_script:2: You can only access go.* functions and values from a script instance (.script file) stack traceback: [C]: in function 'get_id' /main/my_gui.gui_script:2: in function
Передача сообщений
Любой компонент GUI с подключенным скриптом может взаимодействовать с другими объектами в рантайме игры посредством передачи сообщений, он будет вести себя как любой другой скриптовый компонент.
Обращение к компоненту GUI происходит так же, как и к любому другому компоненту скрипта:
local stats = score = 4711, stars = 3, health = 6 > msg.post("hud#gui", "set_stats", stats)

Обращение к нодам
GUI-нодами можно манипулировать с помощью GUI-скрипта, прикрепленного к компоненту. Каждая нода должна иметь уникальный Id, который задается в редакторе:

Id позволяет скрипту получить ссылку на ноду и манипулировать ею с помощью функций пространства имен gui:
-- расширить полосу здоровья на 10 единиц local healthbar_node = gui.get_node("healthbar") local size = gui.get_size(healthbar_node) size.x = size.x + 10 gui.set_size(healthbar_node, size)
Динамически создаваемые ноды
Чтобы создать новую ноду со скриптом в рантайме, есть два варианта. Первый вариант — создавать ноды с нуля, вызвав функции gui.new_[type]_node() . Они вернут ссылку на новую ноду, которую можно использовать для манипуляций с нодой:
-- Создать новую ноду Box local new_position = vmath.vector3(400, 300, 0) local new_size = vmath.vector3(450, 400, 0) local new_boxnode = gui.new_box_node(new_position, new_size) gui.set_color(new_boxnode, vmath.vector4(0.2, 0.26, 0.32, 1)) -- Создать новую ноду Text local new_textnode = gui.new_text_node(new_position, "Hello!") gui.set_font(new_textnode, "sourcesans") gui.set_color(new_textnode, vmath.vector4(0.69, 0.6, 0.8, 1.0))

Альтернативным способом создания новых нод является клонирование существующей ноды с помощью функции gui.clone() или дерева нод с помощью функции gui.clone_tree() :
-- клонировать полосу здоровья local healthbar_node = gui.get_node("healthbar") local healthbar_node_2 = gui.clone(healthbar_node) -- кнопка клонирования дерева нод local button = gui.get_node("my_button") local new_button_nodes = gui.clone_tree(button) -- получить новый корень дерева local new_root = new_button_nodes["my_button"] -- переместить корень (и дочерние элементы) на 300 вправо local root_position = gui.get_position(new_root) root_position.x = root_position.x + 300 gui.set_position(new_root, root_position)
Id динамических узлов
Динамически созданные ноды не имеют присвоенного им идентификатора. Это сделано специально. Ссылки, возвращаемые из gui.new_[type]_node() , gui.clone() и gui.clone_tree() — это единственное, что необходимо для доступа к нодам, поэтому необходимо отслеживать эти ссылки.
-- Добавить ноду Text local new_textnode = gui.new_text_node(vmath.vector3(100, 100, 0), "Hello!") -- "new_textnode" содержит ссылку на ноду. -- Нода не имеет идентификатора, и это нормально. -- Нет причин выполнять gui.get_node(), когда у нас уже есть ссылка.
- English
- 中文 (Chinese)
- Español (Spanish)
- Français (French)
- Νεοελληνική γλώσσα (Greek)
- Język polski (Polish)
- Português (Portuguese)
- Русский (Russian)
Did you spot an error or do you have a suggestion? Please let us know on GitHub!
Что такое script в HTML5?
HTML тег .
Такой подход очень удобный, так как это позволяет использовать один и тот же код на многих страницах веб ресурса, а также такой код имеет свойство к кэшированию. Это означает что файл будет помещен в кэш браузера и при дальнейших переходах на другие страницы не будет повторно загружаться.
Вы можете использовать тег
Атрибуты:
- src — указывается путь к файлу (скрипту), который будет загружен на сайт;
- async — добавляет возможность загрузить скрипт асинхронно;
- type — устанавливает тип подключаемого файла или же скрипта в нем, к примеру для javascript: type=»text/javascript» ;
- language — указывает язык программирования скрипта (считается устаревшим и можно не использовать);
- defer — можно отложить загрузку скрипта до тех пор, пока вся страница не будет полностью загружена.
Пример:
Использование библиотеки jQuery UI на практике

Библиотека jQuery UI состоит из виджетов и взаимодействий, которые позволяют создавать насыщенные веб-приложения со стилевым оформлением пользовательского интерфейса, подчиняющимся определенной теме, и обеспечивают чрезвычайно гибкие возможности настройки в соответствии с конкретными задачами. Ранее мы рассмотрели все эти виджеты и взаимодействия и в этой статье некоторые из указанных средств будут добавлены в наш базовый пример для демонстрации того, каким образом можно организовать их совместную работу.
В качестве отправной точки для данной статьи мы используем вариант документа, приведенный в примере ниже:
jQuery UI Цветочный магазин
В этом документе необходимые элементы генерируются с помощью шаблона данных (для сокращения разметки документа) на основании информации о продуктах, извлекаемой из файла JSON с помощью метода getJSON(). Вся совокупность элементов, соответствующих отдельным видам продукции, собирается в единственном элементе с идентификатором products. Файл mydata.json находиться в одном каталоге с документом и содержит следующие данные:
Также не забудьте добавить файл таблицы стилей styles.css:
h1 < min-width: 70px; border: thick double black; margin-left: auto; margin-right: auto; text-align: center; font-size: x-large; padding: .5em; color: darkgreen; margin-top: 0; >.dtable .drow .dcell .dcell > * input label #buttonDiv #oblock
Вид исходного документа в окне браузера представлен на рисунке:

Отображение данных
В качестве средства отображения продуктов для пользователя мы воспользуемся виджетом Accordion. Несмотря на то что имеется всего лишь шесть продуктов, мы разобьем их на группы, в каждую из которых войдет по два продукта, а для создания структуры элементов, которая требуется для виджета Accordion, используем jQuery. Соответствующие изменения представлены в примере ниже:
. $(function() < $.getJSON("mydata.json", function(data) < var flowers = $('#flowerTmpl').tmpl(data); var rowCount = 1; for (var i = 0; i < flowers.length; i += 2) < $("" + data[i].name + " и " + data[i + 1].name.toLowerCase() + "
").appendTo("#products"); $(" ") .appendTo("#products") .append(flowers.slice(i, i + 2)) > $('#products').accordion(); >); >); .
Здесь в функцию, передаваемую методу getJSON(), добавлен код, предназначенный для создания виджета Accordion, включая построение необходимой структуры элементов и вызов метода accordion(). В новой реализации названия цветов извлекаются из соответствующего источника с помощью объекта данных JSON, но для генерации HTML-элементов (которые затем разбиваются на группы и помещаются в оболочки, образуемые элементами div, в соответствии с требованиями виджета Accordion) по-прежнему используется подключаемый модуль шаблонов данных.
Вид документа в окне браузера после добавления вызова метода accordion() представлен на рисунке:

Добавление корзины покупателя
Нашим следующим шагом будет добавление простейшей корзины покупателя, представляющей отобранные покупателем продукты. Соответствующие изменения, которые для этого требуется внести в образец документа, представлены в примере ниже:
Запустить пример jQuery UI .dcell img #basketTable th, td td:first-child, th:first-child #placeholder #productWrapper #basket #buttonDiv Цветочный магазин
Давайте рассмотрим этот код более подробно.
Помещение виджета Accordion в оболочку
Мы хотим, чтобы корзина покупателя отображалась рядом с панелями виджета Accordion. Для этого мы помещаем элемент, для которого вызывается метод accordion(), внутрь другого элемента div:
Работа виджета Accordion будет нарушена, если окажется, что он не занимает все пространство родительского элемента по ширине, поэтому мы добавляем оболочку и фиксируем ее ширину с помощью CSS-свойства width:
#productWrapper
Таким образом, виджет Accordion, как и должно быть, благополучно располагается по всей ширине элемента-оболочки div, который занимает только 65% ширины своего родительского элемента.
Добавление таблицы
Для отображения корзины мы используем элемент table, который включаем в число статических элементов документа:
Продукт Количество Удалить Ничего не выбрано
Как и в случае виджета Accordion, мы помещаем элемент table в оболочку, ширину которой устанавливаем с помощью CSS-свойства:
#basket
В таблице содержится строка, в которой располагаются заголовки столбцов, и ряд-заполнитель, занимающий всю таблицу по ширине.
Обработка изменений входных значений
Чтобы связать таблицу с виджетом Accordion, мы реагируем на события change, порождаемые элементами input, которые создаются в функции getJSON(). Это делается с помощью следующей функции-обработчика:
$('input').change(function(event) < $('#placeholder').hide(); var fname = $(this).attr("name"); var row = $('tr[id=' + fname + ']'); if (row.length == 0) < $('#rowTmpl').tmpl(< name: fname, val: $(this).val(), product: $(this).siblings("label").text() >).appendTo("#basketTable").find("a").click(function() < removeTableRow($(this).closest("tr")); var iElem = $('#products').find("input[name=" + fname + "]") $('#products').accordion("activate", iElem.closest("div[id^=row]").prev()) iElem.val(0).select(); >) > else if ($(this).val() != "0") < row.children().eq(1).text($(this).val()) >else < removeTableRow(row) >>)
Эта функция-обработчик решает множество задач. Прежде всего, когда пользователь изменяет какое-либо значение, осуществляется проверка того, имеется ли уже в таблице строка, соответствующая данному продукту. В случае отсутствия такой строки создается новая строка, для генерации которой используется шаблон:
Необходимые для данного шаблона значения получаются с помощью методов ядра jQuery, которые извлекают информацию из элемента input, породившего событие. Мы хотим отображать также названия продуктов, и с этой целью выполняем поиск в DOM-дереве для нахождения ближайшего элемента label и считывания его содержимого:
$(this).siblings("label").text()
Вновь созданная строка присоединяется к таблице. Ряд-заполнитель был скрыт еще раньше в самом начале выполнения функции-обработчика:
$('#placeholder').hide();
Процесс добавления новых строк таблицы представлен на рисунке. Пользователь вводит значение в текстовом поле, и как только это поле теряет фокус ввода, в корзине покупателя появляется новая позиция:

Удаление строк
Вы могли заметить, что в качестве части шаблона данных в документ добавляется элемент . При создании строки по шаблону мы регистрируем функцию-обработчик для этого элемента:
. .appendTo("#basketTable").find("a").click(function() < removeTableRow($(this).closest("tr")); var iElem = $('#products').find("input[name=" + fname + "]") $('#products').accordion("option", "active", Number(iElem.closest("div[id^=row]").attr('id').substring(3)) - 1) iElem.val(0).select(); >) .
function removeTableRow(row) < row.remove(); if ($('#basketTable tbody').children(':visible').length == 1) < $('#placeholder').show(); >>
Удалив строку из таблицы корзины покупателя, мы находим среди продуктов элемент input, связанный с данной строкой. Затем мы используем навигацию по DOM-дереву для поиска элемента, являющегося ближайшим предшествующим сестринским элементом по отношению к элементу div, который содержит данный элемент input, и передаем его индекс свойству active виджета Accordion. Это приводит к раскрытию той части виджета Accordion, которая содержит элемент, только что удаленный пользователем из корзины.
Наконец, мы устанавливаем значение данного элемента input равным 0 и вызываем метод select(), в результате чего этот элемент получает фокус ввода, а содержащееся в нем значение выделяется.
Обновление существующих строк
Если в таблице корзины покупателя уже есть строка, соответствующая нужному продукту, то заказываемое количество данного продукта можно изменить. Вместо того чтобы удалять одну строку и создавать другую, мы находим эту строку в таблице и обновляем содержимое нужной ячейки:
row.children().eq(1).text($(this).val())
Переменная row — это объект jQuery, содержащий элемент tr для продукта в таблице. Доступ к элементу td осуществляется по номеру позиции (с помощью метода eq()), а его содержимое устанавливается с помощью метода text().
Применение темы оформления
Теперь наша корзина функционирует вполне удовлетворительно, но ее внешний вид оставляет желать лучшего. К счастью, jQuery UI предоставляет библиотеку CSS-стилей (CSS-фреймворк), которые можно применить к элементам, чтобы они выглядели так же, как и виджеты после применения к ним выбранной вами темы стилевого оформления. В примере ниже показано, насколько просто получить требуемый результат путем добавления классов в HTML-элементы документа:
. class="ui-widget ui-widget-content"> class="ui-widget-header">Продукт Количество Удалить Ничего не выбрано
.
Для элемента table дополнительно к использованию указанных классов задано отсутствие границ (рамки):
#basketTable
Полученный результат проиллюстрирован на рисунке:
Создание кнопки jQuery UI
Наш следующий шаг — перемещение кнопки в другое место и ее преобразование в виджет jQuery UI. Для этого внесем изменения в функцию-обработчик загрузки страницы:
$(function() < . $('#buttonDiv, #basket').wrapAll("").parent().css(< float: "left", marginLeft: "2px" >) $('button').button() >);
а также добавим пару CSS-стилей:
#basket #buttonDiv
Здесь мы поместили элементы buttonDiv и basket в новый элемент div и изменили некоторые CSS-стили для настройки позиций этих элементов. И наконец, мы вызываем метод button() для создания кнопки jQuery UI, как показано на рисунке:

Добавление диалогового окна для завершения заказа
Мы хотим, чтобы, прежде чем завершить оформление заказа, щелкнув на кнопке «Заказать», пользователь предоставил нам некоторую дополнительную информацию о себе. Чтобы внести некоторое разнообразие, воспользуемся виджетом Dialog. Также добавим функцию обработки введенных пользователем данных. В примере ниже показан конечный код примера, а затем мы более подробно рассмотрим нововведения:
Запустить пример jQuery UI .dcell img #basketTable th, td td:first-child, th:first-child #placeholder #productWrapper #buttonDiv #basketTable #basket #buttonDiv /* 2 новых стиля */ #completeDialog input #completeDialog label Цветочный магазин
Здесь мы добавили элемент div, содержимое которого будет отображаться для пользователя в элементе body, а также некоторые CSS-стили, заменяющие стили из файла styles.css, которые импортируются в документ с помощью элемента link. Для создания диалогового окна используется следующий вызов метода dialog():
$('#completeDialog').dialog(< modal: true, autoOpen: false, buttons: [, >] >);
Здесь мы создаем модальный вариант диалогового окна, в котором есть две кнопки. После щелчка на кнопке «Отмена» диалоговое окно закрывается. Щелчок на кнопке «OK» приводит к вызову функции sendOrder():
function sendOrder() < var data = new Object(); $('input').each(function(index, elem) < var jqElem = $(elem); data[jqElem.attr("name")] = jqElem.val(); >) console.log(JSON.stringify(data)); $('#completeDialog').dialog("close"); $('#products input').val("0"); $('#products').accordion("option", "active", 0) $('#basketTable tr').has(':not(th)').filter(':visible').remove(); $('#placeholder').show(); >
В этой функции мы получаем значения, содержащиеся в каждом из текстовых полей, и добавляем их в виде свойств в объект, который затем преобразуем в формат JSON и выводим на консоль.
Далее мы возвращаем документ в исходное состояние путем закрытия диалогового окна, сброса значений в текстовых полях, перехода на первую вкладку виджета Accordion и очистки корзины. Само диалоговое окно выглядит следующим образом:

Щелчок на кнопке «OK» приводит к генерации данных в формате JSON и восстановлению исходного состояния документа. Консольный вывод имеет следующий вид:

Когда пользователь щелкает на кнопке, мы проверяем, является ли элемент placeholder видимым. Это делается с помощью селектора jQuery, предоставляющего объект, который содержит элементы лишь в том случае, если указанный элемент виден на экране.
Здесь видимость элемента placeholder используется для индикации того, выбран ли пользователем хотя бы один продукт. Если в корзине покупателя есть хотя бы один продукт, этот элемент скрыт, и его появление говорит о том, что ни один продукт выбран не был:
$('#buttonDiv button').button().click(function(e) < e.preventDefault(); if ($('#placeholder:visible').length) < $('Вы ничего не выбрали для заказа').dialog(< modal: true, buttons: [>] >) > else < $('#completeDialog').dialog("open"); >>)
Описанный прием служит хорошим примером реализации функциональности приложения на нескольких уровнях. Вместе с тем использованный подход к проверке того, выбрал ли пользователь продукты, зависит от способа реализации корзины покупателя, и если этот способ впоследствии будет изменен, то процедуру проверки также потребуется изменить.
Если пользователь выполняет щелчок на кнопке, не выбрав ни одного продукта, динамически создается и отображается диалоговое окно, представленное на рисунке ниже:

В этой статье мы переработали простой документ, включив в него интерактивные возможности, предлагаемые библиотекой jQuery UI. В него были добавлены виджеты Accordion, Dialog и Button, а также использовалась функциональность классов CSS-фреймворка jQuery UI для управления внешним видом других элементов.
Веб-компонент в сборе
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
Более новая информация по этой теме находится на странице https://learn.javascript.ru/web-components.
В этой главе мы посмотрим на итоговый пример веб-компонента, включающий в себя описанные ранее технологии: Custom Elements, Shadow DOM, CSS Scoping и, конечно же, Imports.
Компонент ui-message
Компонент ui-message будет описан в отдельном файле ui-message.html .
Его использование будет выглядеть следующим образом:
ui-message
Этот код ничем не отличается от использования обычного элемента, поэтому перейдём дальше, к содержимому ui-message.html
Шаблон для ui-message
Файл ui-message.html можно начать с шаблона:
.content < min-height: 20px; padding: 19px; margin-bottom: 20px; background-color: #f5f5f5; border: 1px solid #e3e3e3; border-radius: 4px; box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); >:host < display: block; >:host(.info) .content < color: green; >:host(.warning) .content