第一种方式:
StatusBase.h
#pragma once
#ifndef ___STATUS_BASE_H_
#define ___STATUS_BASE_H_
class PlayerObj;
class StateBase
{
public:
virtual void execute(PlayerObj* machine) = 0;
};
#endif
StatusRest.h
#pragma once
#ifndef __STATE_REST_H_
#define __STATE_REST_H_
#include "StatusBase.h"
class PlayerObj;
class StateRest :public StateBase
{
public:
virtual void execute(PlayerObj*machine);
};
#endif
Status.cpp
#include "StateReset.h"
#include "StateCoding.h"
#include "PlayerStateMachine.h"
void StateRest::execute(PlayerObj*machine) {
if (machine->isWantToCoding()) {
machine->coding();
machine->changeState(new StateCoding());
}
}
StatusCoding.h
#pragma once
#ifndef __STATE_CODING_H_
#define __STATE_CODING_H_
class PlayerObj;
#include "StatusBase.h"
class StateCoding :public StateBase
{
public:
virtual void execute(PlayerObj*machine);
};
#endif
StatusCoding.cpp
#include "StateCoding.h"
#include "StateReset.h"
#include "PlayerStateMachine.h"
void StateCoding::execute(PlayerObj*machine) {
if (machine->isTire()) {
machine->rest();
machine->changeState(new StateRest());
}
}
PlayerStateMachine.h
#pragma once
#ifndef __PLAYER__STATE_MACHINE_H_
#define __PLAYER__STATE_MACHINE_H_
class StateBase;
#include "cocos2d.h"
USING_NS_CC;
class PlayerObj :public Node
{
public:
CREATE_FUNC(PlayerObj);
virtual bool init();
bool isTire();
bool isWantToCoding();
void rest();
void coding();
void changeState(StateBase*state);
virtual void update(float dt);
private:
StateBase* mState;
};
#endif
PlayerStateMachine.cpp
#include "PlayerStateMachine.h"
#include "StatusBase.h"
bool PlayerObj :: init() {
mState = NULL;
scheduleUpdate();
return true;
}
bool PlayerObj::isTire() {
return true;
}
bool PlayerObj::isWantToCoding() {
float ran = CCRANDOM_0_1();
if (ran < 0.1f) {
return true;
}
return false;
}
void PlayerObj::rest() {
log("resting");
}
void PlayerObj::coding() {
log("coding");
}
void PlayerObj::changeState(StateBase*state) {
CC_SAFE_DELETE(mState);
mState = state;
}
void PlayerObj::update(float dt) {
mState->execute(this);
}
第二种:
StatusBase.h
#pragma once
#ifndef ___STATUS_BASE_H_
#define ___STATUS_BASE_H_
class PlayerObj;
class StateBase
{
public:
virtual void execute(PlayerObj* machine) = 0;
};
#endif
StatusRest.h
#pragma once
#ifndef __STATE_REST_H_
#define __STATE_REST_H_
#include "StatusBase.h"
class PlayerObj;
class StateRest :public StateBase
{
public:
virtual void execute(PlayerObj*machine);
};
#endif
StatusRest.cpp
#include "StateReset.h"
#include "StateCoding.h"
#include "PlayerFSM.h"
#include "PlayerStateMachine.h"
void StateRest::execute(PlayerObj*machine) {
if (machine->isWantToCoding()) {
machine->coding();
machine->getFsm()->changeState(new StateCoding());
}
}
StatusCoding.h
#pragma once
#ifndef __STATE_CODING_H_
#define __STATE_CODING_H_
class PlayerObj;
#include "StatusBase.h"
class StateCoding :public StateBase
{
public:
virtual void execute(PlayerObj*machine);
};
#endif
StatusCoding.cpp
#include "StateCoding.h"
#include "StateReset.h"
#include "PlayerFSM.h"
#include "PlayerStateMachine.h"
void StateCoding::execute(PlayerObj*machine) {
if (machine->isTire()) {
machine->rest();
machine->getFsm()->changeState(new StateRest());
}
}
PlayerStateMachine.h
#pragma once
#ifndef __PLAYER__STATE_MACHINE_H_
#define __PLAYER__STATE_MACHINE_H_
class StateBase;
#include "cocos2d.h"
USING_NS_CC;
class PlyerFSM;
class PlayerObj :public Node
{
public:
CREATE_FUNC(PlayerObj);
virtual bool init();
bool isTire();
bool isWantToCoding();
void rest();
void coding();
virtual void update(float dt);
PlyerFSM*getFsm();
private:
PlyerFSM*mFsm;
};
#endif
PlayerStatusMachine.cpp
#include "PlayerStateMachine.h"
#include "StatusBase.h"
#include "StateReset.h"
#include "PlayerFSM.h"
bool PlayerObj :: init() {
mFsm = PlyerFSM::createWithPlyerObj(this);
mFsm->retain();
scheduleUpdate();
return true;
}
bool PlayerObj::isTire() {
return true;
}
bool PlayerObj::isWantToCoding() {
float ran = CCRANDOM_0_1();
if (ran < 0.1f) {
return true;
}
return false;
}
void PlayerObj::rest() {
log("resting");
}
void PlayerObj::coding() {
log("coding");
}
void PlayerObj::update(float dt) {
if (mFsm == NULL) {
return;
}
mFsm->changeState(new StateRest());
}
PlyerFSM *PlayerObj::getFsm() {
return mFsm;
}
PlayerFSM.h
#pragma once
#ifndef __PLAYER_FSM_H_
#define __PLAYER_FSM_H_
#include "cocos2d.h"
#include "StatusBase.h"
class PlayerObj;
USING_NS_CC;
class PlyerFSM :public Node
{
public:
static PlyerFSM* createWithPlyerObj(PlayerObj *obj);
bool initWithPlayerObj(PlayerObj*obj);
virtual void update(float dt);
void changeState(StateBase*state);
private :
StateBase*mState;
PlayerObj*mPlayer;
};
#endif
PlayerFsm.cpp
#include "PlayerFSM.h"
#include "PlayerStateMachine.h"
PlyerFSM* PlyerFSM::createWithPlyerObj(PlayerObj *obj) {
auto fsm = new PlyerFSM();
if (fsm&&fsm->initWithPlayerObj(obj)) {
fsm->autorelease();
}
else {
CC_SAFE_DELETE(fsm);
fsm = NULL;
}
return fsm;
}
bool PlyerFSM::initWithPlayerObj(PlayerObj*obj) {
mState = NULL;
mPlayer = obj;
return true;
}
void PlyerFSM::update(float dt) {
if (mState == NULL) {
return;
}
mState->execute(mPlayer);
}
void PlyerFSM::changeState(StateBase*state) {
CC_SAFE_DELETE(mState);
mState = state;
}