随便写点和游戏有关的设计模式感悟,本篇关于状态机(state)。state用途非常广,用来做某一类的行为管理非常方便。比如人物的移动状态:飞行、走路、奔跑、骑马,再比如相机的模式,聊天、拍照、3D、2D。这些状态都有一些共性,又有各自独立的逻辑,我们不可能到处switch case,各自的状态里处理自己的事情,外面用一个管理器来管理这些状态的进入、离开、刷新,所以就产生了state设计模式。(任何问题欢迎邮件:admin@franciswu.top)
state设计模式简单实现
#include <iostream>
#include <map>
using namespace std;
enum StateIndex
{
STATE_INDEX_NULL = 0,
STATE_A,
STATE_B,
STATE_MAX,
};
class state
{
public:
state(){};
virtual ~state(){};
virtual void entry() = 0;
virtual void leave() = 0;
virtual void print() = 0;
};
class stateA :public state
{
public:
stateA():state(){};
virtual ~stateA(){};
virtual void entry();
virtual void leave();
virtual void print();
};
void stateA::entry()
{
cout<<"进入状态A"<<endl;
}
void stateA::leave()
{
cout<<"离开状态A"<<endl;
}
void stateA::print()
{
cout<<"处于A状态"<<endl;
}
class stateB :public state
{
public:
stateB():state(){};
virtual ~stateB(){};
virtual void entry();
virtual void leave();
virtual void print();
};
void stateB::entry()
{
cout<<"进入状态B"<<endl;
}
void stateB::leave()
{
cout<<"离开状态B"<<endl;
}
void stateB::print()
{
cout<<"处于B状态"<<endl;
}
class StateController
{
public:
StateController();
~StateController();
bool StateInit();
bool StateSwitch(int iStateIndex);
void print();
private:
typedef std::map<int, state*> StateMap;
StateMap m_StateMap;
state* m_state;
};
StateController::StateController()
{
m_state = NULL;
}
StateController::~StateController()
{
StateMap::iterator it = m_StateMap.begin();
for (; it != m_StateMap.end(); ++it)
{
state* pState = it->second;
if (pState != NULL)
{
delete pState;
it->second = NULL;
}
}
}
bool StateController::StateSwitch(int iStateIndex)
{
StateMap::const_iterator c_it = m_StateMap.find(iStateIndex);
if (c_it != m_StateMap.end())
{
if (m_state != NULL)
{
m_state->leave();
}
m_state = c_it->second;
if (m_state != NULL)
{
m_state->entry();
}
}
return true;
}
bool StateController::StateInit()
{
m_StateMap.insert(make_pair(STATE_A, new stateA()));
m_StateMap.insert(make_pair(STATE_B, new stateB()));
return true;
}
void StateController::print()
{
if (m_state != NULL)
{
m_state->print();
}
}
int main()
{
StateController controllerTest;
//初始化状态
controllerTest.StateInit();
controllerTest.StateSwitch(STATE_A);
controllerTest.print();
controllerTest.StateSwitch(STATE_B);
controllerTest.print();
system("pause");
return 0;
}
实现起来很简单,也有很多方法,主要是要去习惯这种思路,很多东西都可以通过一种状态来进行管理,每个状态的处理本状态的事件(结合command模式)。
游戏中的使用
可以通过状态机来管理很多常见的游戏行为,比如人物行为,相机行为,简单AI,到目前为止接触过最有意思的是人物行为的管理。
对于多人在线游戏来说,同样的行为在不同玩家的客户端上处理是不一样的,简单来说,本客户端操作的主玩家在行走的时候,进入motion状态,而其他玩家客户端看到的我则会进入bemotion状态,主客户端处理motion下的行走,跳跃,转向,然后通过服务器将移动消息同步给其他客户端,其他客户端在bemotion中进行处理。