How to avoid multiple button pressed signal calls?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By jim

Hello everyone!

I’ve been working on a business simulator game, menu based, and i’ve come across an unusual problem:
I have a main node (called “Game”), that instantiates diferent screens acoording to a function called from each of its children. The problem happens when i press the TouchScreen button from inside one of the children, I’ve noticed it calls the function several times, and i end up with multiple screens instantiated on top of each other.

Here goes a sample of my code:

Game:

extends Node
export(PackedScene) var scr_title
export(PackedScene) var scr_main
export(PackedScene) var scr_patrimony
export(PackedScene) var scr_store
var screens = [scr_title, scr_main, scr_patrimony, scr_store]

enum GAME_STATE{
	title,
	main,
	patrimony,
	store
}

func _ready():
	show_all_assets()
	if scr_title != null:
		#Goes to the first screen of the game!
		var newest_screen = scr_title.instance()
		add_child(newest_screen)
		pass
	pass

func _process(delta):
	if Input.is_action_just_pressed("ui_left"):
		print("Child Number:")
		print(get_child_count())
	pass

func _change_screen_to(_destination):
	#Function called by all its children. Should change the current screen of the game the destination
	if _destination == GAME_STATE.title: #Change to Title Screen
		print("Change to TITLE")
		pass
	elif _destination == GAME_STATE.main: #Change to Main Screen
		print("Change to MAIN")
		#Ok! Here is where the magic should begin.
		var newest_screen = scr_main.instance()
		add_child(newest_screen)
		last_screen = GAME_STATE.main
		pass
	elif _destination == GAME_STATE.patrimony: #Change to Patrimony Screen
		print("Change to PATRIMONY")
		var newest_screen = scr_patrimony.instance()
		add_child(newest_screen)
		last_screen = GAME_STATE.patrimony
		pass
	elif _destination == GAME_STATE.store: #Change to store Screen
		print("Change to STORE")
		var newest_screen = scr_store.instance()
		add_child(newest_screen)
		last_screen = GAME_STATE.store
		pass
	else:
		print("Ok something went wrong here....")
	pass

And from one of the screens:

MainScreen

extends Node2D

func _ready():
	pass

func _process(delta):
	pass
func _enter_tree():
	pass

func _on_StoreButton_pressed():
	pass # replace with function body


func _on_InventoryButton_pressed():
	pass # replace with function body


func _on_ExitButton_pressed():
	pass # replace with function body


func _on_StoreButton_released():
	get_parent()._change_screen_to(get_parent().GAME_STATE.store)
	queue_free()
	pass # replace with function body


func _on_InventoryButton_released():
	get_parent()._change_screen_to(get_parent().GAME_STATE.patrimony)
	queue_free()
	pass # replace with function body


func _on_ExitButton_released():
	get_tree().quit()
	pass # replace with function body

Even with the queue_free() function present, i still end up with 10 instances of diferent screens, one on top of the other. As you can see, i’ve tried using on_button_released signal, but still, the same problem appears.

Any solutions to elegantly solve the issue?

Thanks in advance!

:bust_in_silhouette: Reply From: happycamper

I’m not sure why your button presses would activate multiple times, but an easy way to work around your problem would be to keep track of the current screen, if the function to change the screen checks that the current screen and the new screen are the same then it should not run its code again. For example

if ( current_screen != new_screen):
    current_screen=new_screen
    change_screen(new_screen) # your function for changing scenes

Also I would put all this change scene code in a global script (singleton) if you aren’t doing that already