Correct way of implementing reusable button (template)?

Hi,

I want to implement multiple buttons that each have the same:

  • click animation
  • click sound

They all have different:

  • image/texture
  • action/behaviour

My goal is to easily add new buttons to the game without reimplementing animation and sound.

In Godot I would have a scene with all the elements in it, and would create inherited copies of this scene where I then simply change the texture.

How would I go about this in Defold?

Right now I would:

  • add the button click sound to the collection
  • add the button animation script to the main gui script
  • handle button click in main gui script and call animation and sound

But this feels a bit all over the place. I would like to keep the button elements together…

Edit: Maybe collections are the way to go? But how would they fit in cleanly with the main gui?

I would probably collect the button click logic in a Lua module and only pass it the button node id and a function to call if the button was clicked. Like this:

-- button.lua

local M = {}

function M.check_click(self, node_id, action, callback)
	local node = gui.get_node(node_id)
	if gui.pick_node(node, action.x, action.y) then
		if action.released then
			gui.animate(node, gui.PROP_SCALE, 1.2, gui.EASING_INOUTQUAD, 0.3, 0, nil, gui.PLAYBACK_ONCE_PINGPONG)
			sound.play("#buttonclick")
			callback(self)
			return true
		end
	end
	return false
end

return M


-- my_ui.gui_script

local button = require("button")

function on_input(self, action_id, action)
	button.check_click(self, "button1", action, function(self) print("button1 was clicked") end)
	button.check_click(self, "button2", action, function(self) print("button2 was clicked") end)
end
2 Likes

YEs, the common approach is to create prefabs/template following some convention (e.g. gui template with node for a background of button, text node, etc) and creating them in code.

Good example of such approach is Druid:

It has a button component already and it is a good approach to make it reusable (in OOP way), by using proper templates and defining “on_click” functions for each button.

1 Like

Thank you. That worked nicely, and cleaned it up quite a bit. :slight_smile:

But I’m still wondering, if there is a way to group the button logic, and button elements like the click sound, or the image texture, together? Or am I thinking wrong here conceptually?

1 Like

Thank you. Druid is something I want to check out in the future. :+1: :slight_smile:

1 Like

The only thing you don’t have in Defold’s GUI component is audio - you have to send a message (like an event) to any script controlling your sounds. Rest - you can do all in gui_script :wink:

Regarding sounds - it’s nevertheless a good practice imho to keep sounds in a separate game object controlling all your sounds in your game and either have all sounds already included in such GO or add/remove them dynamically using factories, when needed (or mixed, e.g. dynamically loading only background music and leaving UI and regularly used sounds “static” for the whole game lifecycle ) :wink:

2 Likes