How to return text based on a keyboard response?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Lindsay4047
:warning: Old Version Published before Godot 3 was released.

Just like in a text adventure, I want what the player types in to return a text response based on what the player types in. I know a signal would be used to accomplish this, but I still don’t have a good grasp on custom signals. I am using the LineEdit and RichTextLabel nodes.

Additionally, would there be an easier or simpler way to organize the responses, instead of using several if statements?

Thanks!

:bust_in_silhouette: Reply From: JTJonny

I think a dictionary {} might be good for this.

I like signals, but I think a plain _process(delta) would be fine.

If I was you I would look through all the String class methods:
http://docs.godotengine.org/en/latest/classes/class_string.html

and I would look though the methods in TextLabel and every other text node you might want to use. Try to see what every node can really do ( and remember it can do everything that it is inheriting from too)

     extends TextEdit
        
# this is a dictionary
        var responses = {["hi", "who are you"] : "hi, I'm a dog", ["i like cats", "i don't like dogs"]: "I'm going to bite you."} 
        var foundResponse = true
        
        func _ready():
        		
        	set_process(true)
        func _process(delta):
        	if Input.is_action_pressed("ui_right") == true:
    		
    		var inputText = get_text()
    		inputText = inputText.to_lower() # make lowercase
    		
           # look for a response in the keys of the dictionary
    		for key in responses.keys():
    			if inputText in key:
    				get_node("Label").set_text(responses[key])
    				foundResponse = true
    				return
    
    		if foundResponse == false:
    			get_node("Label").set_text("i don't understand")
    		
    		foundResponse = false

Thanks for the advice and link. Can you explain why you would use _process(delta) instead of a signal?

This is my code so far, which returns text from the LineEdit node onto the RichTextLabel, but the RichTextLabel isn’t able to return a response relative to the player response.

extends LineEdit

signal return_text

var response = self.get_text()
var _node

func _text_response():
  response.connect("return_text", self, "_signal_response")

func _ready():
  _node = self.get_parent().get_node("RichTextLabel")

func _on_LineEdit_text_entered(text):
  if text.length() > 0:
	_node.add_text(">"+ text)
	_node.newline()
	self.clear()

func _on_text_response(responseIn):
   emit_signal("return_text")

Do you know why the signal isn’t working?

Lindsay4047 | 2016-06-27 07:10

info about signals:
# the built-in signals emit automatically (based on built-in triggers)
# but custom ones do not, so you need to add an emitter: emit_signal(“your_signal_name”)
# the problem you have is: you don’t have anything to trigger your emit_signal()

_process(delta) vs signals
# signals from my understanding are basically free ( the engines checking things if you use them or not)
# signals only send you info when something happens
# _process(delta) allows you to check things constantly

http://docs.godotengine.org/en/latest/tutorials/step_by_step/scripting.html
GDScript reference — Godot Engine (latest) documentation in English

extends LineEdit

signal return_text

var response = self.get_text()
var _node

# you can connect your signal in _ready() (so I delete _text_response())

func _ready():
	_node = self.get_parent().get_node("RichTextLabel") 	    	
	
	# you might be better off using a built-in one like "text_entered"
	connect("text_entered", self, "_on_LineEdit_text_entered") 

func _on_LineEdit_text_entered(text):
	if text.length() > 0:
		_node.add_text(">" + text)
		_node.newline()
		self.clear()

	# Don't really understand whats going on with this part, but I don't think you need it.
	#func _on_text_response(responseIn):
	#   emit_signal("return_text")

JTJonny | 2016-06-27 07:56

:bust_in_silhouette: Reply From: Ilya

You don’t need signals for this.
If you want some response on keyboard input, you should be using built-in _input(event) processing loop.

func _ready():
    set_process_input(true)

func _input(event):
    if event.type == InputEvent.KEY
    # update label / process input

InputEvent

As for processing, I’d follow the other answer with dictionary approach