I am recreating flappy bird for practice. I am trying not to follow a direct tutorial on how to recreate the game in order to challenge myself. For the obstacles, I made a spawner that instantiates a pipe from a different scene. The pipe has its collision shape but it also has an Area2D node that will collide with the player and stop the game.
I have used signals before to detect collisions, but I am not sure how to use a signal from an instantiated scene.
The first screenshot is my main scene, where I have instantiated my “pipe” with the “Spawner” node to spawn as an obstacle.
The second screenshot is the pipe scene itself with its collision shape and area2D. I have 2 sets of area2D nodes. One is for the pipes to stop the game, the other will be the score area through the pipes.
I have tried to look this up online, but I am not entirely sure how this works. Thank you!
Are you asking how to connect signals in code? You call the signal’s connect method and pass in the callback that you want to connect it to. Somewhere, you’ll need to connect each of the pipe’s Area2D’s body_entered signals to callbacks of your choice which will respond to the collision. (If the player node is a PhysicsBody2D.) You can do that from the world script where you instantiated the pipe scene, or inside the pipe script, depending on what function you want to hook up. In the world script, it might look something like pipe.get_node("Death_Pipe").body_entered.connect(on_death_pipe_body_entered (not a great way to use get_node, but it’s just an example). Or you could make that connection in the pipe script, define a new signal in n the pipe script, and have the pipe emit that signal when it gets a body_entered signal from one of its own Area2Ds.
What exactly do you want to happen when the player collides with one of the pipe areas?
Your pipes can likely connect body_entered from the editor within their own scene. What to do with that information and how to get it from the pipe to it’s respective node may be the more difficult part.
func _on_death_pipe_body_entered(body: Node2D) -> void:
if body.name == "Bird":
# do lose screen?
I’d say making a function on your world script to handle losing the game would be best, you can get this world node assuming it’s the current scene with get_tree().current_scene then call your function, for example func show_lose_screen()
func _on_death_pipe_body_entered(body: Node2D) -> void:
if body.name == "Bird":
get_tree().current_scene.show_lose_screen()
I want the game to fully stop when the pipe is hit by the player.
Right now, the game stops when the player hits the ground. It was easier for me because the floor node and the bird node are under the same parent node, “world”. I used the get_tree().paused = true for this inside the bird’s script.
So my issue came from not having the pipe node as a child of the world node. It’s only instantiated by my spawner node.
You can connect the signals inside the Pipe scene itself. Since every spawned pipe is an instance of that scene, its _ready() will run automatically and connect its own Area2D signals. You can also connect them in the editor, which is probably the simplest approach here.
Yeah, once the spawner has added the pipe as its child, the pipe is part of the scene tree. So if all you need to do is call get_tree().paused = true, the pipe script can execute that line the same way the bird script does. You can connect the pipe’s signals to its own functions in the _ready() function or in the editor.
But if you need something outside of the pipe scene to respond to the collision, it makes sense for _on_pipe_timer_timeout() to connect the new pipe’s signal(s) to whatever needs them, because (as of the time of your screenshots, at least) _on_pipe_timer_timeout() is responsible for setting up the new node in the scene tree.