Silverlight游戏开发心得(3)——有限状体机
状态转换表:用于组织状态和影响状态改变的良好机制
构建一个这样的状态转换表,会帮助你理清思路,明确逻辑。
内置的规则:
将状态转换规则嵌入到状态本身的内部。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Troll
{
class Program
{
static void Main(string[] args)
{
Tom tom = new Tom();
tom.currentState = new Sleep();
tom.IsThreatend = true;
tom.IsSafe = false;
string st = "";
Thread t1 = new Thread(() =>
{
while (true)
{
st = Console.ReadLine();
Console.WriteLine("Input:{0}", st);
tom.IsSafe = !tom.IsSafe;
tom.IsThreatend = !tom.IsThreatend;
}
});
t1.Start();
for (; ; )
{
Thread.Sleep(1000);
tom.Update();
}
}
}
public class Sprite
{
public virtual void Update()
{
}
}
public class Tom:Sprite
{
public State currentState;
public bool IsSafe;
public bool IsThreatend;
public void Update()
{
Console.WriteLine("IsSafe:{0} IsThreadtended:{1}", IsSafe, IsThreatend);
currentState.Execute(this);
}
public void ChangeState(State _newState)
{
currentState = _newState;
}
public void MoveAwayFromEnemy()
{
Console.WriteLine("Move Away");
}
public void Snore()
{
Console.WriteLine("Snore");
}
}
public class State
{
public virtual void Execute(Sprite _sprite)
{
}
}
public class RunAway : State
{
public override void Execute(Sprite _sprite)
{
Tom sprite = _sprite as Tom;
if (sprite.IsSafe)
{
sprite.ChangeState(new Sleep());
}
else
{
sprite.MoveAwayFromEnemy();
}
}
}
public class Sleep : State
{
public override void Execute(Sprite _sprite)
{
Tom sprite = _sprite as Tom;
if (sprite.IsThreatend)
{
sprite.ChangeState(new RunAway());
}
else
{
sprite.Snore();
}
}
}
}
当Tom的Update被调用的时候,反过来用this 这个指针指向自己,当作参数传给了当前状态,使得当前状态的执行方法(Execute())得以顺利操作。当前状态获得了Tom 全部状态,就可以根据具体的逻辑转换来做Tom在这个状态下应该做的事情。我们已经把状态作为一个独立的类封装了起来,这样显得简单的多,编码也简单,而且容易扩展。
我没有仔细看过设计模式里面的状态设计模式,不知道他们是否很像,或许目前这种做法并不完美,不过我已经觉得挺好了。
参考书籍 《游戏人工智能编程案例精粹》 [美] Mat Buckland 人民邮电出版社