cdx提供了任意属性的Action回调, 但是runAction的对象需要实现ActionTweenDelegate接口. 鉴于3.0使用了c++11,而c++11提供了std::function, 我们为什么不能利用回调来代替接口实现任意属性的缓动动作呢? 无非是传一个std::function保存在Action里而已,基本代码和ActionTween没有太大区别.

 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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#ifndef __ActionTweenWithFunc_H__
#define __ActionTweenWithFunc_H__

#include "CCActionInterval.h"

class ActionTweenWithFunc : public cocos2d::ActionInterval
{
public:
    static ActionTweenWithFunc* create(float duration, std::function<void(float cur_num)> func, float from, float to);

    bool initWithDuration(float duration, std::function<void(float cur_num)> func, float from, float to);

    // Overrides
    void startWithTarget(cocos2d::Node *target) override;
    void update(float dt) override;
    ActionTweenWithFunc* reverse() const override;
    ActionTweenWithFunc* clone() const override;
protected:
    std::function<void(float cur_num)>  _up_func;
    float            _from, _to;
    float            _delta;
};

#endif /* __ActionTweenWithFunc_H__ */


#include "ActionTweenWithFunc.h"

ActionTweenWithFunc* ActionTweenWithFunc::create(float aDuration, std::function<void(float cur_num)> func, float from, float to)
{
    ActionTweenWithFunc* pRet = new ActionTweenWithFunc();
    if (pRet && pRet->initWithDuration(aDuration, func, from, to))
    {
        pRet->autorelease();
    }
    else
    {
        CC_SAFE_DELETE(pRet);
    }
    return pRet;
}

bool ActionTweenWithFunc::initWithDuration(float aDuration, std::function<void(float cur_num)> func, float from, float to)
{
    if (ActionInterval::initWithDuration(aDuration))
    {
        _up_func = func;
        _to       = to;
        _from     = from;
        return true;
    }
    return false;
}

void ActionTweenWithFunc::startWithTarget(cocos2d::Node *target)
{
    ActionInterval::startWithTarget(target);
    _delta = _to - _from;
}

void ActionTweenWithFunc::update(float dt)
{
    float cur_num = _to - _delta * (1 - dt);
    _up_func(cur_num);
}

ActionTweenWithFunc* ActionTweenWithFunc::reverse() const
{
    return ActionTweenWithFunc::create(_duration, _up_func, _to, _from);
}

ActionTweenWithFunc* ActionTweenWithFunc::clone() const
{
    return ActionTweenWithFunc::create(_duration, _up_func, _from, _to);
}