游戏中的有限状态机 (StateMachine)
/** * 状态机的组成主要是:状态机框架对象(我程序代码中的StateMachine)状态机中的三种状态eat,work,sleep * 状态机负责指挥这三种状态(甚至更多种状态)的变换,让他们是按照一定的先后顺序来走,符合我们的预期目的。 * 然后就是到底谁需要使用状态机呢,我程序里面有2个对象用到了状态机,分别是vokie和NBA. * 他们是通过"sm = new StateMachine(this);"这样一句代码来实现对状态机的绑定, * 他们各自拥有一个状态机,不过我这里偷懒了,用了很蹩脚的instanceof方法来做的,其实可以写成2个状态机 * 绑定以后,我们就可以在eat,work,sleep中处理Person跟Team对象了。 * @author Administrator * */
首先是可能存在的状态的接口定义:(基本的流程)
public interface IState {
public void enter(Object o);
public void excute(Object o);
public void exit(Object o);
}
状态机中包含的三种状态定义:
/**
* 吃饭状态机,任何绑定使用该状态机的对象(Person Team)都可以在StateMachine的指导下、完成吃饭状态
*
*/
public class EatState implements IState{
public EatState() {
}
@Override
public void enter(Object obj) {
if(obj instanceof Person)
{
Person p = (Person)obj;
System.out.println("Eat-1:煮饭~ 执行者:"+p.getName());
}else{
Team t = (Team)obj;
System.out.println("Eat-1:煮饭~ 执行者:"+t.getName());
}
}
@Override
public void excute(Object obj) {
if(obj instanceof Person)
{
Person p = (Person)obj;
System.out.println("Eat-2:吃饭~ 执行者:"+p.getName());
}else{
Team t = (Team)obj;
System.out.println("Eat-2:吃饭~ 执行者:"+t.getName());
}
}
@Override
public void exit(Object obj) {
if(obj instanceof Person)
{
Person p = (Person)obj;
System.out.println("Eat-3:洗碗~ 执行者:"+p.getName());
}else{
Team t = (Team)obj;
System.out.println("Eat-3:洗碗~ 执行者:"+t.getName());
}
}
}
public class WorkState implements IState{
public WorkState() {
}
@Override
public void enter(Object obj) {
if(obj instanceof Person)
{
Person p = (Person)obj;
System.out.println("work-1:上班~ 执行者:"+p.getName());
}else{
Team t = (Team)obj;
System.out.println("work-1:上班~ 执行者:"+t.getName());
}
}
@Override
public void excute(Object obj) {
if(obj instanceof Person)
{
Person p = (Person)obj;
System.out.println("work-2:工作~ 执行者:"+p.getName());
}else{
Team t = (Team)obj;
System.out.println("work-2:工作~ 执行者:"+t.getName());
}
}
@Override
public void exit(Object obj) {
if(obj instanceof Person)
{
Person p = (Person)obj;
System.out.println("work-3:下班~ 执行者:"+p.getName());
}else{
Team t = (Team)obj;
System.out.println("work-3:下班~ 执行者:"+t.getName());
}
}
}
public class SleepState implements IState{
public SleepState() {
}
@Override
public void enter(Object obj) {
if(obj instanceof Person)
{
Person p = (Person)obj;
System.out.println("Sleep-1:关灯~ 执行者:"+p.getName());
}else{
Team t = (Team)obj;
System.out.println("Sleep-1:关灯~ 执行者:"+t.getName());
}
}
@Override
public void excute(Object obj) {
if(obj instanceof Person)
{
Person p = (Person)obj;
System.out.println("Sleep-2:睡觉~ 执行者:"+p.getName());
}else{
Team t = (Team)obj;
System.out.println("Sleep-2:睡觉~ 执行者:"+t.getName());
}
}
@Override
public void exit(Object obj) {
if(obj instanceof Person)
{
Person p = (Person)obj;
System.out.println("Sleep-3:起床~ 执行者:"+p.getName());
}else{
Team t = (Team)obj;
System.out.println("Sleep-3:起床~ 执行者:"+t.getName());
}
}
}
需要使用到状态机的对象:Person & Team
public class Person {
private String name;
private StateMachine sm;
public Person(String name) {
this.name = name;
sm = new StateMachine(this);
sm.setState(new WorkState());
sm.getState().enter(this);
}
public StateMachine getStateMachine()
{
return sm;
}
public String getName() {
// TODO Auto-generated method stub
return name;
}
}
import java.util.ArrayList;
public class Team {
private ArrayList<String> nameList = new ArrayList<String>();
private StateMachine sm;
public Team(ArrayList<String> nameList) {
this.nameList = nameList;
sm = new StateMachine(this);
sm.setState(new WorkState());
sm.getState().enter(this);
}
public StateMachine getStateMachine()
{
return sm;
}
public String getName() {
StringBuilder sb = new StringBuilder();
for(String str:nameList)
sb.append(" | ").append(str);
return sb.toString();
}
}
然后是状态机这个大框架:
/**
* 从一种状态向另一种状态的转移,最常见的就是操作系统里面的状态图,游戏中也经常用到关于状态图
* 比如游戏中篮球运动员投篮的一套动作流程:运球->急停->起跳->投篮.
* 我这里用例是人一天的作息状态转换:工作->吃饭->休息
*/
class StateMachine
{
public IState currentState; //当前正在执行的状态
public IState previousState; //前一个状态
public Object owner; //状态机的拥有者,也就是说明该对象需要使用状态机的机制
public StateMachine(Object t_obj)
{
owner = t_obj;
currentState = null;
previousState = null;
}
public boolean excute()
{
if(currentState != null)
{
currentState.excute(owner);
return true;
}
return false;
}
//状态机改变状态
public boolean changeState(IState newState)
{
if(newState == null)
{
return false;
}
previousState = currentState; //保存当前的状态
currentState.exit(owner); //退出当前状态
currentState = newState;
currentState.enter(owner); //进入新的状态
return true;
}
public boolean reverseToPreviousState()
{
return changeState(previousState);
}
public void setState(IState state)
{
currentState = state;
}
public IState getState()
{
return currentState;
}
}
最后是测试代码:
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
Person vokie = new Person("vokie");
//执行工作状态机的excute方法
vokie.getStateMachine().excute();
//传入SleeState,让SleepState来处理person类中的变量等等
vokie.getStateMachine().changeState(new SleepState());
vokie.getStateMachine().excute();
vokie.getStateMachine().changeState(new EatState());
vokie.getStateMachine().excute();
vokie.getStateMachine().changeState(new WorkState());
vokie.getStateMachine().excute();
vokie.getStateMachine().changeState(new SleepState());
//下面测试代码的作用是想表达的是:状态机可以处理其拥有者owner的逻辑,变量
ArrayList<String> nameList = new ArrayList<String>();
nameList.add("Smith");
nameList.add("Kobe");
nameList.add("James");
Team NBA = new Team(nameList);
NBA.getStateMachine().excute();
//传入SleepState,让SleepState来处理Team类中的所有成员
NBA.getStateMachine().changeState(new SleepState());
NBA.getStateMachine().excute();
NBA.getStateMachine().changeState(new EatState());
NBA.getStateMachine().excute();
NBA.getStateMachine().changeState(new WorkState());
NBA.getStateMachine().excute();
NBA.getStateMachine().changeState(new SleepState());
}
}
运行结果:
work-1:上班~ 执行者:vokie work-2:工作~ 执行者:vokie work-3:下班~ 执行者:vokie Sleep-1:关灯~ 执行者:vokie Sleep-2:睡觉~ 执行者:vokie Sleep-3:起床~ 执行者:vokie Eat-1:煮饭~ 执行者:vokie Eat-2:吃饭~ 执行者:vokie Eat-3:洗碗~ 执行者:vokie work-1:上班~ 执行者:vokie work-2:工作~ 执行者:vokie work-3:下班~ 执行者:vokie Sleep-1:关灯~ 执行者:vokie work-1:上班~ 执行者: | Smith | Kobe | James work-2:工作~ 执行者: | Smith | Kobe | James work-3:下班~ 执行者: | Smith | Kobe | James Sleep-1:关灯~ 执行者: | Smith | Kobe | James Sleep-2:睡觉~ 执行者: | Smith | Kobe | James Sleep-3:起床~ 执行者: | Smith | Kobe | James Eat-1:煮饭~ 执行者: | Smith | Kobe | James Eat-2:吃饭~ 执行者: | Smith | Kobe | James Eat-3:洗碗~ 执行者: | Smith | Kobe | James work-1:上班~ 执行者: | Smith | Kobe | James work-2:工作~ 执行者: | Smith | Kobe | James work-3:下班~ 执行者: | Smith | Kobe | James Sleep-1:关灯~ 执行者: | Smith | Kobe | James

浙公网安备 33010602011771号