第一个对话框

First Dialogue Box

我还处于 pygame 编码的早期阶段,但这是我现在想弄清楚的部分,即绘制对话框,然后在其上绘制文本。当运行时,我看到显示的对话框,但没有文字。

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()

我有一些示例代码,我可以稍作调整并为我正在研究的另一件作品工作,我试图用它来获得灵感来构建 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)

这两个函数集是在游戏循环外定义的,并且在游戏循环内以 {message_display(f-string)} 调用时运行良好。我恭敬地请求指导,以学习如何提出正确的问题来弄清楚如何使 class 实施工作。我想以此为基础,我可以调用对话 window 并允许玩家向后滚动该实例对话中已经给出的对话。 提前致谢!

当你根据pygame.sprite.Sprite制作PyGame Sprite时,你必须至少定义两个变量:

  1. sprite.image - 用于保存精灵位图
  2. sprite.rect - 定义 .image
  3. 的位置和大小

您的 Text Sprite 似乎没有创建 .image,因此它不能作为普通的 sprite 使用。但由于您直接 blit()Text.surf 显示到显示器上,您现在已经避开了这个问题。

该代码未在背景对话之上写入文本图像。它直接将其写入精灵 __init__() 中的屏幕。构建精灵后,此屏幕更新将丢失。

可能你需要这样的东西:

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)   

加载对话背景图像,然后将文本渲染到该框的中心,因此只有一个图像。

由于 surf 已重命名为 image,主循环需要调整:

    ...
    screen.fill((255, 255, 255))
    screen.blit(test_message.image, test_message.rect)
    pygame.display.flip()
    clock.tick(30)
pygame.quit()

但实际上代码应该使用 PyGame Sprite 函数进行绘图,而不是直接访问内部 Surface。

感谢@Kingsley 的意见,你绝对是对的,并帮助我指明了正确的方向。我发现问题在于我如何实例化 class 对象,并在游戏循环中执行一个没有真正意义的奇怪调用。我正在尝试 blit。我重构了我的 class 对象,它现在可以完美运行了!

class Text(pygame.sprite.Sprite):
def __init__(self):
    # Call the parent class (Sprite) constructor
    pygame.sprite.Sprite.__init__(self)
    os.chdir(r"C:\Users\mcbri\Documents\Python\master\Resources\pv1\pv1_objects")
    self.surf = pygame.image.load("spikey_box.png").convert()  #for box
    os.chdir(r"C:\Users\mcbri\Documents\Python\master\Resources\fonts")
    self.font = pygame.font.Font("final_fantasy_36_font.ttf", 12)
    self.rect = self.surf.get_rect()
    self.rect.center = (400, 500) 
    
def pop_message(self, text):
    screen.blit(self.surf, self.rect)
    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)

...在循环中:

    elif event.type == QUIT:
        running = False
pressed_keys = pygame.key.get_pressed()
screen.fill((255, 255, 255))
test_message.pop_message("Hello, world!")
pygame.display.flip()
clock.tick(30)

非常感谢您的快速输入!