I am trying to create a DOMINO game, and to do this I've been created a main/principal scene and another scene using TextureButton as root. After that, I created many inherited Scenes using the TextureButton to represents stones in the DOMINO game.
It works well, but now I need to get values from the inherited scenes when the TextureButton is on pressed. I've already created the signal _on_pressed()
, and I'm able to see the values inside of the TextureButton scene, but I don't know how could I get this value in the principal scene. I've tried to create a Global Group, but I don't know how can I get the values.
How could I access or read the TextureButton's values in the principal scene's script?
Below are the scripts for both the principal scene and TextureButton scene.
class_name PrincipalScene extends Node2D
##CONFS
@export_category("Pedras Domino")
@export var _pedras = [
preload("res://DominoX/pedras/0_0.tscn"),
preload("res://DominoX/pedras/0_1.tscn"),
preload("res://DominoX/pedras/0_0.tscn"),
preload("res://DominoX/pedras/0_1.tscn"),
preload("res://DominoX/pedras/0_0.tscn"),
preload("res://DominoX/pedras/0_1.tscn"),
preload("res://DominoX/pedras/0_0.tscn"),
preload("res://DominoX/pedras/0_0.tscn"),
preload("res://DominoX/pedras/0_1.tscn"),
preload("res://DominoX/pedras/0_0.tscn"),
preload("res://DominoX/pedras/0_1.tscn"),
preload("res://DominoX/pedras/0_0.tscn"),
preload("res://DominoX/pedras/0_1.tscn"),
preload("res://DominoX/pedras/0_0.tscn"),
preload("res://DominoX/pedras/0_0.tscn"),
preload("res://DominoX/pedras/0_1.tscn"),
preload("res://DominoX/pedras/0_0.tscn"),
preload("res://DominoX/pedras/0_1.tscn"),
preload("res://DominoX/pedras/0_0.tscn"),
preload("res://DominoX/pedras/0_1.tscn"),
preload("res://DominoX/pedras/0_0.tscn"),
preload("res://DominoX/pedras/0_0.tscn"),
preload("res://DominoX/pedras/0_0.tscn"),
preload("res://DominoX/pedras/0_1.tscn"),
preload("res://DominoX/pedras/0_0.tscn"),
preload("res://DominoX/pedras/0_1.tscn"),
preload("res://DominoX/pedras/0_0.tscn"),
preload("res://DominoX/pedras/0_1.tscn")
]
var _rng = RandomNumberGenerator.new()
@export_category("PANELS")
#@export var _panel_topo: GridContainer
#@export var _panel_bottom: GridContainer
#@export var _panel_left: VBoxContainer
#@export var _panel_right: VBoxContainer
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
_rng.randomize()
_spawn_random_object()
func _process(_delta: float) -> void:
pass
func _spawn_random_object():
#SELECT THE STONES
while(_controle.size() < _pedras.size()):
var _random_index = _rng.randi() % _pedras.size()
if(!self._controle.has(_random_index)):
self._controle.append(_random_index)
#GET THE STONES 7 EACH 7
var _topo = _controle.slice(0,7)
var _bottom = _controle.slice(7, 14)
var _left = _controle.slice(14, 21)
var _right = _controle.slice(21, 28)
#INSTANCE STONES
for i in _topo.size():
$PanelTop/Top.add_child(self._pedras[i].instantiate())
for i in _bottom.size():
$PanelBottom/Bottom.add_child(self._pedras[i].instantiate())
for i in _left.size():
$PanelLeft/Left.add_child(self._pedras[i].instantiate())
for i in _right.size():
$PanelRight/Right.add_child(self._pedras[i].instantiate())
class_name Stone extends TextureButton
@export_category("Confs")
@export var _valor: int
@export var _index: Array[int]
var _click_stone: bool = false
#STONE VALUE RETURNS
func get_valor_pedra() -> int:
return _valor
#STONE INDEX VALUE RETURNS
func get_index_pedra() -> Array[int]:
return _index
#STONE WAS CLICK
func get_click_stone() -> bool:
return _click_stone
func _on_pressed() -> void:
print("Stone Click Value: " + str(get_valor_pedra()))
print("Stone Click Array Values" + str(get_index_pedra()))
self._click_stone = true
self.get_valor_pedra()
self.get_index_pedra()
self.get_click_stone()
print("Click Stone: " + str(self._click_stone))
func _on_button_up() -> void:
self._click_stone = false
print("Click Stone: " + str(self._click_stone))
It seems like you are trying to have a scene broadcast information to its parent. A handy phrase to remember is "Call down & signal up." The gist being that it is best practice for a node to use something like get_node(...).dostuff(...)
to interact with its children, and to use signals to interact with its parents.
I found this article helpful when learning this.
So, a solution to your problem is to create a signal upon a texturebutton press that passes a number, and connect the signal to the principal scene. Luckily, buttons already have a signal that occurs on pressing the texturebutton, so you just have to modify the signal to also pass a value. Essentially, the easiest way to do this is to create a new signal that gets triggered by, and replaces, the old signal.
First, connect the pressed()
signal from the texturebutton to itself. [click on texturebutton scene, then go to Node tab -> Signals tab -> right click pressed() -> connect -> choose texturebutton] This will create a _on_pressed()
function. Create a new signal, domino_pressed(n)
, and have it passed in the body, as shown below.
# in button's script
...
signal domino_pressed(n)
func _on_pressed() -> void:
domino_pressed.emit(_valor)
...
Second, just connect the new signal to your principal node. [click on texturebutton scene, then go to Node tab -> Signals tab -> right click domino_pressed() -> connect -> choose principalscene] This will create a _on_domino_pressed(n)
function. Now, do whatever you want with the value, as it has been safely passed to the principal scene.
# in principal scene script
...
func _on_button_pressed_with_val(n) -> void:
print("The value of that domino was %s !" %n)
...
Signals are powerful and widely useful, once you learn when to implement them into your projects. Don't forget that the parameters passed with a signal can be anything, including info on the node itself- so you can identify and remember what nodes shared which signals when.