总共加起来有53个测试用例,那就按照它的序号来吧。
基本上所有的子类都实现父类的虚函数onEnter进行具体的操作,所以要改代码的话也是改这一块。
1. ActionMove
void ActionMove::onEnter()
{
ActionsDemo::onEnter();
centerSprites(3);
auto s = Director::getInstance()->getWinSize();
auto actionTo = MoveTo::create(2, Vec2(s.width-40, s.height-40));
auto actionBy = MoveBy::create(2, Vec2(80,80));
auto actionByBack = actionBy->reverse();
_tamara->runAction( actionTo);
_grossini->runAction( Sequence::create(actionBy, actionByBack, nullptr));
_kathia->runAction(MoveTo::create(1, Vec2(40,40)));
}
第一碰到就是centerSprites()函数,这个函数的实现很简单,创建了三个人物,
_tamara, _kathia, _grossini,这种蹩脚的命名方法竟然存在?以下划线开头命名一个变量,第一次见到。
通过传递数字确定几个人显示在桌面上,这里是3个。
其余的已经在基础系列讲过了。
第一个动作是从基本上是移动到右上角,
第二个动作是向上向右偏移(80, 80)个像素。
第三个动作是向左下角移动到(80, 80)这个地方。
有一个Sequence类创建一系列的动作,移动,最后以nullptr结尾。
void ActionsDemo::centerSprites(unsigned int numberOfSprites)
{
auto s = Director::getInstance()->getWinSize();
if( numberOfSprites == 0 )
{
_tamara->setVisible(false);
_kathia->setVisible(false);
_grossini->setVisible(false);
}
else if ( numberOfSprites == 1 )
{
_tamara->setVisible(false);
_kathia->setVisible(false);
_grossini->setPosition(s.width/2, s.height/2);
}
else if( numberOfSprites == 2 )
{
_kathia->setPosition(s.width/3, s.height/2);
_tamara->setPosition(2*s.width/3, s.height/2);
_grossini->setVisible(false);
}
else if( numberOfSprites == 3 )
{
_grossini->setPosition(s.width/2, s.height/2);
_tamara->setPosition(s.width/4, s.height/2);
_kathia->setPosition(3 * s.width/4, s.height/2);
}
}
2. ActionMove3D
可以看到和2D基本上一样,就是坐标有变化,Vec2变成Vec3,没有其余任何变化。
在图片显示上也没有什么变化,负值应该向内,
void ActionMove3D::onEnter()
{
ActionsDemo::onEnter();
centerSprites(3);
auto s = Director::getInstance()->getWinSize();
_tamara->setPosition3D(Vec3(s.width-40, s.height-40, 0));
_kathia->setPosition3D(Vec3(40, 40, 0));
auto actionTo = MoveTo::create(2, Vec3(s.width-40, s.height-40, -100));
auto actionBy = MoveBy::create(2, Vec3(80, 80, -100));
auto actionByBack = actionBy->reverse();
_tamara->runAction(actionTo);
_grossini->runAction(Sequence::create(actionBy, actionByBack, nullptr));
_kathia->runAction(MoveTo::create(1, Vec3(40, 40, -100)));
}
3. ActionRotate
旋转create第一个参数表示时间,第二个表示角度。
void ActionRotate::onEnter()
{
ActionsDemo::onEnter();
centerSprites(3);
auto actionTo = RotateTo::create( 2, 45);
auto actionTo2 = RotateTo::create( 2, -45);
auto actionTo0 = RotateTo::create(2 , 0);
_tamara->runAction( Sequence::create(actionTo, actionTo0, nullptr));
auto actionBy = RotateBy::create(2 , 360);
auto actionByBack = actionBy->reverse();
_grossini->runAction( Sequence::create(actionBy, actionByBack, nullptr));
_kathia->runAction( Sequence::create(actionTo2, actionTo0->clone(), nullptr));
}
4. ActionRotateBy3D‘
分别沿着x轴, y轴, z轴旋转360度,reverse是一个逆过程。
void ActionRotateBy3D::onEnter()
{
ActionsDemo::onEnter();
centerSprites(3);
auto actionBy1 = RotateBy::create(4, Vec3(360, 0, 0));
auto actionBy2 = RotateBy::create(4, Vec3(0, 360, 0));
auto actionBy3 = RotateBy::create(4 ,Vec3(0, 0, 360));
_tamara->runAction( Sequence::create(actionBy1, actionBy1->reverse(), nullptr));
_grossini->runAction( Sequence::create(actionBy2, actionBy2->reverse(), nullptr));
_kathia->runAction( Sequence::create(actionBy3, actionBy3->reverse(), nullptr));
}
5. ActionScale
缩放,第二个参数是x轴的倍数,第三个参数是y轴的参数。
void ActionScale::onEnter()
{
ActionsDemo::onEnter();
centerSprites(3);
auto actionTo = ScaleTo::create(2.0f, 0.5f);
auto actionBy = ScaleBy::create(2.0f, 1.0f, 10.0f);
auto actionBy2 = ScaleBy::create(2.0f, 5.0f, 1.0f);
_grossini->runAction( actionTo);
_tamara->runAction( Sequence::create(actionBy, actionBy->reverse(), nullptr));
_kathia->runAction( Sequence::create(actionBy2, actionBy2->reverse(), nullptr));
}
中间的男士叫做grossini, 左手边叫做tamara, 右手边叫做kathia.
6. SkewTo
描述Skews a Node object to given angles by modifying it's skewX and skewY attributes
翻译过来是倾斜的意思。
static SkewTo* create(float t, float sx, float sy);
倾斜一定的角度,沿着x或者是y轴。
画了一个简单的理解图,同时需要理解to 和by的区别。
void ActionSkew::onEnter()
{
ActionsDemo::onEnter();
centerSprites(3);
auto actionTo = SkewTo::create(2, 37.2f, -37.2f);
auto actionToBack = SkewTo::create(2, 0, 0);
auto actionBy = SkewBy::create(2, 0.0f, -90.0f);
auto actionBy2 = SkewBy::create(2, 45.0f, 45.0f);
auto actionByBack = actionBy->reverse();
_tamara->runAction(Sequence::create(actionTo, actionToBack, nullptr));
_grossini->runAction(Sequence::create(actionBy, actionByBack, nullptr));
_kathia->runAction(Sequence::create(actionBy2, actionBy2->reverse(), nullptr));
}
7. ActionRotationalSkew
旋转的过程中倾斜,比较不好理解。
void ActionRotationalSkew::onEnter()
{
ActionsDemo::onEnter();
this->centerSprites(3);
auto actionTo = RotateTo::create(2, 180, 180);
auto actionToBack = RotateTo::create(2, 0, 0);
auto actionBy = RotateBy::create(2, 0.0f, 360);
auto actionByBack = actionBy->reverse();
auto actionBy2 = RotateBy::create(2, 360, 0);
auto actionBy2Back = actionBy2->reverse();
_tamara->runAction( Sequence::create(actionBy, actionByBack, nullptr) );
_grossini->runAction( Sequence::create(actionTo, actionToBack, nullptr) );
_kathia->runAction( Sequence::create(actionBy2, actionBy2Back, nullptr) );
}
8. ActionRotationalSkewVSStandardSkew
真心搞不懂它们的区别在哪里。
以后有空需要用到再研究吧,现在还不是研究几何关系的时候。
9. Skew Rotate Scale同时进行
auto actionTo = SkewTo::create(2, 0.f, 2.f);
auto rotateTo = RotateTo::create(2, 61.0f);
auto actionScaleTo = ScaleTo::create(2, -0.44f, 0.47f);
auto actionScaleToBack = ScaleTo::create(2, 1.0f, 1.0f);
auto rotateToBack = RotateTo::create(2, 0);
auto actionToBack = SkewTo::create(2, 0, 0);
box->runAction(Sequence::create(actionTo, actionToBack, nullptr));
box->runAction(Sequence::create(rotateTo, rotateToBack, nullptr));
box->runAction(Sequence::create(actionScaleTo, actionScaleToBack, nullptr));
10. jump的几个参数
慢慢地跳到目的地
class CC_DLL JumpTo : public JumpBy
{
public:
/**
* Creates the action.
* @param duration Duration time, in seconds.
* @param position The jumping destination position.
* @param height The jumping height.
* @param jumps The jumping times.
* @return An autoreleased JumpTo object.
*/
static JumpTo* create(float duration, const Vec2& position, float height, int jumps);
最后一个表示跳几次
void ActionJump::onEnter()
{
ActionsDemo::onEnter();
centerSprites(3);
auto actionTo = JumpTo::create(2, Vec2(300,300), 50, 4);
auto actionBy = JumpBy::create(2, Vec2(300,0), 50, 4);
auto actionUp = JumpBy::create(2, Vec2(0,0), 80, 4);
auto actionByBack = actionBy->reverse();
_tamara->runAction( actionTo);
_grossini->runAction( Sequence::create(actionBy, actionByBack, nullptr));
_kathia->runAction( RepeatForever::create(actionUp));
}
11. CardinalSplineBy
这个比较不好理解,不好从字面上理解,使用array指定路径,人物会沿着这个路径行走,
tension这个参数不好理解。贴图说面,大概是tension为0时,曲线比较光滑,曲线为1时是方形的。
左边是tension为0的图。
void ActionCardinalSpline::onEnter()
{
ActionsDemo::onEnter();
this->centerSprites(2);
auto s = Director::getInstance()->getWinSize();
auto array = PointArray::create(20);
array->addControlPoint(Vec2(0, 0));
array->addControlPoint(Vec2(s.width/2-30, 0));
array->addControlPoint(Vec2(s.width/2-30, s.height-80));
array->addControlPoint(Vec2(0, s.height-80));
array->addControlPoint(Vec2(0, 0));
//
// sprite 1 (By)
//
// Spline with no tension (tension==0)
//
auto action = CardinalSplineBy::create(3, array, 0);
auto reverse = action->reverse();
auto seq = Sequence::create(action, reverse, nullptr);
_tamara->setPosition(50, 50);
_tamara->runAction(seq);
auto drawNode1 = DrawNode::create();
drawNode1->setPosition(Vec2(50,50));
drawNode1->drawCardinalSpline(array, 0, 100, Color4F(1.0, 0.0, 1.0, 1.0));
this->addChild(drawNode1);
//
// sprite 2 (By)
//
// Spline with high tension (tension==1)
//
auto action2 = CardinalSplineBy::create(3, array, 1);
auto reverse2 = action2->reverse();
auto seq2 = Sequence::create(action2, reverse2, nullptr);
_kathia->setPosition(s.width/2, 50);
_kathia->runAction(seq2);
auto drawNode2 = DrawNode::create();
drawNode2->setPosition(Vec2(s.width/2, 50));
drawNode2->drawCardinalSpline(array, 1, 100, Color4F(1.0, 0.0, 1.0, 1.0));
this->addChild(drawNode2);
}
12. CatmullRomBy
可以看到是一种特殊的cardinal spline
An action that moves the target with a CatmullRom curve by a certain distance.
A Catmull Rom is a Cardinal Spline with a tension of 0.5.
13. BezierBy
@class BezierBy
@brief An action that moves the target with a cubic Bezier curve by a certain distance.
14. blink
是闪烁的意思,第一个参数指定秒数,第二个参数是闪烁几次。
15. FadeIn/FadeOut
渐变消失或者出现,其中FadeIn是消失。
16. TintBy/TintTo
Tints a Node that implements the NodeRGB protocol from current tint to a custom one.
给图片蒙上了一层奇怪的颜色。
void ActionTint::onEnter()
{
ActionsDemo::onEnter();
centerSprites(2);
auto action1 = TintTo::create(2, 255, 0, 255);
auto action2 = TintBy::create(2, -127, -255, -127);
auto action2Back = action2->reverse();
_tamara->runAction( action1);
_kathia->runAction( Sequence::create( action2, action2Back, nullptr));
}
基本上Action的使用很简单,使用相关的类,调用create,需要传递正确的参数,然后相关的实体调用runAction()方法。
17. File Animation / Manual animation
加载15张图片到szName中,然后把szName传递给animation的addSpriteFrameWithFile方法。
void ActionAnimate::onEnter()
{
ActionsDemo::onEnter();
centerSprites(3);
//
// Manual animation
//
auto animation = Animation::create();
for( int i=1;i<15;i++)
{
char szName[100] = {0};
sprintf(szName, "Images/grossini_dance_%02d.png", i);
animation->addSpriteFrameWithFile(szName);
}
// should last 2.8 seconds. And there are 14 frames.
animation->setDelayPerUnit(2.8f / 14.0f);
animation->setRestoreOriginalFrame(true);
auto action = Animate::create(animation);
_grossini->runAction(Sequence::create(action, action->reverse(), nullptr));
//
// File animation
//
// With 2 loops and reverse
auto cache = AnimationCache::getInstance();
cache->addAnimationsWithFile("animations/animations-2.plist");
auto animation2 = cache->getAnimation("dance_1");
auto action2 = Animate::create(animation2);
_tamara->runAction(Sequence::create(action2, action2->reverse(), nullptr));
_frameDisplayedListener = EventListenerCustom::create(AnimationFrameDisplayedNotification, [](EventCustom * event){
auto userData = static_cast<AnimationFrame::DisplayedEventInfo*>(event->getUserData());
log("target %p with data %s", userData->target, Value(userData->userInfo).getDescription().c_str());
});
后面的等以后需要再掌握吧。这样一个一个记忆效果不好。
ADD_TEST_CASE(ActionSequence);
ADD_TEST_CASE(ActionSequence2);
ADD_TEST_CASE(ActionSequence3);
ADD_TEST_CASE(ActionRemoveSelf);
ADD_TEST_CASE(ActionSpawn);
ADD_TEST_CASE(ActionSpawn2);
ADD_TEST_CASE(ActionReverse);
ADD_TEST_CASE(ActionDelayTime);
ADD_TEST_CASE(ActionRepeat);
ADD_TEST_CASE(ActionRepeatForever);
ADD_TEST_CASE(ActionRotateToRepeat);
ADD_TEST_CASE(ActionCallFunction);
ADD_TEST_CASE(ActionCallFuncN);
ADD_TEST_CASE(ActionCallFuncND);
ADD_TEST_CASE(ActionReverseSequence);
ADD_TEST_CASE(ActionReverseSequence2);
ADD_TEST_CASE(ActionOrbit);
ADD_TEST_CASE(ActionFollow);
ADD_TEST_CASE(ActionFollowWithOffset);
ADD_TEST_CASE(ActionTargeted);
ADD_TEST_CASE(ActionTargetedReverse);
ADD_TEST_CASE(ActionMoveStacked);
ADD_TEST_CASE(ActionMoveJumpStacked);
ADD_TEST_CASE(ActionMoveBezierStacked);
ADD_TEST_CASE(ActionCardinalSplineStacked);
ADD_TEST_CASE(ActionCatmullRomStacked);
ADD_TEST_CASE(PauseResumeActions);
ADD_TEST_CASE(ActionResize);
ADD_TEST_CASE(Issue1305);
ADD_TEST_CASE(Issue1305_2);
ADD_TEST_CASE(Issue1288);
ADD_TEST_CASE(Issue1288_2);
ADD_TEST_CASE(Issue1327);
ADD_TEST_CASE(Issue1398);
ADD_TEST_CASE(Issue2599)
ADD_TEST_CASE(ActionFloatTest);