Cocos2d-x 动作之创建自定义动作
2013-10-16 17:07
375 查看
为了追踪鱼游动的方向,我们可以编写一个定时器,通过帧的转换来更新鱼的方向,不过这也是一个既烦琐又难以维护的办法。参考引擎的做法,我们不妨进一步抽象出独立的旋转跟踪动作,根据精灵的移动路径设置合适的旋转角度。
下面我们编写一个继承于
“RotateWithAction.h”中的定义如下:
“RotateWithAction.cpp”中的实现如下:
也许有的读者已经有了疑问,
现在,我们已经不需要使用4.6节介绍的
CCAction包含两个重要的方法:
step与
update。
step方法会在每一帧动作更新时触发,该方法接受一个表示调用时间间隔的参数
dt,
dt的积累即为动作运行的总时间。引擎利用积累时间来计算动作运行的进度(一个从0到1的实数),并调用
update方法更新动作。
update方法是
CCAction的核心,它由
step方法调用,接受一个表示动作进度的参数,每一个动作都需要利用进度值改变目标节点的属性或执行其他指令。自定义动作只需要从这两个方法入手即可,我们通常只需要修改
update方法就可以实现简单的动作。
下面我们编写一个继承于
CCAction的
CCRotateAction动作。如同复合动作与变速动作一样,它会把另一个动作包装起来,在执行被包装动作的同时,设置精灵的方向。为此,我们需要在每一帧记录上一帧精灵的位置,然后再根据精灵两帧的位移确定精灵的方向。由于我们必须在
CCRotateAction执行的同时运行被包含的目标动作,所以我们需要在
step方法中调用目标动作的
step方法。下面我们来看
CCRotateAction的实现。
“RotateWithAction.h”中的定义如下:
class RotateWithAction : public CCActionInterval { public: CCObject* copyWithZone(CCZone* pZone); ~RotateWithAction(); static RotateWithAction* create(CCActionInterval * action); virtual void startWithTarget(CCNode* pTarget); bool initWithAction(CCActionInterval* pAction); bool isDone(); void step(ccTime dt); protected: void RotateWithAction::setInnerAction(CCActionInterval* pAction); CCNode* pInnerTarget; CCActionInterval* pInnerAction; };
“RotateWithAction.cpp”中的实现如下:
RotateWithAction::~RotateWithAction() { CC_SAFE_RELEASE(pInnerAction); } RotateWithAction* RotateWithAction::create(CCActionInterval* pAction) { RotateWithAction* action = new RotateWithAction(); if (action && action->initWithAction(pAction)) { action->autorelease(); return action; } CC_SAFE_DELETE(action); return NULL; } bool RotateWithAction::initWithAction(CCActionInterval* pAction) { pAction->retain(); pInnerAction = pAction; return true; } void RotateWithAction::startWithTarget(CCNode* pTarget) { pInnerTarget = pTarget; CCAction::startWithTarget(pTarget); pInnerAction->startWithTarget(pTarget); } bool RotateWithAction::isDone() { return pInnerAction->isDone(); } void RotateWithAction::step(ccTime dt) { CCPoint prePos = pInnerTarget->getPosition(); pInnerAction->step(dt); CCPoint curPos = pInnerTarget->getPosition(); float tan = -(curPos.y - prePos.y) / (curPos.x - prePos.x); float degree = atan(tan); degree = degree / 3.14159f * 180; pInnerTarget->setRotation(degree); } void RotateWithAction::setInnerAction(CCActionInterval* pAction) { if (pInnerAction != pAction) { CC_SAFE_RELEASE(pInnerAction); pInnerAction = pAction; CC_SAFE_RETAIN(pInnerAction); } } CCObject* RotateWithAction::copyWithZone(CCZone* pZone) { CCZone* pNewZone = NULL; RotateWithAction* pCopy = NULL; if(pZone && pZone->m_pCopyObject) { pCopy = (RotateWithAction*)(pZone->m_pCopyObject); } else { pCopy = new RotateWithAction(); pZone = pNewZone = new CCZone(pCopy); } CCActionInterval::copyWithZone(pZone); pCopy->initWithAction(dynamic_cast<CCActionInterval*> (pInnerAction->copy()->autorelease())); CC_SAFE_DELETE(pNewZone); return pCopy; }
也许有的读者已经有了疑问,
step方法与
update方法都可以做到每一帧判断一次方向,为什么选择重载
step方法而不是
update方法呢?这是因为引擎在
step方法中对动作对象的内部成员进行了更新,更新后才会由此方法调用
update方法来更新目标节点。在方向追踪的动作中,我们除了在每一帧判断方向,还必须同步执行被包装的动作。这就需要我们调用被包装动作的
step方法,以保证对象能够被完整地更新。
现在,我们已经不需要使用4.6节介绍的
CCSpawn来实现蹩脚的方向追踪效果了,只要把需要追踪方向的动作传递给
CCRotateAction,即可得到一个自动改变鱼方向的智能动作。
相关文章推荐
- Cocos2d-x 3.x 系列教程02-创建自定义项目
- cocos2d 2.x在opengl es 2.0 下自定义着色器来创建特别酷的特效(译)
- 如何在自定义文件下创建cocos2d-x项目
- cocos2d-js的自定义事件的两种创建方法
- quick-cocos2d-x 创建自定义lua绑定c++类
- Cocos2d-x -自定义动作 圆周运动
- 自定义精灵类并为你的精灵设置攻击帧(指定开始帧)以及扩展Cocos2d源码的CCAnimation简化动画创建
- 创建自定义的Cocos2d-x场景
- Cocos2d-x教程(16)-自定义动作 圆周运动
- Cocos2d-x 创建自定义项目模板
- Cocos2d动作: 创建重复性动作
- 【iOS-Cocos2d游戏开发之二十一 】自定义精灵类并为你的精灵设置攻击帧(指定开始帧)以及扩展Cocos2d源码的CCAnimation简化动画创建!
- 创建一个cocos2d-x工程添加一个自定义Scene并显示
- Cocos2d动作: 创建组合动作对象
- 【iOS-Cocos2d游戏开发之二十一 】自定义精灵类并为你的精灵设置攻击帧以及动画创建!【一】
- 使用最新的cocos2d-x-3.4+VS2012创建自定义项目
- (原创)cocos2d-x 3.0+ lua 学习和工作(1) : 自定义创建对象方法
- 【iOS-Cocos2d游戏开发之二十一 】自定义精灵类并为你的精灵设置攻击帧以及动画创建!【二】 推荐
- 【iOS-Cocos2d游戏开发之二十一 】自定义精灵类并为你的精灵设置攻击帧(指定开始帧)以及扩展Cocos2d源码的CCAnimation简化动画创建!
- cocos2d-js的自定义事件的两种创建方法