How to do an interactive tactile gui? (SOLVED)

(sorry for my english)

Hi, i’m trying to make a mobile game with a gui for “pause” and other menu setting…
I want that when the player touch the button “pause” on the right corner the game pause but everywhere else if he touch the screen the menu “pause” don’t open but only the character jump ? Sorry if what i mean isn’t not really clear

Hi @nathan68560!

In our examples section you can find a gui button example which demonstrates the two scenarios: clicking a button, and clicking outside a button which seems to be what you need in your case.

I believe this example is a good start for what you are doing. And feel free to ask more questions if anything is unclear or if you need more help with the code!

6 Likes

Oh yeah thanks that’s what i was looking for !

2 Likes

So here’s my code for my gui_script but when i try it it doesn’t work !

function init(self)

        self.score = 0
        self.GameOver = false
        self.pause = false
		self.score_node = gui.get_node("coin")
		self.game_over = gui.get_node("game_over")
		self.retry = gui.get_node("retry")
		msg.post("#", "acquire_input_focus")
		msg.post("#gameproxy", "load")
end

function final(self)
	msg.post(".", "release_input_focus")
end

function on_message(self, message_id, message, sender)
	if message_id == hash("add_coins") then
		self.score = self.score + 20
		gui.set_text(self.score_node, tostring(self.score))
	elseif message_id == hash("game_over") then
		self.GameOver = true
	elseif message_id == hash("proxy_loaded") then
		msg.post(sender, "enable")
	end
end

function update(self)
	if self.GameOver == true then
		gui.set_text(self.game_over, tostring("GAME OVER"))
		gui.set_text(self.retry, tostring("Touch to retry !"))
	else
		gui.set_text(self.game_over, tostring(""))
		gui.set_text(self.retry, tostring(""))
	end
end

function on_input(self, action_id, action)
    if action_id == hash("touch") and action.pressed then 
        local button = gui.get_node("button")
        if gui.pick_node(button, action.x, action.y) and self.pause == false then 
            self.pause = true
            msg.post("#gameproxy", "set_time_step", {factor = 0, mode = 1})
        else
            self.pause = false
            msg.post("#gameproxy", "set_time_step", {factor = 1, mode = 1})
        end
    elseif action_id == hash("escape") and action.pressed and self.pause == false then 
            self.pause = true
            msg.post("#gameproxy", "set_time_step", {factor = 0, mode = 1})
        else
            self.pause = false
            msg.post("#gameproxy", "set_time_step", {factor = 1, mode = 1})
    end
end

The final else statement will be run every time you get input that isn’t matched by the conditionals above. The indentation is wrong and that might be what is confusing you?

1 Like

I have change that :

function on_input(self, action_id, action)
    if action_id == hash("touch") and action.pressed then 
        local button = gui.get_node("pause")
        if gui.pick_node(button, action.x, action.y) and self.pause == false then 
            self.pause = true
            msg.post("#gameproxy", "set_time_step", {factor = 0, mode = 1})
        else
            self.pause = false
            msg.post("#gameproxy", "set_time_step", {factor = 1, mode = 1})
		end
    elseif action_id == hash("escape") and action.released and self.pause == false then 
            self.pause = true
            msg.post("#gameproxy", "set_time_step", {factor = 0, mode = 1})
    elseif action_id == hash("escape") and action.released and self.pause == true then 
            self.pause = false
            msg.post("#gameproxy", "set_time_step", {factor = 1, mode = 1})
	end
end

but now when i try build my project i have an error message :
java.lang.AssertionError: Assert failed: Cycle detected on node type editor.collection/CollectionNode and output :build-targets
(not (contains? (:in-production ctx) [node-id label]))

What if you restart the editor? Same problem?

Yes i already try to restart the editor (and i just download the new Defold 2 update of today) but it still doesn’t work when i try to build the game

Hmm, it seems like you might have a collection referencing itself. Did you change the #gameproxy by any chance? Please feel free to share the project with me (bjorn.ritzl@king.com) and I can take a look.

In the collection field of my gameproxy i have referenced the “level1. collection” and the gameproxy is in this collection… I now have change that and put the gameproxy and hud object in the main.collection but now when i build the game and pause, all of the level duplicate itself and 1 is mooving and the other no

It’s hard to tell what’s wrong based on the screenshot, but I’ll gladly take a look if you want to?

Here’s a link to download my project if u want to take a look :
new : https://ufile.io/rj9h1

Hmm, but where is your #gameproxy? I can’t find it. A recommended structure could be:

controller.collection
menu.collection
level1.collection
level2.collection

The controller.collection should be your bootstrap collection and have proxies to menu, level1, level2 etc

The controller collection should be the one responsible for loading and unloading the other collections based on the game state.

An example of this can be seen here: https://github.com/britzl/publicexamples/tree/master/examples/menu_and_game

1 Like

Hey thanks for the help, i have done what you tell me, but now i have 2 more problems :

  • when i try the game on my smartphone (Honor 8 on android 7.0) the game don’t do anything when i touch the screen…
  • when i’m in the game it first load the controller.collection who load then the level1.collection but when i’m into this collection i can’t go back in the controller.collection or load the menu.collection

Here’s my project if you want : https://ufile.io/hbt0e

I saw that you have multi-touch bound in your game input bindings. Have you set up your input to actually handle multi touch? It’s a bit different from single touch in the way the touch points are sent in the action in on_input. If you only need single touch then my recommendation is to remove the multi-touch binding and instead set a binding on MOUSE_BUTTON_1 and bind that to action touch. This will translate to single touch on mobile.

Yes thank you now it’s work on my smartphone but have you any idea for the problem to load the menu.collection when i’m in the level1.collection ? In the console it show me this : ERROR:GAMEOBJECT: Instance ‘/controller’ could not be found when dispatching message ‘show_menu’ sent from level1:/InGame#gui

Could you please post the line where you are doing a msg.post() back to the controller?

Sorry for the late response, and thanks dor the help !

Now it’s good i just found the problem, i have forgot to rename a go :sweat_smile:
All work fine now !

(sorry for my english)

1 Like