""" 对话系统 create by 狡猾的皮球 qq:871245007 2020年2月11日 13:46:55 """ import json import pygame from code.engine.sprite import Sprite, draw_src_outline_text, draw_rect_text from code.game_global import g class TalkManager: """ 游戏对话管理器 """ def __init__(self, surface): self.surface = surface # 渲染对话的surface self.switch = False # 对话系统开关 self.all_talk = dict() # 游戏中的所有对话 self.talk_id = -1 # 对话id self.talk_count = -1 # 对话进度 self.talk_script = None # 对话脚本 self.talk_length = -1 # 对话长度 self.face_img = None # 头像 self.current_text = "" # 当前对话的完整文字 self.current_show_text = "" # 当前显示的文字 # 显示文字的速度,10字/秒 self.show_speed = 10 / g.fps self.show_count = 0 # 头像绘制坐标 self.face_x = 0 self.face_y = 0 # 对话框绘制坐标 self.box_x = 0 self.box_y = 0 # 对话框宽度尺寸 self.box_width = 350 self.box_height = 150 # 加载所有对话文件 self.load() def load(self): """ 加载所有对话 """ with open('./resource/talk/total_talk.txt', 'r', encoding='utf8') as file: talk_id_list = file.readlines() talk_id_list = [line.split("'")[0].replace('\n', '') for line in talk_id_list] for talk_id in talk_id_list: with open(f'./resource/talk/{talk_id}.json', 'r', encoding='utf8') as file: self.all_talk[int(talk_id)] = json.loads(file.read()) def reset(self): """ 重置对话管理器 """ self.switch = False # 对话系统开关 self.talk_id = -1 # 对话id self.talk_count = -1 # 对话进度 self.talk_script = None # 对话脚本 self.talk_length = -1 # 对话长度 self.current_text = "" # 当前对话的完整文字 self.current_show_text = "" # 当前显示的文字 self.show_count = 0 # 逐字计数 def start(self, talk_id): """ 开始一个新对话 """ self.talk_id = talk_id self.talk_script = self.all_talk[talk_id] self.talk_length = len(self.talk_script) self.switch = True self.talk() def get_cur_info(self): """ 获取当前对话框以及头像位置信息 """ current_data = self.talk_script[self.talk_count] self.current_text = current_data["text"] self.current_show_text = "" self.show_count = 0 # 加载头像 if current_data["face"] != -1: self.face_img = pygame.image.load(f'./resource/PicLib/all_face/{current_data["face"]}.png').convert_alpha() face_w = self.face_img.get_width() face_h = self.face_img.get_height() else: # 如果没有头像,对话框就在窗口中间显示 face_w = 200 face_h = 250 # 在窗口最底部显示对话框 self.face_y = 480 - face_h self.box_y = 480 - self.box_height # 判断头像方向 if current_data["dir"] == "left": self.face_x = 0 self.box_x = face_w elif current_data["dir"] == "right": self.face_x = 640 - face_w self.box_x = self.face_x - self.box_width def talk(self): """ 对话 """ if not self.switch: return # 更新对话进度 self.talk_count += 1 if self.talk_count >= self.talk_length: self.reset() return # 获取当前对话信息 self.get_cur_info() # TODO:触发事件 pass def logic(self): """ 逐字显示逻辑 """ if not self.switch: return if self.current_show_text == self.current_text: return self.current_show_text = self.current_text[:int(self.show_count) + 1] self.show_count += self.show_speed if int(self.show_count) >= len(self.current_text): self.show_count = len(self.current_text) - 1 def render(self): """ 渲染对话框 """ if not self.switch: return # 画头像 if self.talk_script[self.talk_count]["face"] != -1: Sprite.blit(g.screen, self.face_img, self.face_x, self.face_y) # 画对话框 Sprite.draw_fill_rect(g.screen, self.box_x, self.box_y, self.box_width, self.box_height, (0, 0, 0, 210)) # 画名字 draw_src_outline_text(g.screen, self.box_x + 10, self.box_y + 5, self.talk_script[self.talk_count]["name"] + ":", g.fnt_talk, (255, 255, 255), (255, 127, 39)) # 画文字 draw_rect_text(g.screen, (255, 255, 255), self.current_show_text, g.fnt_talk, self.box_x + 10, self.box_y + 30, self.box_width - 25) def talk_next(self): """ 继续对话 """ if not self.switch: return if self.current_show_text != self.current_text: self.current_show_text = self.current_text else: self.talk()