解决Pygame中打字机效果仅显示最后一段文本的问题
Pygame打字机效果仅显示最后一段文本的解决方法
问题核心
你的代码存在两个关键问题导致仅显示最后一段文本:
- 两次给
text变量赋值,第二次直接覆盖了第一段文本的内容,最终只有第二段文本被传入cursor.write()。 - 即使调用两次
cursor.write(),原write方法会直接替换self.text列表,而非追加文本,导致第一段内容被覆盖丢失。
解决步骤
1. 修复文本覆盖问题
避免直接覆盖text变量,可选择合并两段文本,或用队列存储多段待输出内容:
- 合并文本方式:
text = """[i] Initializing ... [i] Entering ghost mode ... done ... [Me] What you talking about? done ... """
- 队列存储方式(适合分阶段输出):
text_queue = [ """[i] Initializing ... [i] Entering ghost mode ... done ... """, """[Me] What you talking about? done ... """ ]
2. 修改Cursor类的文本处理逻辑
将原write方法改为追加文本,或新增队列管理功能实现多段文本顺序输出:
方案一:简单追加文本
修改Cursor类的write方法:
def write(self, text): # 用extend追加字符列表,而非替换原有内容 self.text.extend(list(text))
之后在主代码中依次调用:
cursor.write("""[i] Initializing ... [i] Entering ghost mode ... done ... """) cursor.write("""[Me] What you talking about? done ... """)
方案二:多段文本顺序输出(推荐)
给Cursor类添加文本队列,实现第一段完全输出后自动加载第二段:
class Cursor(pygame.sprite.Sprite): def __init__(self, board): pygame.sprite.Sprite.__init__(self) self.image = pygame.Surface((10, 20)) self.image.fill((255,255,255)) self.text_height = 34 self.text_width = 20 self.rect = self.image.get_rect(topleft=(self.text_width, self.text_height)) self.board = board self.text = [] # 当前正在输出的字符列表 self.text_queue = [] # 待输出的文本段队列 self.cooldown = 0 self.cooldowns = {'.': 12, '[': 18, ']': 18, ' ': 5, '\n': 30} def add_text(self, text): # 将文本段加入队列 self.text_queue.append(text) def update(self): # 当前无输出内容且队列非空时,取出下一段文本 if not self.text and self.text_queue: self.text = list(self.text_queue.pop(0)) if not self.cooldown and self.text: letter = self.text.pop(0) if letter == '\n': self.rect.move_ip((0, self.text_height)) self.rect.x = self.text_width else: self.board.add(letter, self.rect.topleft) self.rect.move_ip((self.text_width, 0)) self.cooldown = self.cooldowns.get(letter, 8) if self.cooldown: self.cooldown -= 1
主代码中调用新增的add_text方法添加文本:
cursor.add_text("""[i] Initializing ... [i] Entering ghost mode ... done ... """) cursor.add_text("""[Me] What you talking about? done ... """)
完整修改后代码示例
import pygame import os import time #Sets the width and height of the screen WIDTH = 320 HEIGHT = 240 #Importing the external screen os.putenv('SDL_FBDEV', '/dev/fb1') os.putenv('SDL_MOUSEDRV', 'TSLIB') os.putenv('SDL_MOUSEDEV', '/dev/input/touchscreen') #Initializes the screen - Careful: all pygame commands must come after the init pygame.init() clock = pygame.time.Clock() #Sets mouse cursor visibility pygame.mouse.set_visible(False) #Sets the screen note: must be after pygame.init() screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN) class Board(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.image = pygame.Surface((900,900)) self.image.fill((13,13,13)) self.image.set_colorkey((13,13,13)) self.rect = self.image.get_rect() self.font = pygame.font.Font('PressStart2P-Regular.ttf', 18) def add(self, letter, pos): s = self.font.render(letter, 1, (230, 230, 0)) self.image.blit(s, pos) class Cursor(pygame.sprite.Sprite): def __init__(self, board): pygame.sprite.Sprite.__init__(self) self.image = pygame.Surface((10, 20)) self.image.fill((255,255,255)) self.text_height = 34 self.text_width = 20 self.rect = self.image.get_rect(topleft=(self.text_width, self.text_height)) self.board = board self.text = [] self.text_queue = [] self.cooldown = 0 self.cooldowns = {'.': 12, '[': 18, ']': 18, ' ': 5, '\n': 30} def add_text(self, text): self.text_queue.append(text) def update(self): if not self.text and self.text_queue: self.text = list(self.text_queue.pop(0)) if not self.cooldown and self.text: letter = self.text.pop(0) if letter == '\n': self.rect.move_ip((0, self.text_height)) self.rect.x = self.text_width else: self.board.add(letter, self.rect.topleft) self.rect.move_ip((self.text_width, 0)) self.cooldown = self.cooldowns.get(letter, 8) if self.cooldown: self.cooldown -= 1 all_sprites = pygame.sprite.Group() board = Board() cursor = Cursor(board) all_sprites.add(cursor, board) # 添加两段文本到输出队列 cursor.add_text("""[i] Initializing ... [i] Entering ghost mode ... done ... """) cursor.add_text("""[Me] What you talking about? done ... """) #Main loop running = True while running: for e in pygame.event.get(): if e.type == pygame.QUIT: running = False all_sprites.update() screen.fill((0, 0, 0)) all_sprites.draw(screen) pygame.display.flip() clock.tick(60)
内容的提问来源于stack exchange,提问作者IWon Nerd
相关产品推荐
相关产品推荐

