Action动作基类,被 ActionManager 管理着。(cocos2dx 3.0 —- ActionManager)
1
2
2d/actions/ccaction.h
2d/actions/ccaction.cpp
先看看Action的声明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
class CC_DLL Action : public Ref, public Clonable
{
public:
static const int INVALID_TAG = -1;
virtual std::string description() const;
/* 返回拷贝动作 */
virtual Action* clone() const = 0;
/* 返回逆动作 */
virtual Action* reverse() const = 0;
/* 动作是否结束 */
virtual bool isDone() const;
/* 在动作开始前调用 */
/* 初始化 */
virtual void startWithTarget(Node *target);
/* 不要自己调用stop */
/* 把这破事交给ActionManger吧 */
virtual void stop();
/* 在ActionManager的update中每一帧调用 */
/* PS :原文注释中提示,如果你不知道自己在做什么,就不要重写step */
virtual void step(float dt);
/* 每一帧调用的函数 */
/* time的值是从 0 到 1 */
/* 0 表示开始 */
/* 0.5 表示执行一半 */
/* 1 表示结束 */
virtual void update(float time);
inline Node* getTarget() const { return _target; }
inline void setTarget(Node *target) { _target = target; }
inline Node* getOriginalTarget() const { return _originalTarget; }
/* 弱引用 ? */
inline void setOriginalTarget(Node *originalTarget) { _originalTarget = originalTarget; }
inline int getTag() const { return _tag; }
inline void setTag(int tag) { _tag = tag; }
protected:
Action();
virtual ~Action();
Node *_originalTarget;
/* 用startWithTarget设置 */
/* 当调用stop的时候置为null */
Node *_target;
/* 标识 */
int _tag;
private:
/* 禁用拷贝构造函数, 禁止重载等号运算符 */
CC_DISALLOW_COPY_AND_ASSIGN(Action);
};
其中 Clonable 只是一个接口,用于对象的拷贝,除此之外Action还禁用了拷贝构造函数和重载等号运算符。
对于一个Action的子类,你要实现实现以下方法:
FiniteTimeAction即ActionInstant和ActionIntavel的父类。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class CC_DLL FiniteTimeAction : public Action
{
public:
inline float getDuration() const { return _duration; }
inline void setDuration(float duration) { _duration = duration; }
virtual FiniteTimeAction* reverse() const override = 0;
virtual FiniteTimeAction* clone() const override = 0;
protected:
FiniteTimeAction() : _duration(0) {}
virtual ~FiniteTimeAction(){}
/* 时长 */
float _duration;
private:
CC_DISALLOW_COPY_AND_ASSIGN(FiniteTimeAction);
};
然后就木有然后了。就定义了一个接口给瞬时动作和延时动作用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class CC_DLL Speed : public Action
{
/* 此处略去 */
protected:
/* 在step中起关键作用 */
float _speed;
/* 保存目标动作 */
/* 强引用 */
ActionInterval *_innerAction;
private:
CC_DISALLOW_COPY_AND_ASSIGN(Speed);
};
step代码:
1
2
3
4
void Speed::step(float dt)
{
_innerAction->step(dt * _speed);
}
最最关键的一点就在于此 — dt * _speed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class CC_DLL Follow : public Action
{
public:
static Follow* create(Node *followedNode, const Rect& rect = Rect::ZERO);
inline bool isBoundarySet() const { return _boundarySet; }
/* 开启关闭边界 */
inline void setBoudarySet(bool value) { _boundarySet = value; }
virtual Follow* clone() const override;
virtual Follow* reverse() const override;
virtual void step(float dt) override;
virtual bool isDone() const override;
virtual void stop() override;
CC_CONSTRUCTOR_ACCESS:
/* 略去初始化函数,以及初始化列表 */
virtual ~Follow();
/* 跟随节点的引用计数会增加 */
bool initWithTarget(Node *followedNode, const Rect& rect = Rect::ZERO);
protected:
/* 跟随节点 */
Node *_followedNode;
/* 是否开启边界 */
bool _boundarySet;
/* 若边界大于整个屏幕,则不需要跟随动作了 */
bool _boundaryFullyCovered;
/* 快速访问屏幕尺寸 */
Point _halfScreenSize;
Point _fullScreenSize;
/* 边界 */
float _leftBoundary;
float _rightBoundary;
float _topBoundary;
float _bottomBoundary;
Rect _worldRect;
private:
CC_DISALLOW_COPY_AND_ASSIGN(Follow);
};
大致的流程是这样的:
看看还是蛮简单=.. =