| 编辑推荐: | 
                                   
                                   
                                    本文主要介绍如何使用状态机模型进行开发,希望可以让大家有个新的认识。 
                                        本文来自于awflasher.com,由火龙果软件Alice 编辑、推荐。 
                                     | 
                                   
                                  | 
                             
                           
其实在数字电路中就已经介绍过这种模型,包括后续的“信息论”、“随机过程”等课程中,也介绍到了这个模型中的一些基本概念。可是平时在课堂上学过了,没有实际应用确实难以记住。这次在师弟Xophiix(http://www.xophiix.com.cn)处看到状态机一文,发现确实能将这一概念运用到Flash的交互开发中。Xophiix虽然仅仅是大二的学弟,但是有着非常强烈的创新欲望和实践经验。所谓三人行必有我师,这次这个“状态机”,确实帮了我那个挫的不能再挫的“是男人就下100层”的大忙。 
言归正传,来介绍如何使用状态机模型进行开发。 
首先,要明确什么叫做状态(Status)。我不想引用什么字典里的解释,那样只会将这里的问题复杂化。举例说明最方便。就拿我这个游戏来说,玩家所扮演的小人,就存在三种状态:小人跑动(move)、小人站立静止(stand)、小人在空中坠落(falling)。为了配合下面的代码实例,我简记为move, stand, falling,下同。图中分别用橘黄标示为A,B,C。 
  
状态的一大特性就是转化。状态不是孤立的,换句话说,状态是变化的,是会互相转化的,比如,move可以转化到falling;falling可以转化到stand。 
值得一提的是,转化有两条原则: 
·转化本身的逻辑性 - 并非所有的状态之间都可以任意转化,这里stand就不能变化为falling,因为小人不可能站在挡板上不动自己掉下;而falling也不能转化为move,因为小人掉下的途中不可能跑动(脚踩空),而必须通过一次stand,再跑动。 
转化的外界因素 - 转化的时候需要一个外因,这里四种转化,我用数字表示为1,2,3,4,意义分别是 
1、移动出了挡板,从空中坠落 
2、坠落途中掉在挡板上,站立 
3、用户按左、右键,或者掉在了有“方向履带”的挡板上,小人跑动起来 
4、用户停止按键并且小人站在非“方向履带”的挡板上,小人站立 
这两条原则总结完了之后,就好设计程序了。但是在设计程序之前,一定要把这几个状态以及转换原则疏理清晰,如果你连一共有几种状态都分不清楚就开始写代码,那肯定有更多的麻烦等着你。 
while-switch的方法可能是VC程序员最熟悉的了,前文提到的Xophiix的blog中可以看到。不过在Flash中,还是onEnterFrame-switch比较方便。毕竟Flash是按frame渲染的,用onEnterFrame的循环在资源消耗上有着很大的优势。代码如下,保留了整个小人的Action,状态机核心在中间加粗部分: 
							
                            
    getPlayer.onEnterFrame = function() 
      {  
       
      if (this.isTowardLeft == undefined) 
      { 
      // 是否站在履带上 
      xinc = 0; 
      } 
      else if (this.isTowardLeft) 
      { 
      // 左旋转履带 
      xinc = -1; 
      } 
      else 
      { 
      // 右旋转履带 
      xinc = 1; 
      } 
      if(Key.isDown(Key.LEFT)) 
      { 
      //按下左件 
      xinc -= spd; 
      } 
      if(Key.isDown(Key.RIGHT)) 
      { 
      //按下右件 
      xinc += spd; 
      } switch( statusNow ) 
      { 
      case “stand”://站立状态 
      if( xinc != 0 ) 
      { 
      //如果x轴向增量不为零,代表人应该移动了 
      this.gotoAndPlay( “move” ); 
      statusNow = “move”; 
      //跳转到移动状态 
      break; 
      } 
      break; 
      case “move”://移动状态 
      if( !this.isOnLand) 
      { 
      //如果人不在挡板上,则坠落 
      this.gotoAndStop( “falling” ); 
      statusNow = “falling”; 
      } 
      else if( xinc == 0 ) 
      { 
      //如果x轴向增量为0,则站住 
      this.gotoAndStop( “stand” ); 
      statusNow = “stand”; 
      break; 
      } 
      break; 
      case “falling”://坠落状态 
      if( this.isOnLand ) 
      { 
      //如果人掉在挡板上,则转化为站立 
      this.gotoAndStop( “stand” ); 
      statusNow = “stand”; 
      break; 
      } 
      break; 
      default:break; 
      }  
       
      //简单物理模型的建立,参考了ox_darkness师兄@Flash8 
      if( statusNow == “stand” ) 
      { 
      yinc = 0; 
      this._y = this.receiveTarget._y; 
      } 
      if( statusNow == “move” ) 
      { 
      yinc = 0; 
      this._y = this.receiveTarget._y; 
      if( xinc > 0 ) 
      { 
      this._xscale = -Math.abs( this._xscale ); 
      } 
      else if ( xinc < 0 ) 
      { 
      this._xscale = Math.abs( this._xscale ); 
      } 
      if( xinc != 0 ) 
      { 
      this._x += xinc; 
      } 
      if( statusNow == “falling” ) 
      { 
      this._y += yinc; 
      } 
      } 
      if( statusNow == “falling” ) 
      { 
      yinc+=0.15; 
      this._y += yinc; 
      if( xinc > 0 ) 
      { 
      this._xscale = -Math.abs( this._xscale ); 
      } 
      else if ( xinc < 0 ) 
      { 
      this._xscale = Math.abs( this._xscale ); 
      } 
      if( xinc != 0 ) 
      { 
      this._x += xinc; 
      } 
      } 
      if (this._y > sceneh || this._y < -5) 
      { 
      gameOver(); 
      } 
      }  |   
 |