必威体育Betway必威体育官网
当前位置:首页 > IT技术

SRPG游戏开发(四十三)第十章 游戏剧情 - 一 剧本规则 (Rule of Scenario)

时间:2019-10-16 15:43:19来源:IT技术作者:seo实验室小编阅读:85次「手机版」
 

游戏剧本

返回总目录

第十章 游戏剧情(Game Plot)

在大部分的RPG中,故事剧情是非常重要的。例如某些播放某些过场动画,人物台词等文字叙述的显示。这些可以推动整个游戏流程。

在Unity商店中,也有一些剧情类的插件。你可以单独使用它或单独使用我们编写的,也可以配合一起使用。


文章目录

  • 第十章 游戏剧情(Game Plot)
    • 一 剧本规则 (Rule of Scenario)
      • 1 剧本说明(Scenario Description)
      • 2 命令的选择(Selection of commands)
      • 3 命令(Commands)


一 剧本规则 (Rule of Scenario)

在游戏中可以使用“剧本”(或称“故事大纲”),制作好它并使用程序执行,可以让故事发展下去,或产生事件


1 剧本说明(Scenario Description)

能够用程序解释的剧本在格式方面有着严格的规定,而且还存在 条件分支语句(例如游戏中剧情选项) ,这跟电影电视剧)故事大纲(或剧本)有着非常大的差距。它更倾向于“程序语言”。

撰写游戏专用的剧本,应该先有一个“游戏专用的剧本语言”。用它来写出含有可被执行命令的“剧本”。这听起来更接近于解释型语言(例如Python,Lua等),我们称它为脚本(script)。 它不仅可以使用现有的语言,也可以自创语言,而“如何执行它们”才是我们需要做的。

关于编译型语言与解释型语言

  • 百度百科-编译型语言

  • 百度百科-解释型语言

例如,假设可执行命令text表示显示对话,map表示进入地图,if表示条件判断语句,goto表示跳转到剧本的位置,那么:

  • 使用xml格式:

    <?xml version="1.0" encoding="utf-8"?>
    <GameScript name="myScript">
        <contents>
            <TextCommand code="text" position="0" value="你是谁"/>
            <TextCommand code="text" position="1" value="我是主角"/>
            <MapCommand code="map" name="map0" resultVar="map0result"/>
            <IfCommand code="if" var="map0" op="==" value="0" next="goto" flag="lose"/>
        </contents>
    </GameScript>
  • 使用txt格式:

    text 0 你是谁;
    text 1 我是主角;
    map map0 map0result; // 进入地图map0
    if map0result == 0 goto lose; // 如果 map0result == 0,失败了,去lose
    

上面的例子中,表示了两个人对话后进入关卡地图的例子。

这个例子之中,在text中有几个变量:

  • code表示命令关键字,类似C#语言中的intstring

  • position表示文本显示的位置,例如屏幕上边,左边,右边或下边(当然你也可以增加参数使用坐标xy);

  • value表示要显示的文本。

同样的,在mapif中:

  • code表示命令关键字;

  • name表示地图名称;

  • resultVar表示地图是否胜利的标识符名称;

  • varopvalue表示条件判断语句;

  • next表示下一条命令关键字;

  • flag表示goto语句跳转的剧本标识。

就是用类似这种的剧本去推动故事。剧本是用“命令”的形式把必要的功能加到故事中,例如配合故事情节显示菜单选项,切换背景,播放过场动画等。当游戏进行到该命令的部分时,就要执行相应命令。

而语言方面,不限于使用xmltxt的格式,也可以使用任意一种解释型语言。这也就是之前说的, 不限于使用哪种格式,而重要的是“如何执行它们(如何解释它们)”。

而且要记住,在制作这门语言时, 最重要的是制定规则。


2 命令的选择(Selection of Commands)

在指定规则时,我们首先要考虑的就是命令(游戏主要要执行的命令),也就是说我们的剧本有什么样的功能。

在初期,我们考虑的可能不是那么全面,不过不要紧,在之后可以添加。

  • 首先,是一些基础的功能:

    名称(Name) 常用代码(Code) 说明(Description)
    命令分隔符 ;, \n, <eoc>(end of command) 分割语句
    注释 //, ;, # 注释掉后面的内容
    剧情标识符 #, *, $ 可用于跳转剧情
    变量 var, int 生成一个整形变量
    计算 calc 计算变量的值
    条件 if 用于变量判断
    跳转 goto 用于跳转剧情到标识符
    切换 exec, load script 切换脚本
  • 其次,是一些在大部分J-AVG或RPG游戏中都有的功能:

    名称(Name) 常用代码(Code) 说明(Description)
    文本 text 用于显示对话或文本
    菜单 menu 用于显示菜单或选项
    图像相关 load image, show image 图像,CG,动画,特效等操作
    音乐相关 music, sound 用于控制音乐,音效
    暂停剧情 pause, sleep 用于剧本的暂停(等待玩家其它操作后激活)或指定暂停时间延迟后继续剧本
  • 最后,其它一些功能,例如进入哪张地图,移动物体(例如摄像机)等。

这些功能都不是必须的,因为这些都是为我们的游戏服务的,具体要用到哪些主要还是看我们的游戏需求。

为了更加了解它的运行机制,我们采用txt编写它,从零到有的创建一门“专属游戏语言”。

我们规定命令格式:

keycode [param0 [param1 [param2 ...]]]; // code commenting
  • 先写出代码关键字: code

  • 然后以空格" "作为分隔符写上参数: param0 params1 ...

  • 每个命令以“;”分隔符区分;

  • 最后是注释//,其后可以接注释内容。

我们创建的语言,并不要求每一行都是一条命令,而是以;表示一条命令。如果你对行号非常的关注,更建议每一行一条命令,并且以换行符\n表示一条命令。


3 命令(Commands)

我们找一些典型的命令,来看它们的写法。

  • 命令分隔符;与注释//

    这个很好理解,与一些程序语言相同:

    我是命令 我是参数; // 我是注释 
    

    也可以与Python相同:

    我是命令 我是参数 # 我是注释,在这里没有`;`,且一行是一个命令
    
  • 创建变量var

    这个也很好理解,就是生成一个整形变量。

    var a = 1;
    var b = 2;
    var c = -1;
    

    要注意的是,这里不能写成var a=1;(下同),这是由格式化方法决定的,我在C#中读取字符串格式化中使用了[" ", "\t", "\n"]分割参数。如果你需要这种“紧贴式”写法,你需要按单个字符读取并格式化。

    为什么只用整形变量?

    我们这个不是一个复杂的编程语言,只是为了专门写剧本。

    一个整形变量就可以了,可以替代bool(0和1);也可以进行条件判断。

    而其它类型变量,比如字符串,浮点数等几乎用不到。

  • 计算变量calc

    计算在这里,我们规定只使用基本的四则运算,也就是没有括号,运算不能超过两个数字。这足够我们使用了。

    var num0 = 1;
    var num1 = 20;
    calc num0 += 10;
    calc num0 = num0 * num1;
    

    注意:这里同样不能写成calc num0+=10;,理由同var

    当然,如果你觉得不够,可以更改解释器支持更复杂或更多数字的运算,使用逆波兰表达式(Reverse Polish Notation)是比较不错的,几乎所有的二元运算都可以用它解决。

    // 如果使用逆波兰表达式,那么多数情况只需要一个运算表达式参数
    // 注意这里只有一个keycode和一个参数(运算表达式),并不是按单个字符读取。
    calc num0=num1*(num2+20)/5; // keycode RPN;
    
  • 剧情标识符#

    剧情标识符的作用是标记剧本位置,根据变量跳转剧情时使用。

    例如(这里使用#,如果你使用Python形式,可以使用*$):

    #标识符1
    #标识符2
    
  • 条件判断if与跳转剧情goto

    我们这里规定if语句后接goto语句,可以做条件判断,然后跳转到标签。

    if语句判断暂时包含:[==, !=, >, >=, <, <=]

    例如:

    var option = 0; // 建立变量
    
    // 影响option数值的剧情
    
    if option == 1 goto #分支剧情1;
    if option >= 2 goto #分支剧情2; // 相当于 else if
    goto #分支剧情else; // 相当于 else
    goto #条件结束;
    
    #分支剧情1; // option == 1
    // 标识符1分支剧本
    goto #条件结束;
    
    #分支剧情2; // option >= 2
    // 标识符2分支剧本
    goto #条件结束;
    
    #分支剧情else; // option < 1
    //else标识符分支剧本
    goto #条件结束;
    
    #条件结束;
    // 之后剧本
    
    

    这看起来并不是特别难以理解,在C#中的代码对应为:

    public static Class IfGoto
    {
        public static void ExecuteIfGoto()
        {
            int option = 0;
            // 省略影响option数值的剧情
            if (option == 1) 分支剧情1();
            else if (option >= 2) 分支剧情2();
            else 分支剧情else();
    
            // 条件结束后的剧情
        }
    
        private static void 分支剧情1(){}
        private static void 分支剧情2(){}
        private static void 分支剧情else(){}
    }
    

    就像上一个例子中展示的,goto语句也可以单独使用:

    goto #标识符2
    
    #标识符1;
    // 标识符1与标识符2之间的语句不执行
    
    #标识符2;
    // 这里的语句执行
    
  • 切换剧本exec

    将正在执行的剧本停止,并执行另一个剧本。

    例如,当前执行剧本为script1,需要在中途执行另一个剧本script2

    // 当前剧本为script1
    exec script2; // 这将暂停script1,并执行script2
    
  • 显示文本text

    在显示文本时有多种方式,根据你的游戏自定义。

    两个例子:

    • 固定文本UI,传入位置与文本:

      text Top // 顶部位置,`Top`在C#中,用枚举会比较好,比如 WindowDir.Top
          文本行0
          文本行1
          等等...;
      
    • 传入坐标与文本参数:

      text 200 200 100 100 // 文本窗口:X坐标200,Y坐标200,宽度100,高度100
          文本行0
          文本行1
          等等...;
      

    注意1:关于是否使用"'把文本括起来,这取决于你在C#中编写的格式化方法或解释器方法。

    注意2:我们的游戏文本都存储在一个txt文件中,所以参数应该会用数字id,并不会像例子中使用字符串。

  • 菜单选项menu

    菜单选项是非常常见的,比如大部分J-AVG跳出选项,或者RPG对话中给出选项。

    菜单选项常与ifgoto连用:

    // `menuOption`是记录选择的哪个选项的变量名,
    //      在C#中,应在每次打开菜单时重置为不在选项中的默认值
    //      选项如果从0开始,默认值最好为-1
    //      选项如果从1开始,默认值最好为0
    // `Vertical` 表示垂直的选项,
    //      在C#中,最好也用枚举来表示
    //      Horizontal, Vertical, Grid
    //      当然,有没有它也取决于你的解释器
    menu menuOption Vertical 
        选项文本1
        选项文本2
        ...选项文本n;
    
    if menuOption == 1 goto #menuOption1;
    if menuOption == 2 goto #menuOption2;
    goto #menuOptionEnd;
    
    #menuOption1;
    // 选择1的剧本
    goto #menuOptionEnd;
    
    #menuOption2:
    // 选择2的剧本
    goto #menuOptionEnd;
    
    #menuOptionEnd;
    // 结束
    

在这些例子中,脚本的格式与应用已经比较全面,不再举例其它命令。

其它命令与上面所述的内容大同小异。

最重要的还是你的解释器如何格式化文本与如何规定参数。

等到编写时,再按需添加其它命令。


相关阅读

ACM数论----连分数问题

Description 一个高为n的连分数定义为 。 给出2个数,一个用p/q的方式表达,另一个用高度为n的连分数来表示,请你判断他们是否相等。

ER图(实体-联系图Entity Relationship Diagram)

https://blog.csdn.net/k3108001263/article/details/89578515

记一次现金流游戏

作为程序员,往往思想比较单一,一直以理工科的思维来思考这个世界。有时候要跳槽程序这个圈子,让自己的身心做个旅行。前段日子,请假出

Windows7下游戏全屏 发烧友设置最简法

Windows7下游戏全屏 发烧友设置最简法 核心提示:Windows系统的注册表是一个管理功能强大的配置表单,在这里,用户可以尝试到去用很简

勒索病毒已被破解:病毒开发者身份疑似曝光

A5创业网(公众号:iadmin5)12月6日报道,本月初,一种新型的勒索病毒在国内爆发,该病毒采用&ldquo;供应链感染&rdquo;方式进行传播,通过论坛

分享到:

栏目导航

推荐阅读

热门阅读