How do I create clones of a sprite? (Beginner)

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

I’m making a game where you have to catch objects that fall from the top of the screen, but I don’t know how to make multiple fall.

It’s working, thanks!

cookieKing_ | 2023-05-20 17:21

:bust_in_silhouette: Reply From: zhyrin

The most straight forward way to clone any kind of node is using the duplicate() method.

If your original sprite has a script, in most cases it’ll also get copied.
If that doesn’t suit you, you can use the set_script()method.

How to make multiple object fall:
I assume you want them to start from the same height but different x coordinate, and want them to spawn periodically.
Well, the idea is to have a Timer node that is running. It has a timeout signal that gets called every time the timer is up. By connecting a function to this timeout signal, you can run some code every time a sprite is supposed to spawn.
At this point, you create a clone of your sprite, you set its y coordinate to a fixed position (maybe above the screen just enough that it doesn’t “pop in”).
The x coordinate you would set randomly so the new sprites are not always at the same exact spot.
That’s pretty much it for the “level” that should handle creating the new sprites.
The falling mechanic should be owned by the sprite itself (i.e.: an attached script), this is of course quite simple, you just change its y position in either the _process() or _physics_process() function. If the falling is purely visual, you can use process, if it interacts with the physics system, it should be in the physics process.
A consideration is that if you have a sprite that you keep cloning, than it’s quite possible its own falling script is running continuously, when you would only want it as a reference to get cloned into your level. There are a miriad of solutions for this as well, but I’ll leave it up to you.

:bust_in_silhouette: Reply From: Tom Mertz

I think what you might be looking for is saving a reference to another scene (your objects.tscn) inside your main script and then instantiating multiple instances of them using your main script.

A really easy way to do this is using the preload method in your main script to load up a “copy” of a scene you’ve already made and saved into your project elsewhere, then adding that instance to your scene:

# our main.gd script, this is on main.tscn scene in our project root
extends Node2D

# our object.tscn script saved in our project root that we can use to make instances
var object = preload("res://object.tscn")
# our main.tscn scene has a Timer as a child node
# You'd have to set this timer to auto start and make
# it have the wait time you wanted through the inspector
@onready var timer: Timer = $Timer

func _ready() -> void:
	timer.connect("timeout", self, "_on_timer_timeout")

func _on_timer_timeout() -> void:
	# add a copy of our object.tscn to the scene
	var new_object = object.instantiate()
	# add the new_object as a child of this scene's node
	add_child(new_object)
	# you might optionally want to do things like change the
	# new objects position or call functions on it

Technically the object in the script above I believe is a PackedScene. You can see the docs here, but you probably don’t need to worry too much about that now.

This is also a great tutorial that will cover some of these concepts for beginners. Very helpful: