cocos2d-x 游戏开发之有限状态机(FSM) (三)
有限状态机简称FSM,现在我们创建一个专门的FSM类,负责管理对象(Monkey)的状态。然后Monkey类就实现了行为与状态分离。Monkey类只负责自己的行为,MonkeyFSM作为Monkey的成员,负责状态调度。MonkeyFSM调用状态模式类的方法,状态模式类调用真实对象Monkey的方法。注意本文例子代码只是为了说明问题,并不能真正用于实际当中。其中Monkey与MonkeyFSM互相保存对方的指针,存在循环引用问题。
代码部分:
MonkeyFSM:
// MonkeyFSM.h // #ifndef MONKEY_FSM_H_ #define MONKEY_FSM_H_ #include "cocos2d.h" USING_NS_CC; #include "State.h" class Monkey; class MonkeyFSM : public Node { public: MonkeyFSM() { _monkey = 0; _state = 0; log("MonkeyFSM()"); } static MonkeyFSM * createObject(Monkey * mk) { MonkeyFSM * fsm = new MonkeyFSM(); fsm->initWithMonkey(mk); return fsm; } bool initWithMonkey(Monkey * mk) { _monkey = mk; return true; } void changeState(State * newState) { State * oldState = _state; _state = newState; if (oldState) { delete oldState; } } virtual void update(float dt) { if (_state) { _state->execute(_monkey); } } private: State * _state; Monkey * _monkey; }; #endif // MONKEY_FSM_H_
Monkey:
#ifndef MONKEY_H_ #define MONKEY_H_ #include <time.h> #include "cocos2d.h" USING_NS_CC; #include "MonkeyFSM.h" #define MAX_STOP_TIME 10 #define MAX_WALK_TIME 20 #define MAX_WALK_DIST 100 class Monkey : public Node { public: Monkey() { log("Monkey()"); } CREATE_FUNC(Monkey); virtual bool init() { _curPos = 0; _step = 1; _fsm = MonkeyFSM::createObject(this); this->scheduleUpdate(); return true; } void stop() { cocos2d::log("stop()"); } void walk() { _curPos += _step; cocos2d::log("walk(): pos=%d", _curPos); } void turn() { _step *= -1; cocos2d::log("turn(): step=%d", _step); } MonkeyFSM * getFSM() { return _fsm; } void update(float dt) { if (_fsm) { _fsm->update(dt); } } private: MonkeyFSM * _fsm; time_t _curTime; int _curPos; int _step; public: bool isStopTimeout() { return (time(0) - _curTime > MAX_STOP_TIME); } bool isWalkTimeout() { return (time(0) - _curTime > MAX_WALK_TIME); } bool isWalkOutBorder() { return (_curPos > MAX_WALK_DIST || _curPos < -MAX_WALK_DIST); } }; #endif // MONKEY_H_
状态模式类,.h文件没有变化:
// State.h // #ifndef STATE_H_ #define STATE_H_ class Monkey; struct State { virtual void execute(Monkey *mk) = 0; }; #endif // STATE_H_
// WalkState.h // #ifndef WALK_STATE_H_ #define WALK_STATE_H_ #include "State.h" #include "Monkey.h" class WalkState : public State { public: virtual void execute(Monkey *mk); }; #endif // WALK_STATE_H_
// WalkState.cpp // #include "WalkState.h" #include "TurnState.h" #include "StopState.h" void WalkState::execute(Monkey *mk) { mk->walk(); if (mk->isWalkOutBorder()) { mk->getFSM()->changeState(new TurnState()); mk->turn(); } else if (mk->isWalkTimeout()) { mk->getFSM()->changeState(new StopState()); mk->stop(); } }
时间: 2024-10-29 19:06:49