第十章 游戏剧情(Game Plot)
在大部分的RPG中,故事剧情是非常重要的。例如某些播放某些过场动画,人物台词等文字叙述的显示。这些可以推动整个游戏流程。
在Unity商店中,有一些剧情类的插件。我们编写的这个可以配合那些插件使用。
文章目录
三 文本剧本 (Text Script)
之前,我们已经介绍了关于剧本的内容。这一节我们来建立剧本类。
在这之前,我们规定将格式化方法(相当于非常缩水的词法分析器(Lexical Analyzer),没有按字符读取分析,甚至都不完整)也放入之中。当然,你也可以只保存每条命令的字符串,在运行时再格式化。
关于词法分析器(Lexical Analyzer)
关于更复杂的语法分析器(Syntactic Analyzer)与词法分析器(Lexical Analyzer)
如果你对它们感兴趣,可以看一看“yacc”,“lex”,“bison”等分析器。
我们在上一节已经创建好了剧本类:
namespace DR.Book.SRPG_Dev.ScriptManagement
{
/// <summary>
/// 剧本(脚本)
/// </summary>
public class TxtScript : IScenario
{
/// <summary>
/// 剧本的一条命令
/// </summary>
public class Command : IScenarioContent
{
// 省略
}
// TODO 剧本
}
}
在这一节中,我们来添加内容进去。
大致需要的程序集为:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions; // 可能需要正则表达式,如果你熟悉它的话
1 常量字符串(Constant String)
我们的剧本规定了:
-
每一条语句以
";"
分割; -
语句参数之间使用
[" ", "\t", "\n"]
来分割; -
注释使用
"//"
; -
标识符前缀为
"#"
。
则在TxtScript
中建立:
#region Const/Static
/// <summary>
/// 用于命令的分割符
/// </summary>
public const string k_CommandSeparator = ";";
/// <summary>
/// 空格
/// </summary>
public const string k_Space = " ";
/// <summary>
/// 分隔符
/// </summary>
public const string k_Separator = "\t";
/// <summary>
/// 换行符
/// </summary>
public const string k_NewLine = "\n";
/// <summary>
/// 注释前缀
/// </summary>
public const string k_CommentingPrefix = "//";
/// <summary>
/// 默认剧本标识前缀
/// </summary>
public const string k_DefaultFlagMark = "#";
#endregion
注意:我们在之前的Config中,换行符使用的是Enviroment.Newline
,它与"\n"
是有区别的。它的取值取决于你的平台,在Windows下,它表示"\r\n"
,而在Unix Like系统下,它表示"\n"
。在编程时选取"\n"
是更好的选择。Config中使用的并不多,你也可以进行更改。
2 字段与属性(Fields and Properties)
我们的字段与属性几乎完全是按照IScenario
来写的,只是我在这里加了额外变量:
-
m_Buffer
,它用于存储在格式化之前的文本,预留它可能会有用; -
m_FlagMark
,它用于存储当前的剧情标识符,你可能已经将#
作为了注释,那么它也要修改。 -
m_CommentingPrefix
,它用于存储当前注释前缀,有可能你更喜欢用#
表示注释。
字段(Fields):
#region Fields
private string m_Name;
private string m_Buffer;
private string m_FlagMark = k_DefaultFlagMark;
private string m_CommentingPrefix = k_CommentingPrefix;
private string m_Error = string.Empty;
private readonly List<Command> m_Commands = new List<Command>();
#endregion
属性(Properties):
#region Properties
/// <summary>
/// 剧本名(可能为null)
/// </summary>
public string name
{
get {
return m_Name; }
private set {
m_Name = value; }
}
/// <summary>
/// 剧本的原始副本
/// </summary>
public string buffer
{
get {
return m_B