Swap scene variables and setting instances

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

I am trying to build a system similar to how in tetris you have your current block, but can already see what the next block will be in the hud. I tried it like this:
Level:

_ready():
current = Block.instance()
current.random()
add_child(current)
next = Block.instance()
next.random()
Hud.set_next(next)
_process():

//decide it’s time to go to the next piece
remove_child(current)
current = next
add_child(current)
next = Block.instance()
next.random()
Hud.set_next(next)

Currently this leaves me with a new next-piece appearing on the HUD, but my current piece seems to be gone. I already tried many different configurations of mostly similar things, but none worked.
I assume the assignment doesn’t work the way I think it does.
I suspect the reason it disappears is because it isn’t in any tree?
I had a hard time finding similar questions, because the questions is kind of dwarved by questions on “how to set variable of a scene” which is not what I’m looking for.
My goal is to set a variable from scene instance A to scene instance B.
I’m hoestly not sure why it isn’t as simple as it should be.
Anyone have an idea what I’m doing wrong?

This seems like the most logical way to approach this problem:

func _ready():
    current = Block.instance()
    current.random()
    add_child(current)
    create_new_next_block()

func _process():
...
//decide it's time to go to the next piece
    current = next
    create_new_next_block()

func create_new_next_block():
    next = Block.instance()
    add_child(next)
    next.random()
    Hud.set_next(next)

If you want an instance to display on screen it should be a child of a node that’s in the tree. I think when you were remove_child(current) you were deleting something you didn’t want to be deleting. If you’re making a game like tetris you should only remove_child() when you’re checking for completed lines.

timothybrentwood | 2021-11-19 02:31

This seems to have kind of been the issue. What I had to do was add the current block
to the scene after changing the next one like so:

current = next
next = Instance
next.random
Hud.update(next)
add_child(current)

So I suspect I can have any node be only child of one tree, so I first have to use the update-call so the new current block is not hanging in the Hud anymore before I can add him into the level scene.

nonsense | 2021-11-19 07:23

I see. What you’re trying to do is reparent the node. When you call add_child() it’s the same thing as calling self.add_child() (or this.add_child() in other languages). Since the next block is a child of the Hud node the transfer should go something like this:

//decide it's time to go to the next piece
current = next
Hud.remove_child(current)
add_child(current) 
next = Block.instance()
next.random()
Hud.set_next(next) 

I’m not sure what Hud.set_next() is doing but I assume it’s calling add_child() on the newly instanced block. And again I think the only time you call remove_child() from your main scene on blocks is when you’re calculating completed lines.

timothybrentwood | 2021-11-19 14:23

:bust_in_silhouette: Reply From: dewcked

Just put the script in the map.
Provided hierarchy

Map <- put script here
    blocks_stacked: 
        Monoblock_1
        Monoblock_2
        ....
        Monoblock_n
    var current_block: ShapedBlock
        Monoblock_1
        Monoblock_2
        ...
    var next_block: ShapedBlock
        Monoblock_1
        ....

Let’s say every block is consist of Monoblock. If current_block hit the bottom or another block, don’t remove current_block. just add blocks to blocks_stacked one block by one block. and check row is full and pop it. Then set current_block = next_block and change the position of the current_block. After that, instance new block to the next_block. That should solve all the possible problems.