import random import pygame def draw_dialogue_text( text, color, pos, fontsize, letters_shown, surface, space_width=10, letter_spacing=0, line_spacing=5, shake_amount=0, debug=False ): """ Draw up to `letters_shown` characters of `text` onto `surface`. pos is relative to the top-left of `surface`. Returns how many characters were drawn (useful for debugging). """ colors = { "white": (255,255,255), "red": (255,0,0), "green": (0,255,0), "blue": (0,0,255), "yellow": (255,255,0) } fg = colors.get(color, color if isinstance(color, tuple) else (255,255,255)) font = pygame.font.Font("determination.ttf", fontsize) x_start, y = pos drawn = 0 # iterate line-by-line so '\n' is respected for line in text.split("\n"): x = x_start for ch in line: if drawn >= letters_shown: return drawn if ch == " ": x += space_width drawn += 1 continue ch_surf = font.render(ch, True, fg) shake_x = random.uniform(-shake_amount, shake_amount) shake_y = random.uniform(-shake_amount, shake_amount) dest_x = x + shake_x dest_y = y + shake_y surface.blit(ch_surf, (dest_x, dest_y)) if debug: # draw a small rect showing the glyph area (visible overlay) pygame.draw.rect(surface, (255,0,0), pygame.Rect(int(dest_x), int(dest_y), ch_surf.get_width(), ch_surf.get_height()), 1) x += ch_surf.get_width() + letter_spacing drawn += 1 # move to next line. use font.get_linesize if available try: line_h = font.get_linesize() except Exception: line_h = fontsize y += line_h + line_spacing return drawn import pygame, sys, time from pygame.locals import * pygame.init() # paste the draw_dialogue_text() function here (or import it) SCREEN = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() # create dialogue surface (width x height) and a semi-transparent background dialogue = pygame.Surface((590, 120), pygame.SRCALPHA) dialogue.fill((0,0,0,180)) dialogue_text = "* Howdy!\n* I'm FLOWEY.\n* FLOWEY the FLOWER!" letters_shown = 0 last_tick = pygame.time.get_ticks() delay_ms = 40 # reveal speed (ms per character) running = True while running: for ev in pygame.event.get(): if ev.type == QUIT: running = False if ev.type == KEYDOWN and ev.key == K_ESCAPE: running = False # increment letters_shown on a timer now = pygame.time.get_ticks() if now - last_tick >= delay_ms: letters_shown += 1 last_tick = now # clear and draw dialogue.fill((0,0,0,180)) # draw flowey sprite placeholder (comment/remove if you have actual image) # pygame.draw.circle(dialogue, (0,255,0), (30,30), 20) # draw the text onto the dialogue surface (pos inside dialogue) draw_dialogue_text(dialogue_text, "white", (40, 10), 24, letters_shown, dialogue, space_width=10, letter_spacing=-1, line_spacing=2, shake_amount=0.5, debug=True) # blit to main screen at a visible place SCREEN.fill((30,30,30)) SCREEN.blit(dialogue, (25, 340)) # same placement you used pygame.display.flip() clock.tick(60) pygame.quit() sys.exit()