Pygame对话框:同时使用透明表面和渐进打字

Pygame dialog box: using transparent surface and gradual typing simulaneously

所以我正在尝试为字符对话框创建一个透明文本框,并且文本字符一次显示一个。我可以单独做一个或另一个,但是当我尝试将它们组合起来时,直到输入完成后才会透明。文本也是透明的,这是我不希望的。

我的游戏代码很复杂,所以我为这个问题编写了这段代码。虽然我已经尝试了很多变体但没有成功,比如每像素 alpha,将文本渲染到主 window,首先单独渲染 texbox 表面,并将渐进输入绑定到主循环而不是它自己的循环.

这是代码:

import pygame
from sys import exit
pygame.init()

WIN = pygame.display.set_mode((1000,600))
clock = pygame.time.Clock()

textbox_surf = pygame.Surface((700,200))
textbox_surf.set_alpha(100)
textbox_rect = textbox_surf.get_rect(topleft=(150,200))
border_rect = textbox_surf.get_rect(topleft=(0, 0))

FONT = pygame.font.SysFont('Georgia', 24, 0)
s = "This is just an example text to use with gradual typing."
show_textbox = False
typing = False

test_text = FONT.render(s, 1, 'White')
text_rect = test_text.get_rect(topleft=(20, 90))

def gradual_typing(txt):
    global typing
    rendering = ''

    WIN.blit(textbox_surf, textbox_rect)
    pygame.display.update()

    for char in txt:
        pygame.time.delay(35)
        pygame.event.clear()

        rendering = rendering + char
        rendered_text = FONT.render(rendering, 1, 'White')
        text_rect = rendered_text.get_rect(topleft=(20, 90))

        pygame.draw.rect(textbox_surf, "Black", border_rect, 6)
        textbox_surf.blit(rendered_text, text_rect)
        WIN.blit(textbox_surf, textbox_rect)

        pygame.display.update()

    typing = False


while True:
    clock.tick(30)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RETURN:
                show_textbox = True
                typing = True

    WIN.fill('Grey')

    if show_textbox:
        textbox_surf.fill('Blue')

        if typing:
            gradual_typing(s)

        textbox_surf.blit(test_text, text_rect)
        pygame.draw.rect(textbox_surf, "Black", border_rect, 4)
        WIN.blit(textbox_surf, textbox_rect)

    pygame.display.update()

附加问题:我注意到文字在按字符书写时,看起来比完成后更粗。它不会在我的主程序中执行此操作,有谁知道为什么要在这里执行此操作?如果你去掉 set_alpha 行就更容易注意到了。

textbox_surf.set_alpha(100) 使整个 Surface 及其全部内容透明。当您不清除背景(填充灰​​色)时,您正在不断堆叠透明表面。因此,矩形看起来不透明,并且文本具有从旧文本到新文本的轻微淡化效果。

创建一个透明的表面,带有SRCALPHA标志

textbox_surf = pygame.Surface((700,200), pygame.SRCALPHA)

清除每一帧的显示并用透明色填充textbox_surf:

def gradual_typing(txt):
    # [...]

        WIN.fill('Grey')
        textbox_surf.fill((0, 0, 255, 100))
        pygame.draw.rect(textbox_surf, "Black", border_rect, 6)
        textbox_surf.blit(rendered_text, text_rect)
        WIN.blit(textbox_surf, textbox_rect)

        # [...]

完整示例:

import pygame
from sys import exit
pygame.init()

WIN = pygame.display.set_mode((1000,600))
clock = pygame.time.Clock()

textbox_surf = pygame.Surface((700,200), pygame.SRCALPHA)
textbox_rect = textbox_surf.get_rect(topleft=(150,200))
border_rect = textbox_surf.get_rect(topleft=(0, 0))

FONT = pygame.font.SysFont(None, 24, 0)
s = "This is just an example text to use with gradual typing."
show_textbox = False
typing = False

test_text = FONT.render(s, 1, 'White')
text_rect = test_text.get_rect(topleft=(20, 90))

def gradual_typing(txt):
    global typing
    rendering = ''

    WIN.blit(textbox_surf, textbox_rect)
    pygame.display.update()

    for char in txt:
        pygame.time.delay(35)
        pygame.event.clear()

        rendering = rendering + char
        rendered_text = FONT.render(rendering, 1, 'White')
        text_rect = rendered_text.get_rect(topleft=(20, 90))

        WIN.fill('Grey')
        textbox_surf.fill((0, 0, 255, 100))
        pygame.draw.rect(textbox_surf, "Black", border_rect, 6)
        textbox_surf.blit(rendered_text, text_rect)
        WIN.blit(textbox_surf, textbox_rect)

        pygame.display.update()

    typing = False


while True:
    clock.tick(30)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RETURN:
                show_textbox = True
                typing = True

    WIN.fill('Grey')

    if show_textbox:

        if typing:
            gradual_typing(s)

    WIN.blit(textbox_surf, textbox_rect)
    pygame.display.update()