Hello.
I'm making an Arkanoid clone, and I'm having a issue in deleting some instantiated objects.
I have powerups that are generated when the ball collides with the blocks. Then the powerup falls, and after crossing a "deadzone", I want that specific node that crossed the zone to be deleted.

But I'm having issues in deleting the node that crossed in that instant. The problems I have encountered were it simply not being deleted; after being deleted the game crashes trying to create the next instantiated powerup (probably because the parent node was deleted, and not the child); just one powerup visible on the screen at the time (the previous one being deleted when the ball hits the next block and creating the next one, before even going on the deadzone)

One thing I suspect is that the function for creating the instantiated powerups is inside a function I created, and I can't access the instantiated variable from outside to call a queue_free(), and as I said, calling queue_free() with the way my code is structured crashes the game when the next powerup is created.

I'm also using remove_child but it doesn't delete it, so I'm a bit lost.

This is the code I'm using for the powerup:


const pwupdouble = preload("res://actors/double.tscn")

func _ready() -> void:
	add_to_group('powerups')
	set_meta('double', true)
	
#func _physics_process(delta):
#	velocity.y += gravity * delta
#	position.y += velocity.y * delta

func spawn_double_powerup():
	var powerupdouble = pwupdouble.instance()
	powerupdouble.position.x = get_parent().get_node("Ball").ballposition.x
	powerupdouble.position.y = get_parent().get_node("Ball").ballposition.y
	add_child(powerupdouble)
	print(powerupdouble.position)

func _on_Area2D_area_entered(area):
	get_parent().get_node("Pwupdouble").remove_child(self)
	#queue_free()
	print('count', get_child_count())
  • xyz replied to this.
  • pedrohfmg My main suggestion would be to start with something a bit more simple than arkanoid until you get a better grip on how instancing and signals work.

    I've rearranged it slightly as suggested above, so take a look:

    arkanoid.zip
    49kB

    pedrohfmg Who generates the powerups? This code looks like at the same time generates powerups and also is a powerup. I'm guessing there's a problem with scene hierarchy/organization. You should show your scene setup to better communicate the problem.

      xyz It's the ball script, as it have the collision checks. It only calls the spawn powerup function when the ball collides with the block.

      I have some prints showing my project

      • xyz replied to this.

        xyz I'm very sorry, one of the images was repeated. There is a separate script for both.

        • xyz replied to this.

          pedrohfmg Images are too small to read the code. Please post both complete scripts as code snippets and a larger image with the scene structure.

            xyz

            Powerup Script

            const pwupdouble = preload("res://actors/double.tscn")
            
            func _ready() -> void:
            	add_to_group('powerups')
            	set_meta('double', true)
            	
            #func _physics_process(delta):
            #	velocity.y += gravity * delta
            #	position.y += velocity.y * delta
            
            func spawn_double_powerup():
            	var powerupdouble = pwupdouble.instance()
            	powerupdouble.position.x = get_parent().get_node("Ball").ballposition.x
            	powerupdouble.position.y = get_parent().get_node("Ball").ballposition.y
            	add_child(powerupdouble)
            	print(powerupdouble.position)
            
            func _on_Area2D_area_entered(area):
            	get_parent().get_node("Pwupdouble").remove_child(self)
            	#queue_free()
            	print('count', get_child_count())

            Ball Script

            var ballposition = Vector2.ZERO
            
            func _ready() -> void:
            	rngvel.randomize()
            	rngvel = rngvel.randf_range(-0.9, 0.9)
            	speed = 450
            	velocity.x = rngvel
            	velocity.y = -1
            
            func _physics_process(delta: float) -> void:
            	var collision = move_and_collide(velocity * speed * delta)
            	var newdir = position - $"../Player/Ancora".get_global_position()
            		
            	if collision:
            		velocity = velocity.bounce(collision.normal)
            		speed += 1
            		
            		if collision.collider.is_in_group('bricks'):
            			if collision.collider.get_meta('gb') or collision.collider.get_meta('bb'):
            				ballposition = position
            				collision.collider.hpdown()
            				get_parent().get_node("CanvasLayer/Points").ponctuation()
            				print(get_parent().get_node("CanvasLayer/Points").points)
            				$"../Pwupdouble".spawn_double_powerup()
            				
            			else:
            				collision.collider.queue_free()
            				
            		
            		if collision.collider.is_in_group('paddle'):
            			velocity = newdir.normalized()
            			#print(position)
            			#print(newdir)
            			#print($"../Player/Ancora".get_global_position())
            			#print(get_global_mouse_position())
            			
            func _on_Area2D_body_entered(body):
            	position = Vector2(480, 448)
            	velocity = Vector2(rngvel, -1)
            	speed = 0
            	yield(get_tree().create_timer(2.0), "timeout")
            	speed = 450

            I'm also uploading the entire project, in case is needed

            arkanoid.rar
            48kB
            • xyz replied to this.

              pedrohfmg

              Instance of the double scene shouldn't be in the main scene at all.
              The code that instantiates that scene shouldn't be inside that scene itself. Instead put spawn_double_powerup() in the ball.gd.
              Also remove all manual signal connections from/to the double scene and make all needed connections on the instance, once it is instantiated, using connect(). This should all happen in spawn_double_powerup() situated in ball.gd.
              The code inside powerup scene shouldn't really do anything other than movement.

                xyz I started doing some of these suggestions, but then I remembered that when I started this part of the code last night, I did the spawn_powerup in the ball script, but the instantiated powerups all follow the same exact ball movement when they are created, they are for the most part outside of the screen, and they aren't independent of each other. That's why I switched to an object detached from the ball, because at least in this way the movement works.
                Any suggestions?

                • xyz replied to this.

                  pedrohfmg My main suggestion would be to start with something a bit more simple than arkanoid until you get a better grip on how instancing and signals work.

                  I've rearranged it slightly as suggested above, so take a look:

                  arkanoid.zip
                  49kB

                    xyz Thank you very much, I studied your changes to my code and I understood now what you mean by those suggestions.
                    This is my 4th godot project and I tried to do something a little more challenging, as my previous three were successful.
                    Thanks! I will recreate the project from scratch and try to organize my structure in a better way