第一个对话框
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时,你必须至少定义两个变量:
- sprite.image - 用于保存精灵位图
- sprite.rect - 定义 .image
的位置和大小
您的 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)
非常感谢您的快速输入!
我还处于 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时,你必须至少定义两个变量:
- sprite.image - 用于保存精灵位图
- sprite.rect - 定义 .image 的位置和大小
您的 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)
非常感谢您的快速输入!