项目希望能够实现一些剧情动画,类似角色移动,镜头变化,台词展现等.剧情动画这东西随时需要修改调整,不能写死在代码里.考虑之后认为需要做一个简单的DSL来定制剧情脚本,策划在脚本里按顺序写入命令,然后我们解释命令执行即可.

  项目的很多功能系统并没有能够实现导入lua中,非我所能决定,若可以则使用lua方便不少.因此我决定使用C++来制作这个剧情脚本DSL.

  使用boost的spirit来负责脚本的解析,使用asio的coroutine简化了指令处理逻辑.

  DSL当然不能太复杂,第一个版本看起来类似:

role_walk	LEFT		100;
role_dialog	"stop!!!"	4;
role_jump	FORWARD;
role_walk	RIGHT		200;
monster_dialog	"byebye!!!"	2;
monster_run	RIGHT		400    
role_walk	RIGHT		500;
role_jump	BACK;   

  稍加按上边指令流程走下来,会发现一些指令是有延时性的.比如走,跑等,都需要移动到目标地点才算结束.当遇到这个指令时,我们是继续往下解析指令,还是在当前指令阻塞呢?遇到指令立即解析执行,那很可能在一帧里就把脚本的所有指令都执行完毕了,本来30秒的剧情在不到1/60秒里结束了.如果遇到延时性指令立即阻塞呢,会遇到可能有几条延时性指令同时开始的场景.因此决定再加上一个规则,使用方括号括起来的脚本指令,将强制同时执行,第二版本如下:

role_walk	LEFT		100;
role_dialog	"stop!!!"	4;
role_jump	FORWARD;
role_walk	RIGHT		200;
monster_dialog	"byebye!!!"	2;
[
monster_run	RIGHT		400    
role_walk	RIGHT		500;
]
role_jump	BACK;    

 至此我认为脚本的规则能适应足够多场景了.该脚本暂不需要控制结构,控制条件在脚本进行时都预先知道了.

 这是脚本解析代码.

#ifndef __MovieCommandAST_H__
#define __MovieCommandAST_H__

#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/variant/variant.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/fusion/include/std_pair.hpp>

namespace MovieScript
{
    typedef boost::variant<std::string, int, float>        ArgType;
    typedef std::vector<ArgType>                        ArgList;

    namespace Parser
    {
        struct command_atom
        {
            std::string        cmd;
            ArgList            args;
            command_atom():cmd("") {}
        };

        struct command_flow;
        typedef boost::variant<boost::recursive_wrapper<command_flow>, command_atom> command_unit;

        typedef std::list<command_unit> CommandUnitList;

        struct command_flow
        {
            CommandUnitList cmd_flow;
        };

    }
}

BOOST_FUSION_ADAPT_STRUCT
(
MovieScript::Parser::command_atom,
(std::string, cmd)
(MovieScript::ArgList, args)
)

BOOST_FUSION_ADAPT_STRUCT
(
MovieScript::Parser::command_flow,
(MovieScript::Parser::CommandUnitList, cmd_flow)
)


#endif
View Code

相关文章:

  • 2021-06-13
  • 2022-12-23
  • 2021-05-27
  • 2021-07-05
  • 2022-12-23
猜你喜欢
  • 2021-08-23
  • 2021-06-24
  • 2021-12-18
  • 2022-12-23
  • 2021-12-10
  • 2022-12-23
相关资源
相似解决方案