下面我们呢来编写一个敌人类,这个类目前主要有如下几个功能:

  1. 实现各个方向的帧动画切换
  2. 从起点走到终点
  3. 可改变行走速度
  4. 到达终点后消失

是不是觉得功能有点少啊,还是那句话,以后慢慢添加。


写在最前面:

首先说说怎么实现上面说的这几个功能,流程如下:

第一步.首先我是定义了几个可能用到的私有变量

 
  
  1.         //敌人图片  
  2. CCSprite  * _creep;  
  3. //怪物血量  
  4. int _creepHP;  
  5. //怪物移动速度,每秒多少像素  
  6. float _CreepMoveSpeed;  
  7. //当前路点序号  
  8. int _wayPointNow;  
  9. //当前方向  
  10. int _nowDirection;  
  11. //creep是否正在移动  
  12. bool _moving; 

这几个变量的用途很简单,大部分都能看懂,说说几个用途很乱的吧(新手没办法)

  1. //当前路点序号
  2. int _wayPointNow; 

上面这个就是保存了敌人行走的路点序号,就是敌人刚刚走过的路点,比如:敌人走过了a路点,正向着b路点前进,_waypoint就是路点A 。这样说明白了吧。(路点我是为了测试自己瞎写的)

这个路点的序号作用是什么呢?

塔防吗,就要有敌人按照路径走到一个终点,在这走的过程中会有许多转弯的地方,敌人有一个行走的帧动画,在变化方向的时候,我们也要让动画做相应的改变,这样看着才有意思。我是这样让敌人切换转向的:通过比对当前路点和下一个路点得出相对的方向,也就是一个坐标系中a,b两点,b点在a点的上面还是下面,左还是右。得到这个方向之后我们就可以写个函数改变敌人的动画了。


 第二步. 初始化一些参数

 

 
  
  1. //--------------对敌人进行初始化-------------------  
  2.  //设置移动速度  
  3.  _CreepMoveSpeed = 100;  
  4.  //设置血量  
  5.  _creepHP = 100;  
  6.  //初始化路点序列  
  7.  _wayPointNow = 0;  
  8.  //初始化当前方向  
  9.  _nowDirection= getDirection();  
  10.  //初始化精灵  
  11.  //_creep  = CCSprite::create("CloseNormal.png");  
  12.  //初始化是否正在移动  
  13.  _moving = false;  
  14. _creep  = CCSprite::create();  
  15.  _creep->setTag(kSprite);  
  16.  _creep->setPosition(sHWorld->_wayPoint->getControlPointAtIndex(_wayPointNow));  
  17.  setDirectionAnimation(getDirection());  
  18.  this->addChild(_creep); 

第17行的setDirectionAnimation就是一个改变动画方向的函数,其参数就是一个关于放心的枚举,getDirection就是计算方向.

第三步:永远运行的游戏逻辑

在初始化init函数最后加上

 
  
  1. schedule(schedule_selector(mC_Creep::gamelogic)); 

让每帧都调用gamelogic函数

 

 
  
  1. void mC_Creep::gamelogic( float dt )  
  2.  {  
  3.     /*  CCLOG("xy is %f %f",x,y);*/ 
  4.      //如果不移动则运行  
  5.      if(!_moving) creepMove();  
  6.       
  7.      if (_creepHP == 0 )  
  8.      {  
  9.          this->stopAllActions();  
  10.          this->unscheduleAllSelectors();  
  11.          sHWorld->_creepGroup->removeObject(this,true);  
  12.          this->removeChildByTag(kSprite,true);  
  13.      }  
  14.  
  15.  } 

首先判断,如果不是在移动就会判断一下,当HP为0 的时候(被敌人杀死,或者走到了终点我就设置HP 为0),我就做了一些释放,SHworld是用来保存所有的敌人的一个CCArray,作用以后再说。

看看CreepMove函数有什么东西:

 

 
  
  1. void mC_Creep::creepMove()  
  2.  {    
  3.      //1是computeFinishTime()计算直线行走的时间  
  4.      //2.是下一个露点的坐标  
  5.              CCActionInterval * t_Action = CCMoveTo::create(  
  6.                  computeFinishTime(),//1  
  7.                  sHWorld->_wayPoint->getControlPointAtIndex(_wayPointNow+1)//2  
  8.                  );  
  9.              //修改标签,以方便获得  
  10.              t_Action->setTag(kSpeedAction);  
  11.              //生产一个回调函数动作  
  12.              CCCallFunc * callfun = CCCallFunc::create(this,callfunc_selector(mC_Creep::movebyActionCallBack));  
  13.              //生产一个系列动作,让移动完后调用movebyActionCallBack函数  
  14.              CCFiniteTimeAction * seq = CCSequence::create(t_Action,callfun,NULL);  
  15.              //生产速度动作,用于后面的炮弹减速效果  
  16.              CCSpeed * speedaction = CCSpeed::create((CCActionInterval *)seq,1.0f);  
  17.              speedaction->setTag(kSpeedAction);  
  18.              //设置成正在移动。前面有判断如果正在移动就不运作这个函数了  
  19.              _moving = true;  
  20.              //开始所有的动作  
  21.              _creep->runAction(speedaction);  
  22.           
  23.  } 

首先是一个moveto动画,computeFinishTime是用路程除以速度得到的时间,当然这路程是一小段一小段的直线距离。

最后看看

 

 
  
  1. void mC_Creep::movebyActionCallBack()  
  2. {  
  3.  //设置成动作已经完成,可以调用creepMove()让精灵移动  
  4.  _moving = false;  
  5.  do   
  6.  {  
  7.     // CCLOG("pointnow is :%d",_wayPointNow);  
  8.      //改变当前露点。我们已经移动过来了  
  9.      _wayPointNow++;  
  10.      //如果下一个露点序号超出了,所有露点序列的范围  
  11.      if(_wayPointNow>(sHWorld->_wayPoint->count()))   
  12.      {  
  13.          //定制所有动作  
  14.          _creep->stopAllActions();  
  15.          //HP 设为 0 ,让它消失  
  16.          _creepHP = 0;  
  17.          //设置为永远在动,不让它再运行creepMove();  
  18.          _moving = true;  
  19.          break;  
  20.      }  
  21.      //修改动画  
  22.       setDirectionAnimation(getDirection());  
  23.       
  24.  } while (0);  
  25.  

基本上也就这个意思了,我是个新手水平肯定是不高的,如果有错误请指出,欢迎。