Skip to content

Displaying Text and Dialogues in a Visual Novel with Pygame

Introduction

In visual novels, displaying text and dialogues is crucial for storytelling. This documentation provides a detailed guide on how to implement text and dialogue functionality in a visual novel using Pygame.

Creating a Text Display Function

To display text on the screen, create a function that renders text using Pygame’s font module. This function will also handle text wrapping and positioning.

def display_text(text, x, y, font, color=BLACK):
    """
    Renders and displays text on the screen at the specified position.

    Args:
        text (str): The text to be displayed.
        x (int): The x-coordinate of the text position.
        y (int): The y-coordinate of the text position.
        font (pygame.font.Font): The font object to use.
        color (tuple): The color of the text (default is black).
    """
    lines = text.split('\n')
    y_offset = 0
    for line in lines:
        text_surface = font.render(line, True, color)
        screen.blit(text_surface, (x, y + y_offset))
        y_offset += text_surface.get_height()

Handling Dialogues

Dialogues in visual novels typically involve sequential text with player input to proceed. Implement a function to handle and display dialogues:

def show_dialogue(dialogue_list, font, color=BLACK):
    """
    Displays a sequence of dialogues on the screen.

    Args:
        dialogue_list (list): A list of dialogue strings.
        font (pygame.font.Font): The font object to use.
        color (tuple): The color of the text (default is black).
    """
    index = 0
    while index < len(dialogue_list):
        screen.fill(WHITE)
        display_text(dialogue_list[index], 20, SCREEN_HEIGHT - 100, font, color)
        pygame.display.flip()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    index += 1
                    break

Text Box Design

To enhance the visual presentation, you can create a text box background. Use Pygame’s Rect object to define the text box area and fill it with a color:

def draw_text_box(y_offset, width=SCREEN_WIDTH-40, height=100, color=BLACK):
    """
    Draws a text box at the bottom of the screen.

    Args:
        y_offset (int): The y-coordinate offset for the text box.
        width (int): The width of the text box.
        height (int): The height of the text box.
        color (tuple): The color of the text box (default is black).
    """
    pygame.draw.rect(screen, color, pygame.Rect(20, SCREEN_HEIGHT - y_offset - height, width, height))

Text Features

You can add effects such as typing animation to make dialogues more engaging:

import time

def type_text(text, x, y, font, color=BLACK, speed=0.05):
    """
    Displays text with a typing effect.

    Args:
        text (str): The text to be displayed.
        x (int): The x-coordinate of the text position.
        y (int): The y-coordinate of the text position.
        font (pygame.font.Font): The font object to use.
        color (tuple): The color of the text (default is black).
        speed (float): The typing speed in seconds per character (default is 0.05).
    """
    for i in range(len(text) + 1):
        screen.fill(WHITE)
        display_text(text[:i], x, y, font, color)
        pygame.display.flip()
        time.sleep(speed)

Text Formatting

For different text styles, create a dictionary of fonts:

fonts = {
    'normal': pygame.font.Font(None, 36),
    'bold': pygame.font.Font(None, 48),
    'italic': pygame.font.Font(None, 24)
}

def display_styled_text(text, x, y, style='normal', color=BLACK):
    """
    Displays styled text on the screen.

    Args:
        text (str): The text to be displayed.
        x (int): The x-coordinate of the text position.
        y (int): The y-coordinate of the text position.
        style (str): The style of the text ('normal', 'bold', 'italic').
        color (tuple): The color of the text (default is black).
    """
    font = fonts.get(style, fonts['normal'])
    display_text(text, x, y, font, color)

Example Code

Here’s a complete example that integrates text and dialogue handling into a simple Pygame loop:

import pygame
import sys
import time

# Initialize Pygame
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Visual Novel")
font = pygame.font.Font(None, 36)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)

def display_text(text, x, y, font, color=BLACK):
    lines = text.split('\n')
    y_offset = 0
    for line in lines:
        text_surface = font.render(line, True, color)
        screen.blit(text_surface, (x, y + y_offset))
        y_offset += text_surface.get_height()

def show_dialogue(dialogue_list, font, color=BLACK):
    index = 0
    while index < len(dialogue_list):
        screen.fill(WHITE)
        draw_text_box(100)
        display_text(dialogue_list[index], 20, SCREEN_HEIGHT - 100, font, color)
        pygame.display.flip()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    index += 1
                    break

def draw_text_box(y_offset, width=SCREEN_WIDTH-40, height=100, color=BLACK):
    pygame.draw.rect(screen, color, pygame.Rect(20, SCREEN_HEIGHT - y_offset - height, width, height))

# Example dialogue
dialogues = [
    "Welcome to our visual novel!",
    "Here is how we handle text and dialogues.",
    "Press SPACE to proceed through the dialogue."
]

# Main loop
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    show_dialogue(dialogues, font, BLACK)
    pygame.quit()
    sys.exit()