0 votes
extends Node


var dialogue = ["i am [i]extremely[/i] confused but that's ok", 


var dialogueIndex := 0
var stringFinished := false
var textSpeed := .005


func _ready(): 
    load_dialogue()


func _process(delta):
    $"textIndicator".visible = stringFinished
    if Input.is_action_just_pressed("ui_accept"):
        load_dialogue()


func load_dialogue():
    if dialogueIndex < dialogue.size():
        $TextureRect.set_visible(true)
        stringFinished = false
        var temp := ""
        var foundBold = -1
        var boldDone = false

        $dialogueText.clear()
        $dialogueText.set_visible(true)
        $charText.set_visible(true)

        var t = Timer.new()
        t.set_wait_time(textSpeed)
        t.set_one_shot(true)

        for letter in dialogue[dialogueIndex]:


            temp = dialogue[dialogueIndex]
            var findBold = temp.find("[i]")
            var findEndBold = temp.find("[/i]")
            var restOfSentence = ""

            if (temp.find("[i]") != -1) and (boldDone == false):
                stringFinished = false
                var beginning = temp.substr(0, findBold)
                var boldedEnd


                if findEndBold != -1:

                    restOfSentence = temp.substr(findEndBold+4, temp.length())
                    boldedEnd = temp.substr(findBold+3, findEndBold)

                elif findEndBold == -1:
                    boldedEnd = temp.substr(findBold+3, temp.length())


                $dialogueText.set_bbcode("") 

                for letter in beginning:
                    t.start()
                    $dialogueText.append_bbcode(letter)
                    yield(t, "timeout")
                    boldDone = true


                for letter in boldedEnd:
                    t.start()
                    $dialogueText.append_bbcode("[i]" + letter + "[/i]")
                    yield(t, "timeout")
                    boldDone = true


                for letter in restOfSentence:
                    t.start()
                    $dialogueText.append_bbcode(letter)
                    yield(t, "timeout")
                    boldDone = true

                $dialogueText.append_bbcode(beginning + "\n" + boldedEnd + "\n" + restOfSentence)
                stringFinished = true

            elif stringFinished == false:
                for letter in temp:
                    t.start()
                    $dialogueText.append_bbcode(letter)
                    yield(t, "timeout")
                    stringFinished = true


    else:
        queue_free()

    dialogueIndex += 1 

I would have used a tween function, but I wanted to add sound effects for each letter displayed. This probably isn't the most efficient way to do it, but I wanted to get some practice in anyways.

I thought that for example:
a _ [ i ] w o r d [ / i ] .
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

Would print something like "a word." if I called word.substr(2,14). When I run the code it gives me the correct beginning and end but not middle.

I know it says bold in the variables, but I was just testing italics lol. Thanks in advance!

asked Jun 5 in Engine by lyji (33 points)

1 Answer

0 votes
Best answer
extends Node

"""
match [textSpeedInput]:
    [immediate]
        immediateText = 0
    [slow]
        textSpeed = .025
    _
        textSpeed = .005
"""


var dialogue = ["yi er san si", "wu [b]liu![/b] qi", "wo [b]de pong yo[/b]u", "[b]zai na li"]
var dialogueIndex := 0
var stringFinished := false
var textSpeed := .005
var boldDone = false
#":" makes it so that it will never change the variable type


func _ready(): 
    load_dialogue()
    #When ready, call on the load_dialogue() func and 
    #display text inside the dialogue array


func _process(delta):
    $"textIndicator".visible = stringFinished
    #Doesn't need a .play() because it is set to 
    #"Autoplay on Load" already
    if Input.is_action_just_pressed("ui_accept") and stringFinished and boldDone:
        load_dialogue()


func load_dialogue():
    if dialogueIndex < dialogue.size():
        $TextureRect.set_visible(true)
        stringFinished = false
        var temp := ""
        var foundBold = -1
        boldDone = false

        $dialogueText.clear()
        $dialogueText.set_visible(true)
        $charText.set_visible(true)

        var t = Timer.new()
        t.set_wait_time(textSpeed)
        t.set_one_shot(true)
        self.add_child(t)



        for letter in dialogue[dialogueIndex]:


            temp = dialogue[dialogueIndex]
            var findBold = temp.find("[b]")
            var findEndBold = temp.find("[/b]")
            var restOfSentence = ""

            if (findBold != -1) and (boldDone == false) :

                stringFinished = false
                var beginning = temp.substr(0, findBold)
                var boldedEnd
                var endCalc = (temp.substr(findEndBold, temp.length())).length()
                var frontCalc = (temp.substr(0, findBold+3)).length()
                var midLenCalc = abs(temp.length()-endCalc-frontCalc)
                #Len, not index

                if findEndBold != -1:
                    restOfSentence = temp.substr(findEndBold+4, temp.length())
                    #boldedEnd = temp.substr(findBold+3, endCalc-3)
                    boldedEnd = temp.substr(findBold+3, midLenCalc)
                    #Second parameter takes how many letters you want to continue for!!
                    #Not the index, but still need to add one

                    $dialogueText.set_bbcode(str("temp.length()" + str(temp.length()) + " - endCalc " + str(endCalc) +  " - frontCalc" + str(frontCalc) + " = midLenCalc" + str(midLenCalc) + "\n"))
                elif findEndBold == -1:
                    boldedEnd = temp.substr(findBold+3, temp.length())




                #$dialogueText.set_bbcode("") 

                for letter in beginning:
                    t.start()
                    $dialogueText.append_bbcode(letter)
                    yield(t, "timeout")
                    boldDone = true


                for letter in boldedEnd:
                    t.start()
                    $dialogueText.append_bbcode("[b]" + letter + "[/b]")
                    yield(t, "timeout")
                    boldDone = true


                for letter in restOfSentence:
                    t.start()
                    $dialogueText.append_bbcode(letter)
                    yield(t, "timeout")
                    boldDone = true

                $dialogueText.append_bbcode("\n" + beginning + "\n" + boldedEnd + "\n" + restOfSentence)
                stringFinished = true

            elif stringFinished == false:
                for letter in temp:
                    t.start()
                    $dialogueText.append_bbcode(letter)
                    yield(t, "timeout")
                stringFinished = true
                boldDone = true




    else:
        queue_free()
        #Once the load_dialogue function is broken because
        #it read the entire array, the queue will be 
        #freed and nothing will show up on screen
    dialogueIndex += 1 

Figured it out. I'll just dump my code here in case anyone else had the same issue. I've been coding in Java for months so I forgot how to use substrings in Godot oops. Once I figured out the length instead of the index it worked.

answered Jun 5 by lyji (33 points)
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.