cocos:有限状态机

本文介绍了在Cocos2d-x游戏开发中如何使用两种不同的方式实现有限状态机(FSM)。首先展示了StatusBase.h文件的用法,接着详细说明了PlayerStateMachine.h和PlayerFsm.cpp在构建玩家状态机中的角色和实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一种方式:


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;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值