You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

174 lines
5.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

"""
对话系统
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()