Generating TextureButtons that move differently around the board when they are clicked at specific locations

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

First of all… i’m not very experienced and my code will probably look like spaghetti, so don’t expect me to be very intelligent and understand everything in an instant.

This is the singleton i have to use because i’m loading decks from the main menu,
“VariableDatabase.gd”

var dir = Directory.new()
var files = dir.list_dir_begin()
var CardsPath = "res://cards/"
var DecksList = Array()
var DecksOnPlay = Array()
var CardsOnPlay = Array()
var CardCount = 30

then i have this setup and it works but the only thing i can’t wrap my head around is how the hell do i assign every TextureButton to its unique object.

var CardSprite = TextureButton.new()
var CardSpriteCount = 0
var CardsOnPlayArea = Array()
var CardsOnDiscardPile = Array()

var OnPlayAreaPosition = Vector2(480, 50)
var DiscardPilePosition = Vector2(900, 50)

func _on_DeckButton_pressed():
	CardSpriteCount += 1
	var random_card = VariableDatabase.CardsOnPlay[randi() % VariableDatabase.CardsOnPlay.size()]
	if VariableDatabase.CardsOnPlay.size() > 0:
		VariableDatabase.CardsOnPlay.erase(random_card)
		$CardsOnPlayNode.add_child(CardSprite)
		CardSprite.set_position(OnPlayAreaPosition)
		CardSprite.texture_normal = load(random_card)
		CardSprite.texture_focused = load(random_card)
		CardSprite.texture_pressed = load(random_card)
		CardSprite.name = (str(CardSpriteCount, "_") + random_card.get_slice("/", 4))
		CardSprite.connect("pressed", self, "_on_pressed", [CardSprite])
		print(CardSprite.name)
	else:
		pass

func _on_pressed(CardSprite):
	print("You clicked me!")
	var CardSpritePosition = CardSprite.get_position()
	if CardSpritePosition == OnPlayAreaPosition:
		CardSprite.set_position(DiscardPilePosition)
	elif CardSpritePosition == DiscardPilePosition:
		CardSprite.set_position(OnPlayAreaPosition)
	else:
		pass

What i mean is that, i draw 1 card from deck and place it on “OnPlayAreaPosition” and if i click it while its on that position then it gets transferred to “DiscardPilePosition”
But here’s the thing, if i draw another one and press any of them then they become one and all but one disappears, i know why it happens, i just can’t comprehend how to find a workaround for it.

i need to find a way to call “CardSprite” uniquely associated with every generated TextureButton.

:bust_in_silhouette: Reply From: zhyrin

Instead of declaring CardSprite early, you should do so in the _on_DeckButton_pressed() function, when you already determined you could draw a card. This way, every time you draw a new card, you create a new button for it.

If you need to keep references to the created buttons, you could keep them in an array, dictionary or whatever data structure.

Btw, your _on_pressed() function takes a parameter with the name CardSprite, this is called variable overshadowning (you already have a member variable named CardSprite), this is a bad practice.

But if you remove the CardSprite declaration from the class, the function parameter can stay as is.

zhyrin | 2023-03-07 08:11

If i declare CardSprite in _on_DeckButton_pressed() how do i call it in _on_pressed() ? That way it gives me The identifier "CardSprite" isn't declared in the current scope.

mehmet432 | 2023-03-07 10:58

When you connect the signal, you pass it as a bound argument, so the same way you do it now.

zhyrin | 2023-03-08 07:15

Thanks, it works yeah, sorry i’m dumb

Another question, i can’t see any z_index values on the TextureButton node, is there a way to make it go on top when it’s clicked ?

Or do i really have to create a Node2D or CanvasLayer as a parent to all of them to control that ?

Edit: in other words, i don’t want them to “retain” their z_index

Edit: It took me some time but i ended up figuring out a way, if anyone needs it feel free to use it in the future.

func _on_OnPlayLeftArrow_pressed():
	if $CardsOnPlayAreaNode.get_child_count() > 0:
		var amount_of_cards_on_play_area = $CardsOnPlayAreaNode.get_child_count()
		var highest_card = $CardsOnPlayAreaNode.get_child(amount_of_cards_on_play_area - 1)
		$CardsOnPlayAreaNode.move_child(highest_card, 0)
	else:
		pass

i have cards on a playspace and when you press arrow keys to cycle between them, it takes the highest priority one in the “CardsOnPlayAreaNode” and sends it down.

mehmet432 | 2023-03-08 13:04