add ObServer for my game example

2015-04-05 刘太华 更多博文 » 博客 » GitHub »

-c++ -observer -game

原文链接 https://liutaihua.github.io/2015/04/05/add-ObServer-for-my-game-example.html
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。


游戏里有很多事件, 可能会随玩家, 或场景内某个物品或某个生物体的状态, 来触发这些事件。比如那种跟随主人走动的宠物,可以认为随主人的状态变更为STATE_MOVE来触发宠物的某个事件, 比如跟随主人,宠物类和宠物的AI类, 以及人物类, 均是独立的, 我们需要一个观察器来连接他们之间的关联:

{{% highlight c++ %}}

class CreatureObserver
{
public:
    CreatureObserver();
    ~CreatureObserver(){}
    void Observe(Creature *obj);
    fd::delegate<void(Creature*)> SigCreatureMoved; 
private:
    void ObserveCreature(Creature* pCreature);

    void OnCreatureMove(Creature* pCreature);
};

{{% endhighlight %}}

这个简化版的observer, 包含2个方法,被观察者注册上来的实现, 大体是这样: {{% highlight c++ %}}

Creature::Creature(enum ObjectType objType) :  //生物基类的构造函数
    m_pCreatureObserver(CnNew CreatureObserver)
{
    m_pStateMachine = new StateMachine(this);
    m_pCreatureObserver->Observe(this);
    m_pCreatureObserver->SigCreatureMoved.add(boost::bind(&Creature::OnCreatureMoved, this, _1));
}

{{% endhighlight %}} boost库的bind, 我将它看做是在Python里类似偏函数的一个函数再封装过程。 它被注册到观察器的SigCreatureMoved, 当SigCreatureMoved被调用时, 会触发回调Creature::OnCreatureMoved方法。 m_pCreatureObserver->Observe(this);它调用的实现如下, 意思是会让creatureobserver反向往creature类的SigMoved注册一个回调OnCreatureMove, 在OnCreatureMove会显示运行creatureobserver自己的SigCreatureMoved, 从而将creature和creatureobserver关联起来, 而其他类,如Pet, 如果想通过Observer来依照creature状态,触发事件, 则注册到指定的creatureObserver上, 比如这里是SigCreatureMoved. {{% highlight c++ %}}

void CreatureObserver::Observe(Creature* obj)
{
    ObserveCreature(obj);
}
void CreatureObserver::ObserveCreature(Creature* pCreature)
{
    pCreature->SigMoved.add(boost::bind(&CreatureObserver::OnCreatureMove, this, pCreature));
}

void CreatureObserver::OnCreatureMove(Creature* pCreature)
{
    std::cout<<"CreatureObserver::OnCreatureMove"<<"\n";
    SigCreatureMoved(pCreature);
}

{{% endhighlight %}}

{{% highlight c++ %}}

class Creature
{
    public:
        // ... 省略部分
        fd::delegate<void()> SigMoved;
        // ... 省略部分
{{% endhighlight %}}

整个过程还不是很丰满,我会把PetAI是如果根据Pet obj和Player Obj的状态变化,来实现自己的基本AI逻辑一起讲清楚。暂时先到这里了。