您的位置:首页 > 移动开发 > Cocos引擎

cocos:有限状态机(消息驱动)

2016-04-01 21:07 591 查看
State.h

#pragma once
#ifndef __STATE__H_
#define __STATE__H_
#include "MessageEnum.h"
class GameObj;
class State
{
public:
virtual void execuete(GameObj*gameObj, MessageEnum messageEnum)=0;
};

#endif


RestState.h

#pragma once
#ifndef __REST_STATE_H_
#define __REST_STATE_H_
#include "State.h"
class RestState :public State
{
public:
virtual void execuete(GameObj*gameObj, MessageEnum messageEnum);
};

#endif


CodingState.h

#pragma once
#include "MessageEnum.h"
#include "State.h"
class GameObj;
class CodingState:public State
{
public :
virtual void execuete(GameObj*gameObj, MessageEnum messageEnum);
};


GameObj.h

#pragma once
#ifndef __GAME_OBJ__H
#define __GAME_OBJ__H
#include "cocos2d.h"
USING_NS_CC;
class FiniteStateMachine;
class GameObj :public Node
{
public:
CREATE_FUNC(GameObj);
virtual bool init();
void rest();
void coding();
virtual void update(float dt);
FiniteStateMachine*getFsm();
private:
FiniteStateMachine*mFsm;
};

#endif


FiniteStateMachine.h

#pragma once
#ifndef __FINITY_STATE_MACHINE_H
#define __FINITY_STATE_MACHINE_H
#include "cocos2d.h"
#include "State.h"
USING_NS_CC;
class GameObj;
class FiniteStateMachine :public Node
{
public:
~FiniteStateMachine();
static FiniteStateMachine*createWithGameObj(GameObj*gameObj);
bool initWithGameObj(GameObj*gameObj);
void changeState(State *state);
private:
State*mState;
GameObj*mGameObj;
void onRecvWantoRest(Ref*obj);
void onRecvWantoCoding(Ref*obj);
};
#endif


MessageEnum.h

#pragma once
#ifndef __MESSAGE_ENUM__H
#define __MESSAGE_ENUM__H

enum MessageEnum
{
EN_WantToCoding,
EN_WantToRest,
};
#endif


RestState.cpp

#include "RestState.h"
#include "FiniteStateMachine.h"
#include "CodingState.h"
#include "GameObj.h"
void RestState::execuete(GameObj*gameObj, MessageEnum messageEnum) {

switch (messageEnum)
{
case EN_WantToCoding:
gameObj->coding();
gameObj->getFsm()->changeState(new CodingState());
break;
case EN_WantToRest:
break;
default:
break;
}

}
CodingState.cpp

#include "CodingState.h"
#include "GameObj.h"
#include "RestState.h"
#include "FiniteStateMachine.h"
#include "MessageEnum.h"
void CodingState::execuete(GameObj*gameObj, MessageEnum messageEnum) {

switch (messageEnum)
{
case EN_WantToCoding:
break;
case EN_WantToRest:
gameObj->rest();
gameObj->getFsm()->changeState(new RestState());
break;
default:
break;
}

}


GameObj.cpp

#include "GameObj.h"
#include "FiniteStateMachine.h"
bool GameObj::init() {

mFsm = FiniteStateMachine::createWithGameObj(this);
return true;
}
void GameObj::rest() {
log("rest");
MessageBox("rest", "msg");
}
void GameObj::coding() {
log("coding");
MessageBox("coding", "msg");
}
void GameObj::update(float dt) {

}
FiniteStateMachine* GameObj::getFsm() {
return mFsm;
}


FiniteStateMachine.cpp

#include "FiniteStateMachine.h"
#include "GameObj.h"
#include "MessageEnum.h"
#define NOTIFY NotificationCenter::getInstance()
FiniteStateMachine:: ~FiniteStateMachine() {

NOTIFY->removeAllObservers(this);

}

FiniteStateMachine*FiniteStateMachine::createWithGameObj(GameObj*gameObj) {

FiniteStateMachine *fsm = new FiniteStateMachine();

if (fsm&&fsm->initWithGameObj(gameObj)) {
fsm->autorelease();
}
else {
CC_SAFE_DELETE(fsm);
fsm = NULL;
}
return fsm;
}

bool FiniteStateMachine::initWithGameObj(GameObj*gameObj) {

mState = NULL;
mGameObj = gameObj;

NOTIFY->addObserver(
this,
callfuncO_selector(FiniteStateMachine::onRecvWantoCoding),
StringUtils::toString(EN_WantToCoding),
NULL);

NOTIFY->addObserver(
this,
callfuncO_selector(FiniteStateMachine::onRecvWantoRest),
StringUtils::toString(EN_WantToRest),
NULL);
return true;
}

void FiniteStateMachine::changeState(State *state) {
CC_SAFE_DELETE(mState);
mState = state;
}

void FiniteStateMachine::onRecvWantoRest(Ref*obj) {
if (mState == NULL||mGameObj==NULL) {
return;
}
mState->execuete(mGameObj, EN_WantToRest);
}

void FiniteStateMachine::onRecvWantoCoding(Ref*obj) {
if (mState == NULL||mGameObj==NULL) {
return;
}
mState->execuete(mGameObj, EN_WantToCoding);
}


使用:

auto player = GameObj::create();
player->getFsm()->changeState(new RestState());

NotificationCenter::getInstance()->postNotification(StringUtils::toString(EN_WantToCoding), NULL);
addChild(player);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: