April 30, 2025

Делаем кнопку в defold druid через внешний модуль druid widget

  • Установка druid и первая настройка
  • создаем простую кнопку с кликом и изменениями
  • теперь попробуем закинуть кнопку в widget
  • А теперь попробуем сделать шаблон

Установка druid и первая настройка

Ставим пакеты.

-- game object -> project -> dependencies
https://github.com/Insality/druid/archive/refs/tags/1.1.0.zip
https://github.com/Insality/defold-event/archive/refs/tags/11.zip
-- Потом запускаем скачивание: Project ▸ Fetch Libraries

создаем main.gui + main.gui_script, в main.gui подключаем скрипт

-- загружает модуль druid.druid, нахоидтся в вашей папке по этому пути
-- пути в lua идут через точки
-- local druid локальная переменная для обращения
local druid = require("druid.druid")

-- init, жизненный цикл defold, вызывается один раз
-- создаем новый экземпляр druid, а внутрь передается self, к которому внутри экземляра сможет образаться druid
function init(self)
	self.druid = druid.new(self)
end

-- final вызывается один перед уничтожением компонента
-- druid.final останавилвает все анимации и события, чтобы не было утечек памяти
function final(self)
	self.druid:final()
end

-- update каждый кадр с dt
-- dt - дельтой времени с предыдущего кадра (в секундах)
-- druid:update обновляет внутренние таймеры и анимации
function update(self, dt)
	self.druid:update(dt)
end

-- on_message ловит все входящие сообщения от внешних gui, script, collection and etc
-- self.druid:on_input отправляет их внутрь druid, так вы позволяете реагировать на них внутри экземпляра
function on_message(self, message_id, message, sender)
	self.druid:on_message(message_id, message, sender)
end

-- вызывается при любом вводе от игрока
-- передает ввод от игрока внутрь экземпляра druid
function on_input(self, action_id, action)
	return self.druid:on_input(action_id, action)
end

создаем простую кнопку с кликом и изменениями

Создаем в main.gui ноду box, ставим ID btn, под этой ноду создаем текстовую ноду и даем ей ID btn_text, эти ID используются для доступа в коде.
И добавляем в наш код кнопку с текстом и функцию.

local druid = require("druid.druid")

-- функция, которая меняет текст на кнопке через метод :set_text
local function on_button_click(self)
	self.text:set_text('the button clicked!')
end

function init(self)
	self.druid = druid.new(self)
	-- создаем кнопку по ID btn
	self.btn = self.druid:new_button('btn',on_button_click)
	-- создаем текст по ID btn_text
	self.text = self.druid:new_text('btn_text', 'hello, teletype!')
end

теперь попробуем закинуть кнопку в widget

Что такое widget? в доке написано, что это многократно используемые компоненты, зачем это делать пока не знаю, видимо дальше поймем
Создаем widget.lua.

-- widgets/widget.lua
---@class Widget: druid.widget
local M = {}

function M:init()
	self.root = self:get_node("root")

	self.button = self.druid:new_button("btn", self.on_click)
	self.text = self.druid:new_text("btn_text", "Hello, Druid!")
end

function M:on_click()
	self.text:set_text("The button clicked!")
end


return M

А дальше подключаем его в main.gui_script, а, еще main.gui добавить root для нод.

local druid = require("druid.druid")
local Widget = require("main.widget")

function init(self)
	self.druid = druid.new(self)
	self.widget = self.druid:new_widget(Widget, nil)
end

А теперь попробуем сделать шаблон

widget.lua оставляем без изменений

-- widgets/widget.lua
---@class Widget: druid.widget
local M = {}

function M:init()
	self.root = self:get_node("root")

	self.button = self.druid:new_button("btn", self.on_click)
	self.text = self.druid:new_text("btn_text", "Hello, Druid!")
end

function M:on_click()
	self.text:set_text("The button clicked!")
end


return M

Создаем widget.gui, в нем нода root -> btn -> btn_text
И уже в main делаем шаблон и ссылаемся на наш widget.gui
Измененное подключение, добавили template_id

local druid = require("druid.druid")
local Widget = require("main.widget")

function init(self)
	self.druid = druid.new(self)
	self.widget = self.druid:new_widget(Widget, "widget")
end