[SOLVED] How to make an image appear and disappear on the same user input?

Hi,
I am trying to get a pause menu to appear when a user presses Esc and then disappears when they press it again. I am currently making use of the z-coordinates to make it appear when the user presses Esc by giving it a greater z-coordinate than anything else on the screen to make it appear above it, this still doesn’t work, but is there a way to make the pause screen spawn and despawn when the user presses Esc, rather than leaving it spawned in constantly and only seen when the user wants it?

--Initialises the local variables for player input command
local HASH_PAUSE = hash("pause_game")

function init(self)
	--Makes Defold listen to input action in the script
	msg.post(".", "acquire_input_focus")

	--Initialises Starting position
	go.set_position(vmath.vector3(514, 314, 0))
end

function on_input(self, action_id, action)
	--When the player presses Esc, the z-coordinate increases by 2
	if action_id == HASH_PAUSE then
		if action.pressed then
			go.set_position(vmath.vector3(514, 314, 2))
			--When the player presses Esc again, the z-coordinate decreases by 2
			if action_id == HASH_PAUSE then
				if action.pressed then
					go.set_position(vmath.vector3(514, 314, 0))
				end
			end
		end
	end
end

Yes, the way you’ve laid out your script won’t work. Think about why that is.

Your second check for the pause button being pressed only happens when the condition is already true.

Stripping out the rest of your code, effectively this is what you are doing:

if action_id == HASH_PAUSE then
    if action_id == HASH_PAUSE then

   end
end

This means that the z position will always be set to 0.

I’d recommend using a flag to toggle the state. For example, in init I would put:

self.pause_menu_hidden = true

In your input function, only check for the button press once. If the button is pressed, make a conditional statement. If the flag says the pause menu is hidden, then set the z position to 0 and change the flag to false. If the flag says the pause menu is visible, then set the z position to 2 and change the flag to true.

5 Likes

I tried using different inputs for opening and closing the pause menu and that still didn’t work when I tried it, but I did what you said and now it just crashes.
Is this what you meant:

self.pause_menu_hidden = false
function on_input(self, action_id, action)
	--When the player presses Esc, the z-coordinate increases by 2
	if self.pause_menu_hidden == false then
		if action_id == HASH_PAUSE then
			if action.pressed then
				go.set_position(vmath.vector3(514, 314, 2))
				self.pause_menu_hidden = true
			end
		end
		--When the player presses Esc again, the z-coordinate decreases by 2
	elseif self.pause_menu_hidden == true then
		if action_id == HASH_PAUSE then
			if action.pressed then
				go.set_position(vmath.vector3(514, 314, 0))
			end
		end
	end
end

And thank you for helping me btw

Does it just crash without an error? If there’s an error then that is really informative and helps solve the issue.

Few things to check:

  1. Does the pause menu start hidden? If so, the initial declaration should be:
self.pause_menu_hidden = true
  1. Did you put the declaration of the flag inside the init(self) function? You’ve pasted it in the thread but it’s not clear where in your script it resides.

  2. In the second half of your on_input function, you never actually set the flag to false again.

  3. I think it would be better if you switched the order of your conditionals. Currently you’ve got if flag → if action_id → if pressed. I would make it if action_id → if pressed → if flag. As it stands, your script will be evaluating the pause flag every time any input happens (including if you move your mouse).

None of the above issues that I can see should result in a crash, though.

2 Likes

When it crashed it gave no error, but now that I have changed the code to what you said and now it doesn’t crash, but it still doesn’t appear when I press escape.

function init(self)
	self.pause_menu_hidden = true
	
	--Makes Defold listen to input action in the script
	msg.post(".", "acquire_input_focus")

	--Initialises Starting position
	go.set_position(vmath.vector3(514, 314, 0))
end

function on_input(self, action_id, action)
	--When the player presses Esc, the z-coordinate increases by 2
	if action_id == HASH_PAUSE then
		if self.pause_menu_hidden == true then
			if action.pressed then
				go.set_position(vmath.vector3(514, 314, 2))
				self.pause_menu_hidden = false
			end
		end
	--When the player presses Esc again, the z-coordinate decreases by 2
	elseif action_id == HASH_PAUSE then
		if self.pause_menu_hidden == true then
			if action.pressed then
				go.set_position(vmath.vector3(514, 314, 0))
				self.pause_menu = true
			end
		end
	end
end
1 Like

That doesn’t look right?

1 Like

Indeed, that part isn’t right. Furthermore, your if statements aren’t structured right. Read my previous suggestion again and try to implement that.

I like to try and read through the logic in words. What you’ve said is:

“Is the pause button pressed? If not, is the pause button pressed?”

You see how that doesn’t make sense.

What you want to do is establish that the pause button is pressed and that the action.pressed variable is true. At that point you do all the pause stuff.

Ok thank you

Sorry mate but I have spent hours looking at the code and it still won’t work, I don’t want to bother you, but is he logic of the code sound? I tried to implement monarch into it and I couldn’t figure it out either.
Thanks

local monarch = require "monarch.monarch"

function init(self)
	self.pause_menu_hidden = true
	
	--Makes Defold listen to input action in the script
	msg.post(".", "acquire_input_focus")

	--Initialises Starting position
	go.set_position(vmath.vector3(514, 314, 0))
end

function on_input(self, action_id, action)
	if action_id == hash("pause_game") then
		if action.pressed then
			if self.pause_menu_hidden == true then
				go.set_position(vmath.vector3(514, 314, 2))
				--monarch.show(pause_screen)
				self.pause_menu_hidden = false
			elseif self.pause_menu_hidden == false then
				go.set_position(vmath.vector3(514, 314, 0))
				--monarch.back(pause_screen)
				self.pause_menu_hidden = true
			end
		end
	end
end	
1 Like

Nice work, it looks like what I suggested. Shame it doesn’t work! Next step is debugging! What actually happens? How does this behave?

A basic debugging method is sprinkling print() here and there to see what happens (and what doesn’t happen). I’d put prints to confirm:

  • That the pause button is pressed
  • That either of the pause actions happen
  • What the position of the pause menu is at the end of the input action
1 Like

I added the print()'s in like you said, and the loops conditions work perfectly, the code comes in and out of each if statement perfectly and according to the printed coordinates, the image is also moving perfectly but it still isn’t showing properly.
I have the blend mode of the image set to alpha and I am not really sure where to go from here.

Thank you so much for your help, it is greatly appreciated.

function on_input(self, action_id, action)
	if action_id == hash("pause_game") then
		if action.pressed then
			if self.pause_menu_hidden == true then
				print("Pause Initially Pressed")
				go.set_position(vmath.vector3(514, 314, 10))
				print(go.get_position())
				self.pause_menu_hidden = false
			elseif self.pause_menu_hidden == false then
				print("Pause Pressed Again")
				go.set_position(vmath.vector3(514, 314, 0))
				print(go.get_position())
				self.pause_menu_hidden = true
			end
		end
	end
end	```

Can you share a screenshot? Also what do you expect it to look like?

Its just a simple bad game, but the an image is supposed to show in the centre when I press Esc. From the prints I know that the image is moving to a z-coordinate that is above all the others, and then moving back perfectly again, but I cannot see it when this happens.

I know the conditions work properly and the image is moving, but its just not visible.

image

Oh, I thought the z position of 2 or 10 was supposed to be the pause menu hidden. Not sure you’re aware of this but with a default render script, only objects with a z position of -1 to 1 are visible.

If you have a default render script, I would do something like put the pause menu at -10 for hidden, and 1 for visible.

Beyond that, I would look into the GUI system, as that is likely more appropriate for your pause menu.

Thank you that works perfectly, I think I will try to use the GUI system when I try to make the buttons work.

Thanks for your help mate.

3 Likes