QUEUE free a number.

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

There are random numbers in a puzzle game.How can i queue free a number if the sum of any two numbers ( for example 5+7 = 12) and in the random numbers if there is a number 12 .If both are same how to queue free them ?

This question doesn’t make sense. queue_free() is a function of Node. Can you explain a little more what you’re trying to do?

kidscancode | 2019-07-10 15:33

There are random numbers like 1,2,3,4,5…If i first select 1 and then 2 .After selecting 2 if I select 3 ; the numbers 1, 2 and 3 should be hidden as the sum of 1 and 2 is 3. Instead of selecting 3 if i select 4 nothing should happen.

THE HELIX | 2019-07-10 17:24

How are you storing the random numbers? Are they stored in an array and are shown on different nodes? If so you can assign the selected node’s numbers to variables and check if the number they add up to is in the array then queue_free() the selected nodes.

Magso | 2019-07-10 21:35

the numbers are of kinematic body 2D and I attached a TouchSceenButton(Hex) to them .I added the code like

 extends KinematicBody2D

 var number = range(-3, 22)[randi()%range(-3, 22).size()]
 
 func _ready():
  randomize()
      $Label.text = str(number)

 func _on_Hex_pressed():
       var B = int(str(number))
       Hex.A +=  B
       if Hex.A :
	      number
	      queue_free()

Here the Hex is an autoload script

   var A = int()

When execute it the selected numbers are added to the previously selected numbers and are printed in the output.How can i queue_free selected numbers if their sum is a number and that number is already present in the random numbers. i.e if i press 5 and 7 their sum is 12 . After 7 if i press 12 the three numbers 5,7 and 12 shoud be queue_freed.

THE HELIX | 2019-07-11 13:06

If you’re wanting to remove the numbers from the number array you can use array.erase. So if first number + second number = third number, use array.erase for all three of them.

Magso | 2019-07-11 15:33

As I am new in coding ; Can you please explain how to do it ?

THE HELIX | 2019-07-12 15:54

I personally wouldn’t use an autoload script. I would have an array for ints that are set as the selected numbers, and put all the buttons in a group called “Buttons” to access them and give them a RichTextLabel each. This script can go on the parent node with the hex button signals connected to it.

var number = range(-3, 22)[randi()%range(-3, 22).size()]
var number_array : Array
#An array to reference the button nodes to queue free them.
var selectedButtons : Array
onready var buttons = get_tree().get_nodes_in_group("Buttons")

func _ready():
    #assign numbers to labels.
    for index in number.size():
        buttons[index].get_node("RichTextLabel").text = str(number[index])

func _on_Hex_pressed(button):
    if number_array.empty( ):
        number_array[0].append(int(button.get_node("RichTextLabel").text))
        selectedButtons.append(button)
    elif number_array.size() < 2:
        number_array[1].append(int(button.get_node("RichTextLabel").text))
        selectedButtons.append(button)
    else:
        if number_array[0] + number_array[1] == int(button.get_node("RichTextLabel").text):
            number.erase(number_array[0])
            number.erase(number_array[1])
            number.erase(int(button.get_node("RichTextLabel").text))
            selectedButtons[0].queue_free()
            selectedButtons[1].queue_free()
            button.queue_free()
    selectedButtons.clear()
    number_array.clear()

Magso | 2019-07-12 16:44

Thanks for helping me out.When I execute the code i get a error
" Invalid call. Nonexistent function ‘size’ in base ‘int’. "
How to solve it ?

THE HELIX | 2019-07-13 15:51

Ah, I missed that. I thought number was an array not an int. If you change it so number is an array of numbers it should work.

var number : Array
...
func _ready():
    while number.size() < rand_range((lowest amount), (highest amount)):
        number.append(randi()%22+-3)

Magso | 2019-07-13 19:34

Should I add " while number.size() < rand_range((lowest amount), (highest amount)): " in the code ?

THE HELIX | 2019-07-13 19:51

I put lowest amount and highest amount where you need to put how little or many numbers there can possibly be.

Magso | 2019-07-13 20:37

I added it and executed it.The numbers are shown but on pressing the numbers it is showing an error at the “else” of ’ func _on_Hex_pressed(button): ’ . The error is
" Invalid call. Nonexistent function ‘get_node’ in base ‘Array’. "
How to solve it ?

THE HELIX | 2019-07-14 15:56

Is there a line number? I can’t see where I’ve used array.get_node() which wouldn’t work because get_node needs a directory from the referenced node before it.

Magso | 2019-07-14 22:07

I haven’t used array.get_node() but I still get the error . The code is as shown

 extends KinematicBody2D
 onready var buttons = get_tree().get_nodes_in_group("Buttons")
 var number : Array
 var number_array : Array
 var selectedButtons : Array
 func _ready():
     randomize()
     number.size() < rand_range(-3, 22)
     number.append(randi()%22+-3)
     for index in number.size():
	     buttons[index].get_node("Label").text = str(number[index])

 func _on_Hex_pressed():
     if number_array.empty( ):
	     number_array[0].append(int(buttons.get_node("Label").text))
	     selectedButtons.append(buttons)
     elif number_array.size() < 2:
	     number_array[1].append(int(buttons.get_node("Label").text))
	     selectedButtons.append(buttons)
     else:
	     if number_array[0] + number_array[1] == int(buttons.get_node("Label").text):
		     number.erase(number_array[0])
		     number.erase(number_array[1])
		     number.erase(int(buttons.get_node("Label").text))
		     selectedButtons[0].queue_free()
		     selectedButtons[1].queue_free()
		     buttons.queue_free()
     selectedButtons.clear()
     number_array.clear()

Can you please tell me where i have done a mistake ?

THE HELIX | 2019-07-15 15:20

You have used buttons.get_node() and buttons is an array returned by get_nodes_in_group(). You need a parameter in the signal function
func _on_Hex_pressed(>here<): and use that instead of the array. Here’s a question posted about getting the node that calls a signal function.

Magso | 2019-07-15 21:47

I added " func _on_Hex_pressed(which) " .On clicking the numbers the numbers are not added and I get an error
E 0:00:08:0165 Error calling method from signal ‘pressed’: ‘KinematicBody2D(Circle.gd)::_on_Hex_pressed’: Method expected 1 arguments, but called with 0.
Can you please show how to code the " _on_Hex_pressed " signal.

THE HELIX | 2019-07-17 15:08

Have you changed the rest of the code too? Where you have int(buttons.get_node("Label").text) needs to be int(which.get_node("Label").text) because which is now the parameter name.
Also, just noticed I put number_array[0].append which only needs to be number_array.append for both of them, I mixed myself up when typing that :confused:

Magso | 2019-07-17 21:54

I put int(which.get_node(“Label”).text) and used number_array.append .Here is the code

func _on_Hex_pressed(which):
    if number_array.empty( ):
        number_array.append(int(which.get_node("Label").text))
        selectedButtons.append(buttons)
    elif number_array.size() < 2:
         number_array.append(int(which.get_node("Label").text))
         selectedButtons.append(buttons)
    else:
         if number_array[0] + number_array[1] == int(which.get_node("Label").text):
             number.erase(number_array[0])
             number.erase(number_array[1])
             number.erase(int(which.get_node("Label").text))
             selectedButtons[0].queue_free()
             selectedButtons[1].queue_free()
             buttons.queue_free()
     selectedButtons.clear()
     number_array.clear()

On clicking the numbers ; I get an error
E 0:00:08:0165 Error calling method from signal ‘pressed’: ‘KinematicBody2D(Circle.gd)::onHexpressed’: Method expected 1 arguments, but called with 0.
And the numbers are not added.
Can you please tell me where I am wrong ?

THE HELIX | 2019-07-18 15:15

That’s because the parameter isn’t declared. In this link wombatstampede connected the signal in _ready()

func _ready():
    for b in get_node("buttons").get_children():
        b.connect("pressed", self, "_button_pressed",[b])

You can use the buttons array to do this in your script, and create a variable to declare the parameter as the button the for loop is currently connecting.

var this_button

func _ready():
    for a_button in buttons.size():
       this_button = buttons[a_button]
       this_button.connect("pressed", self, "_on_Hex_pressed",[this_button])

Magso | 2019-07-19 18:14

Thanks I attached the code ; but when i execute I get an error for the line
this_button.connect(“pressed”, self, “_on_Hex_pressed”,[this_button]) the error is
" In Object of type ‘KinematicBody2D’: Attempt to connect nonexistent signal ‘pressed’ to method ‘KinematicBody2D._on_Hex_pressed’ ".

THE HELIX | 2019-07-20 15:12

The buttons array should have the touchscreenbutton nodes, so the pressed signal should exist. Is the signal still connected in the node tab? You won’t need it if the script is connecting it.

Magso | 2019-07-20 15:34

I got rid of the error but on pressing the numbers they are not adding up.When running the game all numbers are showing random numbers but when I press a number the next generated numbers are showing 1 after few seconds the 1 get’s changed to different random numbers .
Also I tried to see which numbers were added ; so attached print(number_array) at the end of the func _on_Hex_pressed(which): and on clicking the numbers I am getting empty
How to solve it ?

THE HELIX | 2019-07-20 16:33

Try print(int(which.get_node("Label").text)) do the numbers show up in output?

Magso | 2019-07-20 17:16

When running the game all Label are showing random numbers but when I press a number the next generated numbers are showing a number (1) after few seconds the 1 get’s changed to different random numbers .
Why is that happening ?

THE HELIX | 2019-07-20 19:44

It shouldn’t when the random numbers are being assigned in _ready are there any other scripts running that would cause this?

Magso | 2019-07-20 20:09

I added print but when I press a number ; in the output one number is printed twice or thrice.Can you please take a look at what I have done wrong in the project.

[ Here the circle is of kinematicbody 2D and I create a node to spawn the circles and How can I make the viewport as a container to hold the falling numbers]

THE HELIX | 2019-07-21 14:59

ok… I didn’t know the script was on the button itself, I thought the script was on a parent node that had the buttons as children. In this case the buttons only need the pressed signal to send the number to a parent node that adds them up. Also the random number can just be generated instead of appending a number array with random numbers and assigning them.

Basically have the button have a random number and when clicked, sends that number to another node that will keep count of how many buttons have been clicked and do the adding up. Here’s the code logic on a basic level.

#for button
var the_number = randi()%22+-3
onready var otherNode = (path to the node that adds the numbers up)

func _ready():
    $label.text = str(the_number)

func _on_hex_pressed():
    otherNode.numbers_to_add.append(the_number)
    otherNode.button_the_number_came_from.append(self)


#other node to add numbers up
var numbers_to_add : Array
var button_the_number_came_from : Array

func _process(delta):
    if numbers_to_add > 2:
        if numbers_to_add[0] + numbers_to_add[1] == numbers_to_add[2]:
            for index in button_the_number_came_from.size():
                button_the_number_came_from[index].queue_free()
        button_the_number_came_from.clear()
        numbers_to_add.clear()
        

Hopefully that makes sense :slight_smile:

Also may I suggest using a Camera2D so the game can be played at any aspect ratio.

Magso | 2019-07-21 22:51

I didn’t use onready var otherNode = () in the script instead I attached both the scripts to the Circle(Kinematicbody 2D) script.But I am getting an error at if numbers_to_add > 2: as " Parser Error: Invalid operand types (‘Array’ and ‘int’) to operator ‘>’. "

THE HELIX | 2019-07-22 14:53

Sorry I forgot to put .size() on the array. You cant put both scripts on the button because these are being instanced constantly. The button needs to know when it’s pressed and send it’s number. These should then be added in a node to manage the numbers.

Magso | 2019-07-22 16:54

Where should I add the script of other node to add numbers up , should I add it the Circle(Kinematicbody 2D) script or create a autoload script for it as the button node is the child of Circle

Another doubt ;How can I make the viewport as a container to hold the falling numbers. I had used move_and_collide with a few lines of code to make the numbers bound to the viewport but when the lower numbers are cleared they stick together and doesn’t fall down ? (the code for viewport is in the Circle script, can you please take a look at it or is there any other methods)

THE HELIX | 2019-07-22 18:08

The button signal should be connected to the script on ‘circle’. You could use an autoload script to add the numbers up or put the script on the parent of the instanced circles.

Magso | 2019-07-22 19:59

I used an autoload for the #other node to add numbers up.When I execute it the numbers are spawned and I click on a number.
The number which I pressed is shown in the output asthe_number .But on pressing the number I am getting an error at otherNode.numbers_to_add.append(the_number); as
Invalid get index ‘numbers_to_add’ (on base: ‘String’).

THE HELIX | 2019-07-23 14:44

On base string? There shouldn’t be a string, the types should be autoload.array, no string should exist.

Magso | 2019-07-23 15:33

I got rid of the error.I pressed the numbers ; when I press the second number there is an error at if numbers_to_add[0] + numbers_to_add[1] == numbers_to_add[2]: as Invalid operands ‘int’ and ‘Object’ in operator ‘+’.

THE HELIX | 2019-07-23 16:33

This if statement should happen after the third button is pressed. I think by ‘object’ it means that numbers_to_add[1] hasn’t been assigned any value.

Magso | 2019-07-24 23:29

It happens after the second button is pressed. If i put number_array.size() < 3 ; it happens after the third button is pressed.When I keep the mouse on numbers_to_add[0] or on numbers_to_add[1] it is showing which and all numbers were pressed instead of showing/assigning one number to numbers_to_add[0] and the other number in numbers_to_add[1]. How to solve it ?

THE HELIX | 2019-07-25 13:00

Array.append “appends an element at the end of the array.” if you print numbers_to_add it should output [int, int, int]

Magso | 2019-07-25 16:57

So should I replace Array by Array.append?

THE HELIX | 2019-07-25 18:36

No, append is a method of array. Each number should be added to the array.

Magso | 2019-07-25 19:36

I added print(numbers_to_add) . I get the output as

[]
[]
[]
[]

when I press a number I get the output as

[]
[]
[]
[18, [KinematicBody2D:3243]]
[18, [KinematicBody2D:3243]]
[18, [KinematicBody2D:3243]]

when I press the second number I get the output as

[18, [KinematicBody2D:3243]]
[18, [KinematicBody2D:3243], -1, [KinematicBody2D:3628]]
[18, [KinematicBody2D:3243], -1, [KinematicBody2D:3628]]
[18, [KinematicBody2D:3243], -1, [KinematicBody2D:3628]]
[18, [KinematicBody2D:3243], -1, [KinematicBody2D:3628]]

then when I press the third number I get the error as Invalid operands ‘int’ and ‘Object’ in operator ‘+’. for size < 4. How to solve it ?

THE HELIX | 2019-07-26 15:03

You’re adding the numbers and the circles to the same array, they need to be in seporate arrays.

Magso | 2019-07-28 00:05

How to seperate them?

THE HELIX | 2019-07-29 18:05

Make 2 arrays, assign the numbers to one and the circles to the other like in the example I gave you above.

Magso | 2019-07-29 20:24

I did as you told.I created a Add autoload script and attached the code like

extends Node

var numbers_to_add : Array

func _process(delta):
     if numbers_to_add.size() > 4:
	     if numbers_to_add[0] + numbers_to_add[1]  == numbers_to_add[2]:
		     numbers_to_add.clear()
     print(numbers_to_add)

then added the code to the Circle script as

extends KinematicBody2D

var the_number = randi()%22+-3
var button_the_number_came_from : Array

 func _process(delta):
      for index in button_the_number_came_from.size():
		  button_the_number_came_from[index].queue_free()
		  button_the_number_came_from.clear()

 func _on_Hex_pressed():
      Add.numbers_to_add.append(the_number)
      button_the_number_came_from.append(self)

The numbers are spawning.When I press the numbers the output is printed as [11, 13, 0] . and the pressed numbers are queue_freed and shown in the output ; instead of adding the selected numbers and clearing if the choosen number(answer) is right.
Can you please tell me where I did wrong in coding ?

THE HELIX | 2019-07-30 14:58

button_the_number_came_from should be in the autoload script.

Magso | 2019-07-30 15:38

I added the button_the_number_came_from to autoload .When i press the numbers I am getting the output as [18, [KinematicBody2D:3243], -1, [KinematicBody2D:3628]] and since number_array.size() < 3 after two times pressing the numbers I get the error as Invalid operands ‘int’ and ‘Object’ in operator ‘+’.
You had told to seperate the arrays but can you please show me how to seperate the arrays ?

THE HELIX | 2019-07-31 14:51

Do you have these lines in the circle’s script?

Add.numbers_to_add.append(the_number)
Add.button_the_number_came_from.append(self)

Magso | 2019-07-31 18:14

I had already added these lines in the circle’s script ; but I still get the error

func _on_Hex_pressed(): 
      Add.numbers_to_add.append(the_number)
      Add.button_the_number_came_from.append(self)

THE HELIX | 2019-08-01 13:57

And var button_the_number_came_from : Array is in the add script?

Magso | 2019-08-01 14:32

Yes I have added var button_the_number_came_from : Array in the add script ; but I still get the error

THE HELIX | 2019-08-01 14:42

But Add.numbers_to_add.append(the_number) should only add the numbers, [18, [KinematicBody2D:3243], -1, [KinematicBody2D:3628]] should only be [18, -1]. button_the_number_came_from should be [[KinematicBody2D:3243], KinematicBody2D:3628]].

Magso | 2019-08-01 15:02

If I add print(numbers_to_add) or print(button_the_number_came_from) to the add script ; I am getting same output for both print command’s as [18, [KinematicBody2D:3243], -1, [KinematicBody2D:3628]]. But since number_array.size() < 3 after two times pressing the numbers I get the error as Invalid operands ‘int’ and ‘Object’ in operator ‘+’. What may be the reason for the error ?

THE HELIX | 2019-08-01 15:19

Ok, I had no idea about This but “arrays haven’t been initialized. Therefore the content is undefined.” So the array vars have to be written like one of kidscancode’s examples. A crash from an undefined array issue is also on github.

Magso | 2019-08-01 16:46

I got rid of the error ; Now the numbers are adding up.
I got another doubt i.e I need to make the viewport as a barrier / a wall to hold the numbers.I put this code in the circle script

extends KinematicBody2D

var extents
var screensize
var pos
var velocity = Vector2()
var gravity = 50

func _ready():
      screensize = get_viewport_rect().size
      extents = $Sprite.get_texture().get_size() / 8
      pos = screensize / 8

func _physics_process(delta):
      velocity.y += gravity * delta
      position.y += velocity.y * delta
      move_and_collide(velocity * delta)
      pos += velocity * delta
      if pos.x >= screensize.x - extents.x:
	       pos.x = screensize.x - extents.x
	       velocity.x *= 0
      if pos.x <= extents.x:
	       pos.x = extents.x
	       velocity.x *= 0
      if pos.y >= screensize.y - extents.y:
	       pos.y = screensize.y - extents.y
	       velocity.y *= 0
      if pos.y <= extents.y:
	       pos.y = extents.y
	       velocity.y *= 0

When I execute it the viewport acts as a wall/barrier.But during spawning the numbers are held by the viewport wall.After some time more numbers fall . When the lower numbers are cleared the upper numbers do not come in the place of the cleared numbers but stay where they where and comes down only when more numbers fall on them.When I make velocity.y *= 1 and velocity.x *= 1 ; the numbers come down if the lower numbers are cleared.But when more numbers fall on them they pass through the collission body and fail to detect collissions .I even put staticbody around the viewport but they fail to detect collission.
I have put this code in the project . Can you please check it and help me out ?

THE HELIX | 2019-08-02 14:38

This needs to be posted as a new question. Related questions are ok but this is now jumping to another topic.

Magso | 2019-08-02 15:12

I added the project in failing to detect COLLISSION in godot . Can you please take a look at it ?

THE HELIX | 2019-08-22 16:15