设为首页 加入收藏

TOP

《游戏编程模式》(5)(一)
2017-10-13 10:40:12 】 浏览:4686
Tags:《游戏编程模式》

Chatper 11 字节码

通过将行为编码成虚拟机指令,而使其具备数据的灵活性。

 

解释器模式(慢):

 1 class Expression
 2 {
 3 
 4 public:
 5   virtual ~Expression() {}
 6   virtual double eva luate() = 0;
 7 
 8 };
 9 
10 class NumberExpression : public Expression
11 {
12 
13 public:
14   NumberExpression(double value)
15   : value_(value)
16   {}
17  
18   virtual double eva luate()
19   {
20     return value_;
21   }
22 
23 private:
24   double value_;
25 
26 };
27 
28 class AdditionExpression : public Expression
29 {
30 
31 public:
32   AdditionExpression(Expression* left, Expression* right)
33   : left_(left),
34     right_(right)
35   {}
36 
37   virtual double eva luate()
38   {
39     // eva luate the operands.
40     double left = left_->eva luate();
41     double right = right_->eva luate();
42  
43     // Add them.
44     return left + right;
45   } 
46 
47 private:
48   Expression* left_;
49   Expression* right_;
50 
51 };

 

字节码模式:

当你的游戏需要定义大量行为,可以指定一套指令集,虚拟机逐条执行指令栈上的这些指令。通过组合指令,即可完成很多高级指令。

 1 enum Instruction
 2 {
 3   INST_SET_HEALTH = 0x00,
 4   INST_SET_WISDOM = 0x01,
 5   INST_SET_AGILITY = 0x02,
 6   INST_GET_HEALTH = 0x03,
 7   INST_GET_WISDOM = 0x04,
 8   INST_GET_AGILITY = 0x05,
 9   INST_PLAY_SOUND = 0x06,
10   INST_SPAWN_PARTICLES = 0x07,
11   INST_LITERAL = 0x08,
12   INST_ADD = 0X09,
13 };
14 
15 class VM
16 {
17 
18 public:
19   VM()
20   : stackSize_(0)
21   {}
22  
23   void interpret(char bytecode[], int size)
24   {
25     for (int i = 0; i < size; i++)
26     {
27       char instruction = bytecode[i];
28       switch (instruction)
29       {
30          case INST_SET_HEALTH:
31          {
32               int amount = pop();
33               int wizard = pop();
34               setHealth(wizard, amount);
35               break;
36          } 
37 
38          case INST_SET_WISDOM:
39          case INST_SET_AGILITY:
40          // Same as above... 
41 
42          case INST_GET_HEALTH:
43          {
44               int wizard = pop();
45               push(getHealth(wizard));
46               break;
47          } 
48 
49          case INST_GET_WISDOM:
50          case INST_GET_AGILITY:
51          // You get the idea...
52 
53          case INST_PLAY_SOUND:
54               playSound(SOUND_BANG);
55               break;
56 
57          case INST_SPAWN_PARTICLES:
58               spawnParticles(PARTICLE_FLAME);
59               break;
60 
61          case INST_LITERAL:
62          {
63               // Read the next byte from the bytecode.
64               int value = bytecode[++i];
65               push(value);
66               break;
67          }
68  
69          case INST_ADD:
70          {
71               int b = pop();
72               int a = pop();
73               push(a + b);
74               break;
75          }
76     }
77   } 
78 
79 private:
80      void push(int value)
81      {
82          // Check for stack overflow.
83          assert(stackSize_ < MAX_STACK);
84          stack_[stackSize_++] = value;
85      }
86 
87      int pop()
88      {
89          // Make sure the stack isn't empty.
90          assert(stackSize_ > 0);
91          return stack_[--stackSize_];
92      }
93 
94      static const int MAX_STACK = 128;
95      int stackSize_;
96      int stack_[MAX_STACK]; 
97 
98 };

 

指令的组合:

1 setHealth(0, getHealth(0) + (getAgility(0) + getWisdom(0)) / 2);

翻译为:

 1 LITERAL 0    [0]            # Wizard index
 2 LITERAL 0    [0, 0]         # Wizard index
 3 GET_HEALTH   [0, 45]        # getHealth()
 4 LITERAL 0    [0, 45, 0]     # Wizard index
 5 GET_AGILITY  [0, 45, 7]     # getAgility()
 6 LITERAL 0    [0, 45, 7, 0]  # Wizard index
 7 GET_WISDOM   [0, 45, 7, 11] # getWisdom()
 8 ADD          [0, 45, 18]    # Add agility and wisdom
 9 LITERAL 2    [0, 45, 18, 2] # Divisor
10 DIVIDE       [0, 45, 9]     # Average agility and wisdom
11 ADD          [0, 54]        # Add average to current health
12 SET_HEALTH   []             # Set health to result

 

基于栈的虚拟机:

1.  指令小(通常一字节);

2.  指令数多

基于寄存器的虚拟机:

  1. 指令大(Lua虚拟机每个指令占用32位,6位存储指令类型,剩下的存储参数);
  2. 指令数少

值的表示:

  1. 坚持使用单一数据类型 or
  2. 使用带标签的联合体
 1 enum ValueType
 2 {
 3   TYPE_INT,
 4   TYPE_DOUBLE,
 5   TYPE_STRING
 6 }; 
 7 
 8 struct Value
 9 {
10   ValueType type;
11 
12   union
13   {
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Restful与webService区别 下一篇ASP.NET Zero--4.不使用谷歌字体..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目