Разбор проектов на Defold 7. Простая кнопка

Всем привет :waving_hand:
Продолжаем серию разборов чужого кода с этой страницы: Публичный пример Defold .

Сегодня разбираем пример от britzlПростая кнопка.
Попробуйте этот проект в действии: запустите пример .
Исходная папка с проектом: ссылка на github .
Исходная папка с публичными примера Defold на github: ссылка на github.

Обращение к новичкам:

Я предполагаю, что у вас уже установлен Defold, если нет, перейдите по этой ссылке: Добро пожаловать в Defold.
Также, будет плюсом, если вы хотя бы поверхностно знакомы со строительными блоками Defold. Если нет, ознакомиться с основными концепциями Defold можно на официальном сайте — перейдите по этой ссылке.6.

Пример того, как скачать и открыть готовый проект:

Скачиваем архив с примерами проектов из github
Распаковываем скачанный ZIP архив примеров в любую папку во вашему усмотрению.
Переходим в папку examples.
Ищем проект play_animation.
Открываем game.project.

Внимание: скриншоты представлены ниже, это пример скачивания и открытия проекта, в этом примере мы рассматриваем пPreformatted textроект с названием play_animation, потому название папок проекта будет отличаться.


Скриншот 3. Открываем разархивированную папку(наименование может отличаться от вашего названия скаченной папки)
Скриншот 4. Открываем папу с примерами.

Рассмотрим структуру проекта:

ui.atlas— этот файл содержит изображения, предназначенные для визуализации кнопок.

Файл simple_button.gui представляет собой шаблон GUI-сцены, включающий две прямоугольные (box) ноды, каждая из которых содержит по одной текстовой ноде. Для отрисовки графики в прямоугольных нодах используется текстура — ссылка на изображение из атласа ui.atlas. Для текстовых нод в проект был добавлен шрифт, используемый для отображения текста.
image

Файл 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-обработчики для каждой кнопки. Они сами решают, нажаты ли они в данный момент.

Надеюсь, кому-нибудь этот материал будет полезен.
Всем спасибо за внимание :light_blue_heart:

Другие разборы:
  1. Разбор проектов на Defold 1.Tilemap Collisions [tilemap]
  2. Разбор проектов на Defold 2. Параллакс [parallax]
  3. Разбор проектов на Defold 3. Движение игровых объектов [animation, movement, input]
  4. Разбор проектов на Defold 4. Воспроизвести анимацию [animation, movement, input]
  5. Разбор проектов на Defold 5. Меню и игра. Прокси-коллекции [proxy-collection, gameloop, collection, gui]
  6. Разбор проектов на Defold 6. Пауза [пауза]
2 Likes