【问题标题】:How do I blit text letter by letter in pygame? (like in those retro RPG games)如何在 pygame 中逐个字母地 blit 文本? (就像那些复古的 RPG 游戏一样)
【发布时间】:2021-01-10 12:31:53
【问题描述】:

我设置了与 NPC 的碰撞,这样当玩家靠近它们时会出现一个对话,但我决定更改它,因为如果文本逐个字母呈现,它会看起来更复古,我试着“blit”每个字母并在每个字母之间添加time.sleep(1),但这会在执行时大大减慢游戏速度。有没有其他方法可以做到这一点?我已经从我的代码中附加了对话功能,我的整个代码都链接了here

def npc_one_dialogue():
    P = font.render('P', True, black)
    r = font.render('r', True, black)
    o = font.render('o', True, black)
    f = font.render('f', True, black)
    e = font.render('e', True, black)
    s = font.render('s', True, black)
    scr.blit(P, (110, 420))
    time.sleep(0.2)
    scr.blit(r, (140, 420))
    time.sleep(0.2)
    scr.blit(o, (170, 420))
    time.sleep(0.2)
    scr.blit(f, (200, 420))
    time.sleep(0.2)
    scr.blit(e, (230, 420))
    time.sleep(0.2)
    scr.blit(s, (260, 420))
    time.sleep(0.2)
    scr.blit(s, (290, 420))
    time.sleep(0.2)
    scr.blit(o, (320, 420))
    time.sleep(0.2)
    scr.blit(r, (350, 420))

【问题讨论】:

  • 你可以将它的睡眠时间减少到 0.2 秒左右......它会影响整个游戏,还是只会影响对话?如果您的问题仍然存在,请尝试上传代码,因为可能还有其他问题
  • @Shufi123 将睡眠值保持为 1 或 0.2,无论哪种方式,它都会减慢速度,以至于它甚至没有达到预期的效果,整个游戏都变慢了,甚至没有执行关键事件速度足够快,它们会延迟 5 秒甚至不完全执行,因为代码会立即对其进行编辑并添加对话功能部分,并为整个内容添加 GitHub 链接

标签: python time pygame


【解决方案1】:

所以我们需要一个计时器。但在此之前,手动渲染每个字母的方式非常繁琐。我们可以把它放在一个循环中,这样每次迭代我们都会渲染一个字母。

这样做的一种方法是为每个字母生成单独的文本表面并将它们存储在surfaces 列表中。在那之后,我们需要知道我们想把每个字母放在哪里。我们可以遍历表面并将位置相应地添加到positions 列表中。

FONT = pygame.font.Font(pygame.font.get_default_font(), 20)
previousWidth = 0
def getSurfaces(word, pos):
    global previousWidth
    
    surfaces = []
    positions  = []
    for i in range(len(word)):
        surf = FONT.render(f"{word[i]}", True, black)
        surfaces.append(surf)
    for i in range(len(surfaces)):
        previousWidth += surfaces[i-1].get_rect().width
        positions.append([previousWidth + pos[0], pos[1]])
    return surfaces, positions

该函数返回单词中每个字母的表面和位置。 positions 列表中的第一个位置与第一个字母、第二个与第二个字母等相关,因此很容易像这样循环和 blit 它们:

    for i in range(len(surfaces)):
        src.blit(surfaces[i], (positions[i][0], positions[i][1]))

工作最小示例:

import time
import pygame
pygame.init()

D = pygame.display.set_mode((500, 300))
FONT = pygame.font.Font(pygame.font.get_default_font(), 20)

black = (0, 0, 0)
word = "profes"
   
previousWidth = 0
def getSurfaces(word, pos):
    global previousWidth
    
    surfaces = []
    positions  = []
    for i in range(len(word)):
        surf = FONT.render(f"{word[i]}", True, black)
        surfaces.append(surf)
    for i in range(len(surfaces)):
        previousWidth += surfaces[i-1].get_rect().width
        positions.append([previousWidth + pos[0], pos[1]])
    return surfaces, positions

surfaces, positions = getSurfaces(word, [100, 150])

def npc_one_dialogue():
    for i in range(len(surfaces)):
        D.blit(surfaces[i], (positions[i][0], positions[i][1])) 

while True:
    pygame.event.get()
    D.fill((255, 255, 255))

    npc_one_dialogue()

    pygame.display.flip()

现在我们有了单独渲染每个字母的方法,问题就变成了在渲染每个字母之间添加延迟,这可以使用time.time 来完成。所以我们可以把npc_one_dialogue函数改成:

start = time.time()
count = 0
def npc_one_dialogue(delay=0.3):
    global count
    global start
    now = time.time()
    if count < len(surfaces):
        if now - start > delay:
            count += 1
            start = now
    for i in range(count):
        D.blit(surfaces[i], (positions[i][0], positions[i][1]))

【讨论】:

  • @pythonnewbie 欢迎您。此外,当我将代码从 IDLE 复制到此处时,我以某种方式设法删除了一行代码,因此最小的“工作”示例不起作用。不过我现在改变了它,所以它确实有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-07
  • 2013-07-25
  • 1970-01-01
  • 2022-11-04
  • 2020-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多