Check for texture in atlas

Hello, how can I check if texture exists in atlas?

for example

if some_method_to_caeck(hash("some_texture")) then
    gui.play_flipbook(node, hash("some_texture"));
end

Or maybe there are some other way to do that…?
Thanks !

There is no API to check this. But don’t you already know if the atlas contains the animation? (since you did create it)

Not exactly.
I have custom Button module and to initiate that you need to provide gui node and 3 states (textures) of button.

local btn1 = Button.new("sound_btn", hash("sound_up"),  hash("sound_down"),  hash("sound_hover"),  callback);

Now if anyone wants to change one of textures he also need to go in to code, find the button and change the name of texture there. And problem is, it is not always a person who understand Lua.

What I want to achieve, is to create name patterns for button textures, for example.

function Button.new(node_name)
	local this = {};
	this.node = gui.get_node(node_name);

	local up_state  =  gui.get_flipbook(node); -- up_state - is not a string  :(  
    local down_state =  hash( up_state .. "_down"); -- this is not posible
    local hover_state = hash( up_state .. "_hover"); -- this is not posible
	local _callback = callback;
end

But while I was trying to explain my goal, I understood that it won’t work, because I can’t concatenate hash with string.
Even if I mention all three texture in constructor and then decide to delete a “hover_state” from atlas, my code will crash because it can’t first check if texture is there. And again I have to correct code.
My point is, that I can’t separate work of game designer from my work as programmer, this makes me upset(
Sorry for complaining, you doing great job with Defold, but some things here are not flexible.

Unrelated but ; is not necessary and style wise preferred to not include in any public module. :innocent:

In your example, when creating the btn1 with Button.new you can add an extra parameter to define the name of the base texture which is then used with all of the states. That is what we do in our games. In our pattern we say have a “btn_blue” that has states like “btn_blue_normal” “btn_blue_over” “btn_blue_down” then the name of the texture would be just “blue”, then playing the right animation is done with concatenated strings.

2 Likes

but ; is not necessary

yes), I know! A Habit from other language.

In our pattern we say have a “btn_blue” that has states like “btn_blue_normal” “btn_blue_over” “btn_blue_down” then the name of the texture would be just “blue”

As I mentioned earlier, this approach also rigid.
Imagine you have same Button class for 2 games, one of them are mobile game and you don’t need hover state.
In order to make this work you have to refactor Button class to not use this hover state. Or even in same game you can have two types of buttons, with and without some state.
There are plenty of diferent cases, and for ech one you have to fix some code.
And many of this trivial problems could be solved by simple check if texture exists.

Also it would be a great if I could create this texture name patterns by concatenating (“id”/ or current texture) of node with some strings.
This will allow to change textures for buton without touchin any part of code.

1 Like

You want to create some kind of generic button class that can handle different kinds of buttons and be designer friendly at the same time. Where do you draw the line here? When is the button class too hard to use for a designer/non-programmer.

Is it the designer that calls Button.new(node_name)? Could you add some way for the designer to decide available states and still keep it designer-friendly?

-- state config - maps button states to images in an atlas
-- normal state from gui.get_flipbook(node_name)
local blue_hover_button = {
	hover = "btn_blue_hover",
	down = "btn_blue_down"
}
Button.new(node_name, blue_hover_button)

local green_button = {
	down = "btn_green_down"
}
Button.new(node_name, green_button)

The above doesn’t feel that bad tbh. And if you really want to guard against a mismatch between state and images in the atlas you can probably catch the error and handle it in your button class:


local function update_button_state(node, anim)
	local ok, err = pcall(function()
	    gui.play_flipbook(node, anim)
	end)
	if not ok then
		-- failed to set anim
	end
end

1 Like

I think what he means is letting the designer pick the starting texture/button animation within the GUI editor itself, and then having the button code detect that starting texture and use that instead of having to set the label in the code.

that’s would be the perfect case!

I have tried this, but after 4th call, application window simple closes.

I guess, I’ll stick with some layout_config.lua module.
Where I can specify textures for buttons.

LayoutConfig = {
  [hash("play_btn")] = {
    up_state = hash("play_up"),
    down_state = hash("play_down"),
    hover_state = hash("play_hover"),
  }
}

Button class will try to find his one textures there.
this way you can put any texture for button without changing anything in main code.

There is an engine crash (not simply a script error) related to playing animations in GUIs which do not exist. I’ve seen it too.

1 Like

We’d like to get help reproducing this if possible so that we can fix it!

@avetissargsian can you share your project in the state where it closes on its own to @britzl ?

I will, but little bit later, not at home right now.

https://1drv.ms/u/s!AvNHx3c2-U6giSiQiIkBblWEKehE?e=GCCPDb - this one I just made for demonstration purposes

https://1drv.ms/u/s!AvNHx3c2-U6giSZ8BleJWKzEOnE2?e=AkAKHx - and this one is my old project I am trying to recreate with Defold

Behavior of pcall differs in this projects, first one remain running with corrupted texture, second are crushes.