游戏Entity层通信机制:超越虚函数

    面向对象的程序设计模式无疑是成功的,虚函数机制对构造复杂系统无疑是非常有用的。但面对足够复杂的问题时,我们往往会需要更加强大的机制。 游戏的实体层的构造,就是其中一种可能的情况。

    有人会惊诧道:哪尼,传说中的XXL号的软件都可以完美地用OO实现,一个游戏逻辑会更复杂?莫急莫急,待我娓娓道来。话说从前有个程序,它有很多可能的事件需要子类定制处理,于是它就定义了很多的虚函数,但是每个子类通常只关心一小撮事件的处理,于是大部分的时间浪费在调用不能内联的空的虚函数上了,它的人生很空虚,于是它在和其它程序的比武中败阵下来。这就是最不重要的一个原因:空的虚函数开销。

    用虚函数机制最大的问题是耦合性,因为基类里必须为所有可能的事件定义虚函数,也就意味着本应该对游戏具体逻辑最无知的基类必须和游戏具体设计相关。相比而言,消息机制则有更大的灵活性,基类只需一个虚函数来处理一个消息,而不需要知道具体是什么消息,而且可以方便地广播分发给多个实体。用C写过Windows或XWindow程序的读者会立刻觉得很熟悉。但是,对高级一点的语言和应用开发框架,比如MFC/WinForm/WPF,这些API看起来是标准的一个事件一个虚函数的方式啊?这就是机制和表象的区别了。在底层,它是一套消息机制,在高层,可以把它包装成容易按OO方式理解的形式。MFC是用宏将消息映射到成员函数。WinForm是根据消息触发事件虚函数,基类Control只映射通用的事件虚函数,子类会映射自己专用的事件虚函数。WPF不使用操作系统的消息机制,而是有自己的消息系统,核心组件是Dispatcher类,它的消息定义和一个函数调用非常的类似,消息数据就是函数和调用参数。

    类似的,游戏实体层设计中,也有不同的消息机制实现。有人喜欢简单的switch枚举量(消息作为数据),有人喜欢把它包装得象函数调用(消息作为操作)。定义消息最原始的方式是:

struct Message
{
    MsgCode msg;
    int param1;
    int param2;
}

    缺点很明显:参数个数有限且需要类型转换。更OO的方式是定义一个消息类型继承系统:

class Message
{
public:
    virtual MsgCode getMsgCode() const = 0;
    virtual ~Message() {}
}

class UpdateMessage : public Message
{
public:
    MsgCode getMsgCode() { return MSG_UPDATE; }
    float TimeInterval;
}

    当然也有用C++流方式的,省去了为每个消息定义类型的麻烦,但也失去了类型检查:

Message msg;
msg << MSG_UPDATE << timeInterval;
SendMessage(msg);

    托管语言可以简单地用对象数组传递参数,将消息映射到类成员函数,而同时享有运行时参数类型检查:
MessageQueue.SendMessage(MsgCode.Update, timeInterval);

    脚本语言可以动态dispatch:
MessageQueue.SendMessage("Update", timeInterval);

    尽管方式各有不同,消息队列都是必定要有的,因为消息机制的另一个重要好处是可以支持异步处理和优先级。异步的极致是可以让游戏逻辑分配到多个线程并行,甚至多个server并行,并可以根据负载动态调整任务分配。异步不止意味着并行(Parallel),还有并发(Concurrent)。游戏逻辑中,经常有并发的需求,比如角色A走到角色B面前,和B说话,之后去桌上拿一本书,同时游戏其它部分照常运行,这可以通过响应消息的状态机实现,或者看起来更直观的coroutine。消息的优先级支持,还可以扩展到指定消息n秒后发送,以实现延时操作的功能。

    到此,我们回忆一下基本的面向对象概念中对象的几个基本元素:属性(property)、方法(method)、消息(message)。消息?!没错。我们过于熟悉C++等主流编程语言,以致忘记了OO的本来面貌。看看Objective C或Smalltalk等纯OO语言,就会发现消息在其中占的比重是多么的大。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值