How to remove already picked up items after revisiting the same level?

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

I just started godot (never programmed before) and trying out mechanics with global variables. Right know i want to make the following steps:

  1. Player is in Stage1 and picks up collectables (both ones that can respawn and ones that can be picked up only once).
  2. Player changes scene.
  3. Player goes back to Stage1 and the “one time pick up” items does not spawn anymore because they are already taken.

I made an “export var = once” which determines that the item can be picked up more times or only once. So a have the following code on collectables:

func _ready():

if Global.taken == true and once == true:
	queue_free()

func _on_collectible_body_entered(body):

if once == false and taken ==false:
	emit_signal("collectible_done")
	set_collision_mask_bit(0,false)
	Global.score = Global.score + 1

if once == true and taken == false:
	emit_signal("collectible_done")
	set_collision_mask_bit(0,false)
	Global.score = Global.score + 1
	already_taken = true
	Global.taken = true

My problems are:

  1. When i collect a one time pick up item the global.taken variable changes to true so revisiting the scene all of the uncollected one time pick up items are already gone. Is there any method to use a list in global script which registers every collected item individually when i pick them up? Because right now there is only on boolean variable which effects every one time pick up item. I think i should use some kind of array but i dont really know how they work or how to fill them up with different items.

2.I tried to implement an “already_taken” variable (which would have the same function as global.taken) but if i change the scene this variable changes back to default. So if there would be an already_taken= true statement, it would never happen after reloading the scene. Is there any method to connect variables form different scenes into the global script?

:bust_in_silhouette: Reply From: AlexTheRegent

There are many ways to do it. One of the ways is to give unique names to all your one-time pick up objects. This way you can easily distinguish one object from another. Then, once player has picked up this object, you can write it’s name to Dictionary (search in Dictionaries usually works faster, because they are indexed). And lastly, during scene setup or inside _ready() function of one time pickup objects you can check if your dictionary has name of this object. If it does, then just queue_free() it.
Here’s draft of this approach:

# global.gd
var collected_pickups = {}

# pickup.gd
func _ready():
  if Global.collected_pickups.has(get_name()):
    queue_free()

func on_body_entered(body):
  Global.collected_pickups[get_name()] = true

Make sure that names of your pickups are unique across all scenes. Or you can make collected_pickups to be dictionary that contains dictionaries with names of collected pickups for each scene separately. Again, there are many ways to do it. This is just one of the approaches.