A huge thing for me to code which I require help

Godot Version
4.1

Question

How to basically connect signals to other functions, which changes a variable & a word?

Basically, im making a game where as an enemy spawns, having a random letter above it. There is a word on top which is a fill-in-the blanks. It could be like “R_d” or “B_ue”.

What I want to do is to create a sequence where when the enemy with the letter above them is defeated, that letter is then checked whether it can be used for the word. So if I defeat an enemy with the letter E and the word is Red, then it will see that and understand that I got it right and move on to the next word.

Here is how the code looks like

Enemy’s code:

extends CharacterBody2D

signal enemy_down(letter)

const MAX_SPEED = 75

# Called when the node enters the scene tree for the first time.
func _ready():
	$Area2D.area_entered.connect(on_area_entered)


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	var direction = get_direction_to_Player()
	velocity = direction * MAX_SPEED
	move_and_slide()


func get_direction_to_Player():
	var player_nodes = get_tree().get_first_node_in_group("player") as Node2D
	if player_nodes != null:
		return (player_nodes.global_position - global_position).normalized()
	return Vector2.ZERO

func on_area_entered(other_area: Area2D):
	queue_free()
	enemy_down.emit(	)

The code for another scene for label

extends Label

signal alphabetfromenemy(letter)

var letters = "abcdefghijklmnopqrstuvwxyz"
func gen_unique_string(length: int) -> String:
	var result = ""
	for i in range(length):
		result += letters[randi() % letters.length()]
	return result

func _ready():
	for i in range(1):
		print(gen_unique_string(1))
		var alphabet = gen_unique_string(1)
		set_text((gen_unique_string(1)))
		alphabetfromenemy.emit()


func _on_hooded_enemy_down(letter):
	get_tree().get_second_node_in_group("Label")

The code for the word generation

extends Label

var WordArray = ["ssma_l", "rre_", "bb_ue", "gg_een"]

signal word

func _ready():
	var random = RandomNumberGenerator.new()
	random.randomize()
	var RandomWord = WordArray[randi() % WordArray.size()]
	print(RandomWord)
	set_text(RandomWord)
	if RandomWord == "ssma_l":
		word.emit()
		print("word small sent")
	elif RandomWord == "rre_":	
		print ("word red sent")
		word.emit()
	elif RandomWord == "bb_ue":
		print("word blue sent")
		word.emit()
	elif RandomWord == "gg_een":
		print ("word green sent")
		word.emit()
	else: print("error")

Hi!

This is a pretty good start. The big issue is that you’re trying to use signals to send information, but the way that signals are supposed to work is that they’re supposed to tell other game objects when to react to other game objects, not just for sending information. For example, the “enemy_down” signal would send out a signal that you could connect to other game objects that could then react to the enemy going down. You could send then send the letter to the other objects. I would have the enemy generate the letter, then tell the label to display the letter:

func _on_area_entered(other_area):
    enemy_down.emit(letter)

The second big thing - You should have some sort of parent script in the scene where all these scenes are going to appear, like a World or Level. Then, this parent can receive the signal from the enemy and then tell the “word” scene to check if the letter received from the enemy would complete the word! So something like:

func _on_enemy_down(letter):
        $Word.check_letter(letter)

I’ve skimmed past some pieces, but I hope this makes sense. If not I’ll try and explain it better!

2 Likes

Hi yeah thanks for explaining this. However one slight issue is that the enemy doesn’t generate the letter. It is another label in another scene that is instantiated to the scene of the enemy. Because of this there is no label that is a child node to the enemy.

edit: Nevermind I realized not many things were in the main scene. But really I appreciate your feedback, thank you so much

1 Like

Hi, can you please explain better if possible, I am a beginner so this is going to take a long time.

2 Likes

1: Each unit doesn’t have a corresponding word, rather, an insinuated scene of a letter. So each unit comes with a letter

2: The word is basically a child node under the node “canvas_layer” so the word is able to follow the camera. I am realizing that this could make it harder, but I need the word to follow the camera. If I were to simply add the word to the camera, the word wouldn’t show in the camera.

1 Like

While you shouldn’t over-rely on this, it’s okay to create a singleton that defines some signals so that any scene can either subscribe to it or emit it. Let’s say you call it Events and set it to autoload via Project Settings → Autoload and it has the signal:

extends Node

signal letter_defeated(letter: String)

Then when you create enemy, have a property on it that represents the letter attached to enemy:

var letter: String

Then in wherever you create the enemy scene:

var enemy = my_enemy_scene.instantiate()
enemy.letter = "a" # <- replace with w/e assigned letter

In enemy scene when enemy dies:

letter_defeated.emit(self.letter)

and then in any other scene that needs to react to a letter being defeated:

func _ready():
    Events.letter_defeated.connect(_on_letter_defeated)

func _on_letter_defeated():
   # your code to check if letter is in the word
2 Likes

Btw all of the above can be replaced with:

var RandomWord = WordArray.pick_random()
set_text(RandomWord)
word.emit()
print("word %s sent" % RandomWord)
1 Like

I am realizing that this could make it harder, but I need word to show in camera.

1: Basically, the game is that there is a word in the top of your screen, and it’s a fill-in-the blanks. The word should be shown in the camera for the player to know which enemies to defeat to obtain the letter and finish the word.

2: The game is built where the enemies chase you with a letter above them. The game is built on surviving and completing the word.

3: The player has to know what word are they trying to fill in, else they can’t know.

Each unit doesn’t have a corresponding word, rather,

1: Basically I am in a deadline right now and I have to make this game as fast as possible.

2: The word is a child node under a canvas layer. The enemy isn’t. If it possible to then I would do it.

3: It would change the main goal of my project, which is to help kids to spell the word.


1: Only 1 and it’s for the main scene

2: As long as it helps me to code it fast, then yes.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.