0 votes

Hello,

I am new to the godot engine and new to game enginiering. I have done the your first game in the documentation . Based on that I wanted to program a "Flappy Bird" clone. I am now having problems connecting the signals. My scenes look like this:

Main
Player
HUD
Wall

This is the main-scene code:

onready var Wall = preload("res://Wall.tscn")

func _ready():
    randomize()
    get_tree().get_root().find_node("Wall", true, false).connect("lose_game", self , "_on_Wall_lose_game()")

func _on_Wall_lose_game():
    get_tree().reload_current_scene()

func _on_WallSpawTimer_timeout():
    $WallPath/WallSpawnLocation.offset = randi()
    var wall = Wall.instance()
    add_child(wall)
    wall.position = $WallPath/WallSpawnLocation.position

As you can see, the timer spawns the wallparts every one second. This works fine.

This is the wall-scene code:

extends Node2D

var screen_size
var velocity = Vector2()
signal get_point
signal lose_game

# Called when the node enters the scene tree for the first time.
func _ready():
    screen_size = get_viewport_rect().size

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
    velocity.x = -150
    position += velocity*delta
    if position.x < 0:
        queue_free()


func _on_UpperWall_area_entered(area):
    emit_signal("lose_game")
    print("hit oben")

func _on_LowerWall_area_entered(area):
    emit_signal("lose_game")
    print("hit unten")

func _on_Score_area_exited(area):
    emit_signal("get_point")
    print("punkt")

The wall-scene should transmit two signals:
- "losegame" when the upper-wall-collision or the lower-wall-collision gets triggerd. This should be connected with the main scene and restart the game.
- "get
point" when the score-collision is triggerd. This should be connected to the HUD-scene and update the label.

The print-methods works fine so I assume that the singals are sent.

At last, this is the HUD-scene code:

extends Node2D

# Declare member variables here. Examples:
var score = 0
# var b = "text"


# Called when the node enters the scene tree for the first time.
func _ready():
    get_tree().get_root().find_node("Wall", true, false).connect("get_point",self, "handle_get_point")


func handle_get_point():
    score += 1
    $ScoreLabel.text = str(score)
    print(score)

The documentation says to connect the nodes with the signals in the readyfunction. I have already tested some variations (e.g. $Wall.connect("getpoint",self, "handlegetpoint"), getNode("Wall").connect(...), gettree().getroot().findnode("Wall", true, false).connect(...)) but nothing seems to connect the signals correctly.

When im using $Wall.connect("lose_game", self , "_on_Wall_lose_game()") this error appear:

E 0:00:00.610   get_node: (Node not found: "Wall" (relative to "/root/Main").)
  <C++ Error>   Condition "!node" is true. Returned: __null
  <C++ Source>  scene/main/node.cpp:1371 @ get_node()
  <Stack Trace> Main.gd:8 @ _ready()

When using Wall.connect("lose_game", self , "_on_Wall_lose_game()") this one appear:

E 0:00:00.598   connect: In Object of type 'PackedScene': Attempt to connect nonexistent signal 'lose_game' to method 'Node2D._on_Wall_lose_game()'.
  <C++ Error>   Condition "!signal_is_valid" is true. Returned: ERR_INVALID_PARAMETER
  <C++ Source>  core/object.cpp:1500 @ connect()
  <Stack Trace> Main.gd:8 @ _ready()

I guess i am missing something fundamental about the signals but i donĀ“t know what it is. I've been looking for answers for the last two days and found a few similar questions but nothing that helped me. So if someone has already asked the same question I would like to apologize in advance and would be glad if someone could help me.

thank you in advance and kind regards

Visterface

Godot version 3.3.2.stable
in Engine by (15 points)

1 Answer

+1 vote
Best answer

You're on the right track. Your problem is when you do this:

Wall.connect("lose_game", self , "_on_Wall_lose_game()")

you're not referring to a node. Wall is your loaded PackedScene that you're instancing.

$Wall.connect("lose_game", self , "_on_Wall_lose_game()")

There is no node named "Wall". Because node names must be unique among siblings, the instance you're creating isn't named that.

What you want to do is connect each wall's signal when you instance it and add it to the tree. You have the wall variable, which refers to the instance, and you're using that to refer to it in order to add it to the tree.

func _on_WallSpawTimer_timeout():
    $WallPath/WallSpawnLocation.offset = randi()
    var wall = Wall.instance()
    add_child(wall)
    wall.position = $WallPath/WallSpawnLocation.position
    wall.connect("lose_game", self , "_on_Wall_lose_game")

Also, when referring to the name of the target method in connect(), you do not include the ().

by (20,481 points)
selected by

Thank you very much!! This was the problem and the solution works fine. The game is now running as intended. I really really appreciate you taking the time to help me out!

If someone has a similar problem: To connect the signal of the HUD I used onready var hud = get_node("HUD") and for the connection
wall.connect("get_point", hud , "handle_get_point")
The main scene now looks like this:

extends Node2D

onready var Wall = preload("res://Wall.tscn")
onready var hud = get_node("HUD")

# Called when the node enters the scene tree for the first time.
func _ready():
    randomize()


func _on_Wall_lose_game():
    get_tree().reload_current_scene()

func _on_WallSpawTimer_timeout():
    $WallPath/WallSpawnLocation.offset = randi()
    var wall = Wall.instance()
    add_child(wall)
    wall.position = $WallPath/WallSpawnLocation.position
    wall.connect("lose_game", self , "_on_Wall_lose_game")
    wall.connect("get_point", hud , "handle_get_point")
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.