02.coding-the-slideshow

Coding the slideshow

In this lesson, we will write the code to display the text of each slide. We will also advance to the next slide when the player clicks the button. When we’ve reached the last slide, clicking the button will close the running scene.

To achieve that, we need to:

  1. Keep track of the displayed slide to know which comes next.
  2. Know how many slides there are to know when to close the game.
  3. Display the slides.

Let’s start by keeping track of the displayed slide’s index.

Keeping track of the displayed slide

We need to know which slide is currently displayed to know which slide should come next.

To represent the data of each slide, we created an array named slides for you. Each slide is a Dictionary inside of the slides array.

var slides := [
    {"text": "In this series, you'll code a slideshow."},
    {"text": "You can use the techniques you'll see here for simple cut-scenes, linear conversations, and more."},
    {"text": "What you'll see here isn't limited to conversations. You'll learn the basics behind any sequence of events."},
    {"text": 'We will build upon this series to later create a branching dialogue system, a sort of "choose your own adventure" toy.'},
]

Because slides is an array, each slide has a corresponding index that we can store: 0 corresponds to the first slide, 1 to the second slide, and so on.

var slide_index := 0

Before displaying a slide, we want to change the slide_index and update the displayed text.

To do so, we define a new function named show_slide(). It takes the slide’s index as its parameter and updates the slide_index variable.

func show_slide(new_slide_index: int) -> void:
    slide_index = new_slide_index

Displaying the desired slide

In the same function, we retrieve the corresponding slide’s dictionary and change our Label’s text.

To access the Label, we store it in an onready variable at the top of our script.

onready var label := $VBoxContainer/Label


func show_slide(new_slide_index: int) -> void:
    # ...
    var slide: Dictionary = slides[slide_index]
    set_text(slide["text"])


# In the next lesson, we'll animate the text and need multiple lines of code to
# do so. That's why we define a function just to change the displayed text.
func set_text(new_text: String) -> void:
    label.text = new_text

You can show the first slide using the _ready() function.

func _ready() -> void:
    show_slide(0)

Advancing to the next slide

To advance to the next slide, we need to show the slide that comes after the current slide_index value.

func advance() -> void:
    show_slide(slide_index + 1)

We write a new function named advance() to connect the button’s pressed signal.

So far, we have connected signals using the editor’s Node dock. We can connect signals using code as well.

onready var button := $VBoxContainer/Button

func _ready() -> void:
    # ...
    button.connect("pressed", self, "advance")

To connect a signal using code, you call the connect() function on the node that has the signal. In this case, we want to connect the Button’s pressed signal, so we call button.connect().

The function takes three required arguments:

  1. The signal’s name as a String.
  2. The node that has the callback function we’re connecting to. Here, self means “the node with the script attached.”
  3. The name of the function to call when emitting the signal, as a String.

That way, every time you press the button, the advance() function runs and shows the next slide’s text.

Quitting the game after the last slide

You’ll often want to move on at the end of a slideshow.

You may want to hide the dialogue box or change the running scene. But here, we don’t have anything else to show, so we’ll quit the game.

Precisely, we want to do two things:

  1. When we reach the last slide, we change the button text to “Quit”.
  2. When we are displaying the last slide, and the player presses the button, we quit the game.

Detecting the last slide

To detect when we reached the last slide, we can store the last slide’s index in a new variable. That’s the slides array’s size minus one.

var last_slide_index := slides.size() - 1

We can then use that value in the show_slide() function to update the button’s text.

func show_slide(new_slide_index: int) -> void:
    # ...
    if slide_index == last_slide_index:
        button.text = "Quit"

Finally, if the button’s text is “Quit” when pressing it, we can quit the game by calling get_tree().quit().

We do that from the advance() function, in which we introduce conditions.

func advance() -> void:
    if slide_index == last_slide_index:
        get_tree().quit()
    else:
        show_slide(slide_index + 1)

You can now run the scene, click the button, and see the conversation run to its end!

The code

Here’s the full code for the slideshow script.

extends Control

var slides := [
    {"text": "In this series, you'll code a slideshow."},
    {"text": "You can use the techniques you'll see here for simple cut-scenes, linear conversations, and more."},
    {"text": "What you'll see here isn't limited to conversations. You'll learn the basics behind any sequence of events."},
    {"text": 'We will build upon this series to later create a branching dialogue system, a sort of "choose your own adventure" toy.'},
]

var slide_index := 0
var last_slide_index := slides.size() - 1

onready var label := $VBoxContainer/Label
onready var button := $VBoxContainer/Button


func _ready() -> void:
    show_slide(0)
    button.connect("pressed", self, "advance")


func show_slide(new_slide_index: int) -> void:
    slide_index = new_slide_index

    var slide: Dictionary = slides[slide_index]
    set_text(slide["text"])
    if slide_index == last_slide_index:
        button.text = "Quit"


# In the next lesson, we'll animate the text and need multiple lines of code to
# do so. That's why we define a function just to change the displayed text.
func set_text(new_text: String) -> void:
    label.text = new_text


func advance() -> void:
    if slide_index == last_slide_index:
        get_tree().quit()
    else:
        show_slide(slide_index + 1)