游戏架构 游戏架构设计(5)





4.3、脚本语言解释

  在设计脚本语言之前,我们首先需要明白,我们的脚本语言要实现什么样的功能?否则随心所欲的做下去写出个C的解释器之类的也说不定。我们要实现的功能只是简单的逻辑判断和循环,其他所有的功能都可以由事先提供好的函数来完成。嗯,这样我们就可以列出一张工作量的表单:设计物件在底层的保存结构,提供脚本和底层间的访问接口,设计支持逻辑判断和循环的解释器。

  下面先来谈谈物件在底层的保存结构。具体到每种不同属性的物件,需要采用不同的结构,当然,如果你愿意的话,你可以所有的物件都采同同样的结构,然后在结构里面设计一个散列表来保存各种不同的属性。但这并不是一个好方法,过分的依赖散列表会让你的游戏的逻辑变得繁杂不清。所以,尽量的区分每种不同的物件采用不同的结构来设计。但是有一点值得注意的是,不管是什么结构,有一些东西是统一的,就是我们所说的物件头,那么我们怎么来设计这样一个物件头呢?

  typedef struct object_head_s
  {
    char* name;
    char* prog;
  }object_head_t;

  其中name是在散列表中这个物件的索引号,prog则是脚本解释器需要解释的程序内容。下面我们就以NPC为例来设计一个结构:

  typedef struct npc_s
  {
    object_head_t header;    // 物件头
    int hp;           // NPC的hp值。
    int level;          // NPC的等级。
    struct position_s position; // 当前的位置信息。
    unsigned int personality;  // NPC的个性,一个unsigned int可以保存24种个性。
  }npc_t;

  OK,结构设计完成,那么我们怎么来设计脚本解释器呢?这里有两种法,一种是用虚拟机的模式来解析脚本语言,另外一中则是用类似汇编语言的那种结构来设计,设置一些条件跳转和循环就可以实现逻辑判断和循环了,比如:

  set name, "路人甲";
  CHOOSE: random_choose_personality;  // 随机选择NPC的个性
  compare hp, 100;           // 比较气血,比较出的值可以放在一个固定的变量里面
  ifless LESS;             // hp < 100的话,则返回。
  jump CHOOSE;             // 否则继续选择,只到选到一个hp < 100的。
  LESS: return success;

  这种脚本结构就类似CPU的指令的结构,一条一条指令按照顺序执行,对于脚本程序员(Script. Programmer)也可以培养他们汇编能力的说。

  那么怎么来模仿这种结构呢?我们拿CPU的指令做参照,首先得设置一些寄存器,CPU的寄存器的大小和数量是受硬件影响的,但我们是用内存来模拟寄存器,所以想要多大,就可以有多大。然后提供一些指令,包括四则运算,寻址,判断,循环等等。接下来针对不同的脚本用不同的解析方法,比如说对NPC就用NPC固定的脚本,对ITEM就用ITEM固定的脚本,解析完以后就把结果生成底层该物件的结构用于使用。

  而如果要用虚拟机来实现脚本语言的话呢,则会将工程变得无比之巨大,强烈不推荐使用,不过如果你想做一个通用的网络游戏底层的话,则可以考虑设计一个虚拟机。虚拟机大体的解释过程就是进行两次编译,第一次对关键字进行编译,第二次生成汇编语言,然后虚拟机在根据编译生成的汇编语言进行逐行解释,如果大家对这个

你可能感兴趣的:(云计算,游戏开发,技术架构)