Here is the piece I am trying to figure out right now, which is to draw the dialogue box, then the text on top of it. When ran, I see the displayed dialogue box, but no text.
import pygame
from pygame.locals import *
import os
pygame.init()
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
class Text(pygame.sprite.Sprite):
def __init__(self, text):
# Call the parent class (Sprite) constructor
pygame.sprite.Sprite.__init__(self)
os.chdir(r"<my directory to the dialogue box>.png")
self.surf = pygame.image.load("spikey_box.png").convert()
os.chdir(r"<my directory to my font>")
self.font = pygame.font.Font("final_fantasy_36_font.ttf", 12)
# set up dialogue box sprite
self.rect = self.surf.get_rect()
self.rect.center = (400, 500)
screen.blit(self.surf, self.rect)
# for text
self.textSurf = self.font.render(text, True, (255, 255, 255))
self.textRect = self.textSurf.get_rect()
self.textRect.center = (400, 500)
screen.blit(self.textSurf, self.textRect)
test_message = Text("Hello, world!")
running = True
clock = pygame.time.Clock()
while running:
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
elif event.type == QUIT:
running = False
pressed_keys = pygame.key.get_pressed()
screen.fill((255, 255, 255))
screen.blit(test_message.surf, test_message.rect)
pygame.display.flip()
clock.tick(30)
pygame.quit()
I have some sample code that I was able to adapt a little and make work for another piece I'm working on that I tried to use for inspiration to build the class:
def text_objects(text, font):
textSurface = font.render(text, True, (0, 0, 0))
return textSurface, textSurface.get_rect()
def message_display(text):
largeText = pygame.font.Font('freesansbold.ttf', 20)
TextSurf, TextRect = text_objects(text, largeText)
TextRect.center = ((SCREEN_WIDTH//2), (SCREEN_HEIGHT//2))
screen.blit(TextSurf, TextRect)
The set of two functions were defined outside of the game loop, and worked fine when called from within the game loop as {message_display(f-string)}. I respectfully request guidance to figure out how to make the class implementation work. I want to build on it to the point that I can call the dialogue window and allow the player to scroll back over dialogue already given in that instanced conversation.
When you make a PyGame Sprite based on pygame.sprite.Sprite
, you must define two variables as a minimum:
Your Text
Sprite does not appear to be creating the .image
so it wont work as a normal sprite. But since you directly blit()
the Text.surf
to the display, you've dodged this issue for now.
The code is not writing the text image on top of the background dialogue. It's writing it directly to the screen in the sprite __init__()
. Once the sprite is constructed, this screen update is lost.
Probably you need something like:
class Text(pygame.sprite.Sprite):
def __init__(self, text):
# Call the parent class (Sprite) constructor
pygame.sprite.Sprite.__init__(self)
os.chdir(r"<my directory to the dialogue box>.png")
self.image = pygame.image.load("spikey_box.png").convert()
os.chdir(r"<my directory to my font>")
# Draw the text, centred on the background
self.font = pygame.font.Font("final_fantasy_36_font.ttf", 12)
text = self.font.render(text, True, (255, 255, 255))
centre_x = ( self.rect.width - text.get_width() ) // 2
centre_y = ( self.rect.height - text.get_height() ) // 2
self.image.blit( text, ( centre_x, centre_y ) )
# Set the rect
self.rect = self.image.get_rect()
self.rect.center = (400, 500)
Which loads the dialogue background image, and then rendered the text centred into that box so there is just a single image.
Since surf
has been renamed to image
, the main loop needs a tweak:
...
screen.fill((255, 255, 255))
screen.blit(test_message.image, test_message.rect)
pygame.display.flip()
clock.tick(30)
pygame.quit()
But really the code should use the PyGame Sprite functions for drawing, rather than accessing the internal Surface directly.