首页 > 解决方案 > 如何在 PyGame 上显示文本?

问题描述

我正在尝试创建一个游戏,我需要在不同的区域显示文本,所以我尝试创建一个类来显示文本,但我需要调用 pygame.display.set_mode 才能对我的文本进行 blit 但我已经有了:

black = (0, 0, 0)
white = (255, 255, 255)
gold = (250, 175, 50)
blue = (50, 50, 250)


class Display:
    def __init__(self, width, height, colour):
        self.width = width
        self.height = height
        self.colour = colour
        canvasW, canvasH = width, height
        canvas = pygame.display.set_mode((canvasW, canvasH), pygame.NOFRAME)
        canvas.fill(colour)


class Text:
    def __init__(self, text, size, colour, bg, font, bold, italic, x, y, width, height, col):
        self.text = text
        self.size = size
        self.colour = colour
        self.bg = bg
        self.font = font
        self.bold = bold
        self.italic = italic
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.col = col

        Display(width, height, col)
        pygame.font.init()
        myFont = pygame.font.SysFont(font, size, bold, italic)
        textSurf = myFont.render(text, False, colour, bg)
        Display.canvas.blit(textSurf, (x, y))


class DrawDisplay:
    def __init__(self, width, height, col, intro):
        self.width = width
        self.height = height
        self.col = col
        self.intro = intro

        os.environ['SDL_VIDEO_CENTERED'] = '1'
        pygame.init()

        Display(self.width, self.height, self.col)
        # canvasW, canvasH = width, height
        pygame.display.set_caption("TRAVELLER")

        # canvas = pygame.display.set_mode((canvasW, canvasH), pygame.NOFRAME)
        clock = pygame.time.Clock()
        pygame.display.flip()

        if intro:
            # Text('TRAVELLER', 50, black, 'freesansbold.ttf')
            Text('TRAVELLER', 50, black, white, 'freesansbold.ttf', True, False, 10, 100, width, height, col)
            # Text('TRAVELLER', 48, white, 'freesansbold.ttf')
            pygame.display.update()
            clock.tick(120)
            pygame.display.flip()
            time.sleep(7.5)
            pygame.quit()
        else:
            while True:
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        pygame.quit()
                        sys.exit()
            canvas.fill(gold)
            clock.tick(120)
            pygame.display.flip()


class Load(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        width = 450
        height = 250
        DrawDisplay(width, height, gold, True)


class User(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        width = 1920
        height = 1080
        DrawDisplay(width, height, blue, False)


LoaderThread = Load()
UserThread = User()

LoaderThread.start()
LoaderThread.stop()
UserThread.start()

我不确定如何在不将文本连接到显示类的情况下执行此操作,或者我不确定如何在需要时调用它。

标签: pythontextpygamepycharmgame-engine

解决方案


阅读实例对象实例属性

创建Display和的实例Text

display = Display(self.width, self.height, self.col)
text1 = Text('TRAVELLER', 50, black, white, 'freesansbold.ttf', True, False, 10, 100, width, height, col)

该类Display需要一个方法来绘制背景并更新显示:

class Display:
    def __init__(self, width, height, colour):
        self.width = width
        self.height = height
        self.colour = colour
        canvasW, canvasH = width, height
        self.canvas = pygame.display.set_mode((canvasW, canvasH), pygame.NOFRAME)
        pygame.display.set_caption("TRAVELLER")
    def drawbackground(self):
        self.canvas.fill(self.colour)
    def update(self):
        pygame.display.flip()

text 类在构造函数中构造文本表面。它得到一个draw方法,可以blit将文本 ( self.textSurf) 发送到显示表面 ( canvas),这是该draw方法的一个参数:

class Text:
    def __init__(self, text, size, colour, bg, font, bold, italic, x, y, width, height, col):
        self.text = text
        self.size = size
        self.colour = colour
        self.bg = bg
        self.font = font
        self.bold = bold
        self.italic = italic
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.col = col

        myFont = pygame.font.SysFont(font, size, bold, italic)
        self.textSurf = myFont.render(text, False, colour, bg)
    def draw(self, canvas):
        canvas.blit(self.textSurf, (self.x, self.y))

不要使用time.sleep. 你有一个主应用程序循环,所以使用它。根据状态绘制场景self.intro。如果按下某个键或经过一段时间,则跳过介绍。用于pygame.time.get_ticks()获取以毫秒为单位的时间。例如:

class DrawDisplay:
    def __init__(self, width, height, col, intro):
        self.width = width
        self.height = height
        self.col = col
        self.intro = intro

        os.environ['SDL_VIDEO_CENTERED'] = '1'
        pygame.init()
        pygame.font.init()

        display = Display(self.width, self.height, self.col)
        text1 = Text('TRAVELLER', 50, black, white, 'freesansbold.ttf', True, False, 10, 100, width, height, col)

        clock = pygame.time.Clock()    
        start_time = pygame.time.get_ticks()
        run = True
        while run:
            clock.tick(120)

            # handel events
            current_time = pygame.time.get_ticks()
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    run = False
                if self.intro and event.type == pygame.KEYDOWN:
                    run = False
            # change game states
            if self.intro and current_time > start_time + 7500: # 7.5 seconds 
                run = false

            # draw dispaly
            display.drawbackground()

            # draw scene 
            if self.intro:
                text1.draw(display.canvas) #
            else:
                # draw game objects
                # [...]
                pass      

            # update display
            display.update()

推荐阅读