下面我们呢来编写一个敌人类,这个类目前主要有如下几个功能:
- 实现各个方向的帧动画切换
- 从起点走到终点
- 可改变行走速度
- 到达终点后消失
是不是觉得功能有点少啊,还是那句话,以后慢慢添加。
写在最前面:
首先说说怎么实现上面说的这几个功能,流程如下:
第一步.首先我是定义了几个可能用到的私有变量
- //敌人图片
- CCSprite * _creep;
- //怪物血量
- int _creepHP;
- //怪物移动速度,每秒多少像素
- float _CreepMoveSpeed;
- //当前路点序号
- int _wayPointNow;
- //当前方向
- int _nowDirection;
- //creep是否正在移动
- bool _moving;
这几个变量的用途很简单,大部分都能看懂,说说几个用途很乱的吧(新手没办法)
- //当前路点序号
- int _wayPointNow;
上面这个就是保存了敌人行走的路点序号,就是敌人刚刚走过的路点,比如:敌人走过了a路点,正向着b路点前进,_waypoint就是路点A 。这样说明白了吧。(路点我是为了测试自己瞎写的)
这个路点的序号作用是什么呢?
塔防吗,就要有敌人按照路径走到一个终点,在这走的过程中会有许多转弯的地方,敌人有一个行走的帧动画,在变化方向的时候,我们也要让动画做相应的改变,这样看着才有意思。我是这样让敌人切换转向的:通过比对当前路点和下一个路点得出相对的方向,也就是一个坐标系中a,b两点,b点在a点的上面还是下面,左还是右。得到这个方向之后我们就可以写个函数改变敌人的动画了。
第二步. 初始化一些参数
- //--------------对敌人进行初始化-------------------
- //设置移动速度
- _CreepMoveSpeed = 100;
- //设置血量
- _creepHP = 100;
- //初始化路点序列
- _wayPointNow = 0;
- //初始化当前方向
- _nowDirection= getDirection();
- //初始化精灵
- //_creep = CCSprite::create("CloseNormal.png");
- //初始化是否正在移动
- _moving = false;
- _creep = CCSprite::create();
- _creep->setTag(kSprite);
- _creep->setPosition(sHWorld->_wayPoint->getControlPointAtIndex(_wayPointNow));
- setDirectionAnimation(getDirection());
- this->addChild(_creep);
第17行的setDirectionAnimation就是一个改变动画方向的函数,其参数就是一个关于放心的枚举,getDirection就是计算方向.
第三步:永远运行的游戏逻辑
在初始化init函数最后加上
- schedule(schedule_selector(mC_Creep::gamelogic));
让每帧都调用gamelogic函数
- void mC_Creep::gamelogic( float dt )
- {
- /* CCLOG("xy is %f %f",x,y);*/
- //如果不移动则运行
- if(!_moving) creepMove();
- if (_creepHP == 0 )
- {
- this->stopAllActions();
- this->unscheduleAllSelectors();
- sHWorld->_creepGroup->removeObject(this,true);
- this->removeChildByTag(kSprite,true);
- }
- }
首先判断,如果不是在移动就会判断一下,当HP为0 的时候(被敌人杀死,或者走到了终点我就设置HP 为0),我就做了一些释放,SHworld是用来保存所有的敌人的一个CCArray,作用以后再说。
看看CreepMove函数有什么东西:
- void mC_Creep::creepMove()
- {
- //1是computeFinishTime()计算直线行走的时间
- //2.是下一个露点的坐标
- CCActionInterval * t_Action = CCMoveTo::create(
- computeFinishTime(),//1
- sHWorld->_wayPoint->getControlPointAtIndex(_wayPointNow+1)//2
- );
- //修改标签,以方便获得
- t_Action->setTag(kSpeedAction);
- //生产一个回调函数动作
- CCCallFunc * callfun = CCCallFunc::create(this,callfunc_selector(mC_Creep::movebyActionCallBack));
- //生产一个系列动作,让移动完后调用movebyActionCallBack函数
- CCFiniteTimeAction * seq = CCSequence::create(t_Action,callfun,NULL);
- //生产速度动作,用于后面的炮弹减速效果
- CCSpeed * speedaction = CCSpeed::create((CCActionInterval *)seq,1.0f);
- speedaction->setTag(kSpeedAction);
- //设置成正在移动。前面有判断如果正在移动就不运作这个函数了
- _moving = true;
- //开始所有的动作
- _creep->runAction(speedaction);
- }
首先是一个moveto动画,computeFinishTime是用路程除以速度得到的时间,当然这路程是一小段一小段的直线距离。
最后看看
- void mC_Creep::movebyActionCallBack()
- {
- //设置成动作已经完成,可以调用creepMove()让精灵移动
- _moving = false;
- do
- {
- // CCLOG("pointnow is :%d",_wayPointNow);
- //改变当前露点。我们已经移动过来了
- _wayPointNow++;
- //如果下一个露点序号超出了,所有露点序列的范围
- if(_wayPointNow>(sHWorld->_wayPoint->count()))
- {
- //定制所有动作
- _creep->stopAllActions();
- //HP 设为 0 ,让它消失
- _creepHP = 0;
- //设置为永远在动,不让它再运行creepMove();
- _moving = true;
- break;
- }
- //修改动画
- setDirectionAnimation(getDirection());
- } while (0);
- }
基本上也就这个意思了,我是个新手水平肯定是不高的,如果有错误请指出,欢迎。
转载于:https://blog.51cto.com/farsa/1137360