Cocos2d-x 学习笔记(9) Action 运行原理

1. 从一个Action开始

1.1 创建

在Scene里写一个Sprite,并添加Action:

Sprite *sp = Sprite::create("m1.png");
MoveBy *mb = MoveBy::create(20, Vec2(300,10));
sp->runAction(mb);
this->addChild(sp);

先通过create方法创建Action,之后Sprite和Action通过runAction方法产生联系。

create方法坐标参数被转为Z为0的三维坐标。

看create方法主要语句:

MoveBy *ret = new (std::nothrow) MoveBy();
ret->initWithDuration(duration, deltaPosition))
ret->autorelease();
return ret;

Action交给内存管理池进行内存管理,还要执行initWithDuration方法。

看initWithDuration方法,调用了父类的ActionInterval的initWithDuration(duration),并设置MoveBy的成员变量:

_positionDelta = deltaPosition;
_is3D = true;

看父类的ActionInterval的initWithDuration(duration)方法,是设置了父类成员变量:

_duration = d;
_elapsed = 0;
_firstTick = true;
_done = false;

创建好了Action,执行runAction方法,主要是执行下面的语句:

_actionManager->addAction(action, this, !_running);

ActionManager的addAction方法在我的这篇文章有介绍,再次介绍大致流程:

结束之前执行action的startWithTarget(target)方法,该方法实际执行了其所有继承类的同名方法,对以下成员变量设置:

_originalTarget = _target = aTarget; // Action
_elapsed = 0.0f;
_firstTick = true;
_done = false;
_previousPosition = _startPosition = target->getPosition3D(); // MoveBy

简要地说,是把action添加到node对应的element的actions容器中,并通过ActionManager把action和node匹配,并不是“run”。

1.2 运行

Action的实际运行在ActionManager的update方法中,该方法简要地说是对ActionManager的哈希链表_targets进行遍历,对遍历到的每个element的actions再遍历,对遍历到的action执行step(float dt)。

MoveBy的step(float dt)方法实际是执行父类的同名方法,在每次step方法中又会调用一次MoveBy的update方法,step和update的大致流程:

2. 总结

创建并使用action,用到了action的create方法和node的runAction方法,也使action与node产生了关联。

随着ActionManager在每帧调用回调函数update,每个element的action都会执行一次step方法和update方法,step通过已执行的时间(进度时间与帧间隔dt的和)与我们定义的总时长来计算动作执行进度,update把执行进度转为我们在屏幕上看到的进度。当进度到1,动作执行完了,_done置true。

posted @ 2019-07-26 11:13  deepcho  阅读(784)  评论(2编辑  收藏  举报

博客园提供博客支持
爱我所选,选我所爱。
❤️