Всем привет
Продолжаем серию разборов чужого кода с этой страницы: Публичный пример Defold .
Сегодня разбираем пример от britzl — Простая кнопка.
Попробуйте этот проект в действии: запустите пример .
Исходная папка с проектом: ссылка на github .
Исходная папка с публичными примера Defold на github: ссылка на github.
Обращение к новичкам:
Я предполагаю, что у вас уже установлен Defold, если нет, перейдите по этой ссылке: Добро пожаловать в Defold.
Также, будет плюсом, если вы хотя бы поверхностно знакомы со строительными блоками Defold. Если нет, ознакомиться с основными концепциями Defold можно на официальном сайте — перейдите по этой ссылке.6.
Пример того, как скачать и открыть готовый проект:
Скачиваем архив с примерами проектов из github
Распаковываем скачанный ZIP архив примеров в любую папку во вашему усмотрению.
Переходим в папку examples
.
Ищем проект play_animation
.
Открываем game.project
.
Внимание: скриншоты представлены ниже, это пример скачивания и открытия проекта, в этом примере мы рассматриваем п
Preformatted text
роект с названием play_animation, потому название папок проекта будет отличаться.


Рассмотрим структуру проекта:
ui.atlas
— этот файл содержит изображения, предназначенные для визуализации кнопок.
Файл simple_button.gui
представляет собой шаблон GUI-сцены, включающий две прямоугольные (box) ноды, каждая из которых содержит по одной текстовой ноде. Для отрисовки графики в прямоугольных нодах используется текстура — ссылка на изображение из атласа ui.atlas
. Для текстовых нод в проект был добавлен шрифт, используемый для отображения текста.
Файл simple_button.collection
— представляет коллекцию, включающий в себе один игровой объект, содержащий шаблон gui-сцены.
simple_button.gui_script
— это GUI-скрипт, привязанный к компоненту simbple_button.gui
.
simple_button.lua
— это модуль, который позволяет создавать кнопку и обрабатывать события, связанные с ней.
Рассмотрим simple_button.lua:
local M = {}
Создаём переменную, которая будет содержать в себе таблицу.
-- create a simple button handler
-- @param node The node representing the button
-- @param pressed_animation
-- @param released_animation
-- @param callback Function to call when button is clicked
-- @return Button instance
Этот блок — документация к функции M.create(...)
, написанная в стиле LDoc, который часто используют в Lua для описания функций. Он не выполняется — это просто комментарии, поясняющие, как работает функция.
LDoc — это совместимая с LuaDoc система генерации документации для исходного кода Lua. Она анализирует комментарии к декларации и документации в наборе исходных файлов Lua и создает набор страниц XHTML, описывающих прокомментированные декларации и функции.
local button = {
pressed = false
}
Создаём таблицу-кнопку. Переменная pressed
отвечает за то, нажата кнопка или нет.
gui.play_flipbook(node, released_animation)
Изначально ставим анимацию кнопки в состояние “не нажата”. Напомню, у нас в атласе два изображения предназначенных для двух разных состояний: нажата
, не нажата
.
function button.on_input(action_id, action)
...
end
Добавляем функцию в таблицу button
. Это то, что нужно будет вызывать из on_input()
в simple_button.gui_script
. Этот блок кода обрабатывает взаимодействие игрока с кнопкой. Иными словами: “будет проверять, нажал ли игрок на кнопку или нет”.
local over = gui.pick_node(node, action.x, action.y)
gui.pick_node(node, x, y)
— проверяет, находится ли action
в границе ноды (позиция курсора по оси X и Y). Возвращает true
или false
.
action
— это таблица, которую Defold передаёт в твою функциюon_input(action_id, action)
при каждом взаимодействии пользователя. Она содержит данные о том, что именно произошло на экране: куда нажали, отпустили ли кнопку и т.д.
if over and action.pressed then
button.pressed = true
gui.play_flipbook(node, pressed_animation)
Если координаты мыши находятся на ноде и если игрок нажал на кнопку, меняем значение button.pressed
на истину (кнопка нажата), меняем анимацию ноде.
elseif action.released and button.pressed then
button.pressed = false
gui.play_flipbook(node, released_animation)
if over then
callback(button)
end
end
Если:
action.released
— игрок отпустил кнопку мыши или палец.
button.pressed
— до этого была нажата эта же кнопка (button.pressed == true
).
button.pressed = false
— мы сбрасываем флаг, говорящий, что кнопка больше не нажата.
gui.play_flipbook(node, released_animation)
— меняем изображение на соответствующее состоянию “не нажата”.
if over then
callback(button)
end
Если палец/мышь отпущены, и до этого была нажата кнопка — вызывается callback
.
Рассмотрим simple_button.gui_script:
local simple_button = require "simple_button.simple_button"
Импортирует модуль, в котором определена функция simple_button.create — она создаёт кнопку и возвращает объект с функцией on_input.
local function create_blue_button(node, callback)
return simple_button.create(node, hash("blue_button_pressed"), hash("blue_button_released"), callback)
end
Эта функция создаёт кнопку, передавая нужные flipbook-анимации (pressed
и released
) и callback.
function init(self)
msg.post(".", "acquire_input_focus")
Запрашиваем фокус ввода, чтобы получать события on_input.
self.button1 = create_blue_button(gui.get_node("button1"), function()
print("Clicked button 1")
end)
Создаём первую кнопку. Callback — в консоли напечатается Clicked button 1.
self.button2 = create_blue_button(gui.get_node("button2"), function()
print("Clicked button 2")
end)
То же самое, но для второй кнопки.
function on_input(self, action_id, action)
self.button1.on_input(action_id, action)
self.button2.on_input(action_id, action)
end
Когда игрок нажимает или отпускает кнопку мыши или палец — вызываются on_input-обработчики для каждой кнопки. Они сами решают, нажаты ли они в данный момент.
Надеюсь, кому-нибудь этот материал будет полезен.
Всем спасибо за внимание
Другие разборы:
- Разбор проектов на Defold 1.Tilemap Collisions [tilemap]
- Разбор проектов на Defold 2. Параллакс [parallax]
- Разбор проектов на Defold 3. Движение игровых объектов [animation, movement, input]
- Разбор проектов на Defold 4. Воспроизвести анимацию [animation, movement, input]
- Разбор проектов на Defold 5. Меню и игра. Прокси-коллекции [proxy-collection, gameloop, collection, gui]
- Разбор проектов на Defold 6. Пауза [пауза]