Kinect超时按钮实现 – 基于qfFSM有限状态自动机类库
qfFSM有限状态自动机类库目前拥有C++、C#、Java、JavaScript版本,对于同一份UML状态图,不同语言均可用qfFSM来实现。
本文使用JavaScript版本在浏览器中实现一个超时按钮,为方便测试,我使用鼠标指针来模拟Kinect关节,接入Kinect数据后,只需将手部关节坐标替换进来即可。
首先看超时按钮的UML状态图:
主状态机中有STATE_Normal、STATE_PointIn、STATE_PointOut三个状态,其中后面两个作为子状态机存在,他们内部分别含有3个状态:激活/非激活开始状态、正在激活/非激活状态、已激活/非激活状态。
设计 正在激活/非激活状态 是为了配合相应动画机制,如经典的按钮注水、按钮转满一周等计时方式。
事件方面支持UserLeave、PointIn、PointOut,以及MultiActive(多次连续激活)。
MultiActive机制可以很方便的实现 保持按住按钮,系统会周期触发某个事件。
源码中分为以下几个部分:
1、首先定义了各种常量:状态名称、事件名称、属性名称:
var timeoutButton_const_def = { … };
2、定义数据模型Model实现类:
var TimeoutButton_Model = { … };
在Model中定义各种属性,如激活时间、指针是否在对象可视范围内、计时器开始和结束。
3、定义各个子状态机、状态的实现类,他们分别继承自qfStateMachine/qfState基类,并实现doAction()事件:
var State_Normal = { … };
var STATE_PointIn = { … };
var STATE_PointOut = { … };
var STATE_Active_start = { … };
var STATE_Activing = { … };
var STATE_Actived = { … };
var STATE_DeActive_start = {… };
var STATE_DeActiving = { … };
var STATE_DeActived = { … };
4、定义了主逻辑状态机,继承自qfFsmLogic基类:
var timeoutButton_Logic = { … };
其中核心方法为状态机初始化函数(initTimeoutButtonMachine()成员函数),包含三个方面:
1)设置状态机环境变量,此处只设置数据模型Model,以便各个状态获取数据属性。
2)实例化各个子状态机、状态,并绑定到各自父状态机中。
3)配置状态转移规则,这里完成对UML状态图的描述翻译。
5、实例化主逻辑状态机,并调用他的start()方法:
var timeoutButton = timeoutButton_Logic.createNewInstance();
timeoutButton.start();
6、绑定mouseover、mouseout事件,完成OnTimer()函数,将来的Kinect数据获取也是一个周期性事件,直接放在此处即可。
7、最后是界面的Html代码,其中包含一个多次激活标志checkbox、还有一个支持超时激活的按钮(DIV实现),如下图:
其中Current State为状态机当前状态,可以实时看到状态转移过程。
实现DEMO展示Url:qfFSM_for_javascript_kinect_timeoutButton
源代码右键查看即可。
qfFSM各版本源码下载:http://www.YuYuYouEr.cn/blog/?p=290