cocos2d-x 3.3 中各种动画笔记与实例

来源:互联网 发布:淘宝运营高级教程视频 编辑:程序博客网 时间:2024/06/15 12:18

接触到cocos2d-x 3.3中动画,写了如下笔记。我的笔记与代码实例是一起的,方便查看。笔记中记录了大部分动画创建、运用、理解和实现,也表明一些错误原由和可能出现错误地方,方便新手少走弯路,也使自己以后查看时会注意到。


查看代码时可能因为转过来格式问题,有些出入,望理解下,代码在VS2012测试都通过的。测试每个动画时,把注释去掉就可以。注意下多个动画运行时,不易观察的情况。要用这个代码的话,自己可以根据自己的项目酌情修改下。


在使用每个动画是最好追溯到源定义查看下它的定义与用法及实现,以便更好理解,这里希望大家一起交流、讨论下,不懂或有问题的留言给我,一起探讨。



下面贴上代码:


HelloWorldScene.h文件没有什么改变,加了3个回调函数,有写注释: 


#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__


#include "cocos2d.h"


class HelloWorld : public cocos2d::Layer
{
public:
    // there's no 'id' in cpp, so we recommend returning the class instance pointer
    static cocos2d::Scene* createScene();


    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
    virtual bool init();
    
    // a selector callback
    void menuCloseCallback(cocos2d::Ref* pSender);


//用于测试CallFunc?系列函数
void test_CallFunc();


void test_CallFuncN(Node * pSence);


void test_CCCallFuncND(Node * pSence, void * data);
    
    // implement the "static create()" method manually
    CREATE_FUNC(HelloWorld);
};


#endif // __HELLOWORLD_SCENE_H__



HelloWorldScene.cpp文件这里才是重点,笔记全在这里,有做标记的:


#include "HelloWorldScene.h"


USING_NS_CC;


Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::create();
    
    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();


    // add layer as a child to scene
    scene->addChild(layer);


    // return the scene
    return scene;
}


// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }
    
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();


    /////////////////////////////
    // 2. add a menu item with "X" image, which is clicked to quit the program
    //    you may modify it.


    // add a "close" icon to exit the progress. it's an autorelease object
    auto closeItem = MenuItemImage::create(
                                           "CloseNormal.png",
                                           "CloseSelected.png",
                                           CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
    
closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
                                origin.y + closeItem->getContentSize().height/2));


    // create menu, it's an autorelease object
    auto menu = Menu::create(closeItem, NULL);
    menu->setPosition(Vec2::ZERO);
    this->addChild(menu, 1);


    /////////////////////////////
    // 3. add your codes below...


    // add a label shows "Hello World"
    // create and initialize a label
    
    auto label = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 24);
    
    // position the label on the center of the screen
    label->setPosition(Vec2(origin.x + visibleSize.width/2,
                            origin.y + visibleSize.height - label->getContentSize().height));


    // add the label as a child to this layer
    this->addChild(label, 1);


//====================================================================================================================================================


//创建一个精灵用于反转等动画
auto sprite_flip = Sprite::create("CloseNormal.png");
sprite_flip->setPosition(Vec2(50, visibleSize.height/2));
this->addChild(sprite_flip, 1);


//动画演示 (可以用 auto 自动生成类型) 可以参考 http://www.jellythink.com/archives/749

//1、瞬时动画


//Place 瞬间移动 create(具体位置); 移动时间很快,一般看不到,不明显。
Place * pPlace = Place::create(Vec2(visibleSize.width/2, 50));
//label图层运行创建place的动画,下同。
label->runAction(pPlace);


//hide 隐藏动画 create(void);隐藏后消失。
Hide * pHide = Hide::create();
//label->runAction(pHide);


//show 显示动画 create(void);当运行隐藏动画后,就会重新显示。
Show * pShow = Show::create();
//label->runAction(pShow);


//ToggleVisibility 若先显示,则隐藏,若先隐藏,则显示 create(void); 可以用于判断,是显示和隐藏结合互反。
ToggleVisibility * pToggleVisibility = ToggleVisibility::create();
//label->runAction(pToggleVisibility);


//FlipX/FlipY 延X/Y轴反转 create(bool);精灵测试可以,而 label 的文本测试有中断错误
FlipX * pFlipX = FlipX::create(true);
sprite_flip->runAction(pFlipX);
FlipY * pFlipY = FlipY::create(true);
sprite_flip->runAction(pFlipY);


//2、延时动画


//MoveTo/MobveBy 移动到/移动多少距离 create(运行时间f,移动到的位置/移动的距离 ); 注意TO与BY的区别。 
MoveTo * pMoveTo = MoveTo::create(3.0f, Vec2(430, visibleSize.height/2));
//sprite_flip->runAction(pMoveTo);
MoveBy * pMoveBy = MoveBy::create(3.0f, Vec2(50, 50));
//sprite_flip->runAction(pMoveBy);


//JumpTo/JumpBy 跳动到/跳动多少距离 create(运行时间f, 跳动到的位置/跳动的距离,跳动的高度f,跳动的次数); 注意TO与BY的区别。
JumpTo * pJumpTo = JumpTo::create(3.0f, Vec2(430, visibleSize.height/2), 20.0f, 5);
//sprite_flip->runAction(pJumpTo);
JumpBy * pJumpBy = JumpBy::create(3.0f, Vec2(50, 50), 20.0f, 5);
//label->runAction(pJumpBy);


//BezierTo/BezierBy 延贝塞尔曲线运动到/延贝塞尔曲线运动多少距离 create(运行时间f, 一阶贝塞尔曲线特殊结构体); 注意引用结构体和TO与BY的区别。
//ccBezierConfig 结构体 第一个为起始点,二为控制点,三为末尾点。
ccBezierConfig BezierConfig = { Vec2(50, 30), Vec2(60, 100), Vec2(200, 120) };
BezierTo * pBezierTo = BezierTo::create(3.0f, BezierConfig);
//sprite_flip->runAction(pBezierTo);
BezierBy * pBezierBy = BezierBy::create(3.0f, BezierConfig);
//label->runAction(pBezierBy);


//ScaleTo/ScaleBy 缩放到多少/缩放了多少 create(运行时间f,一个参数f时为整体,2个3个参数f分别为x、y、z方向); 缩放时,大于一为放大,小于一为缩小。 
ScaleTo * pScaleTo = ScaleTo::create(3.0f, 0.5);
//sprite_flip->runAction(pScaleTo);
ScaleBy * pScaleBy = ScaleBy::create(3.0f, 1.5, 1.5);
//label->runAction(pScaleBy);


//RotateTo/RotateBy 旋转到/旋转了多少 create(运行时间f,线或者点或者面); 后面的参数可以是一条线,或者点,或者面,区别就是立体感觉,面时要用Vec3。  
RotateTo * pRotateTo = RotateTo::create(3.0f, visibleSize.width/2, visibleSize.height/2);
//sprite_flip->runAction(pRotateTo);
RotateBy * pRotateBy = RotateBy::create(3.0f, 350);
//label->runAction(pRotateBy);


//Blink 闪烁 create(运行时间f,闪烁次数); 闪烁是如星星的动画 
Blink * pBlink = Blink::create(3.0f, 5);
//label->runAction(pBlink);


//TintTo/TintBy 色调变化到/色调加减值 create(运行时间f,红值,绿值,蓝值); 当超过255或者低于0时,会进行在0-255循环加减。 
TintTo * pTintTo = TintTo::create(5.0f, 255, 20, 20);
//label->runAction(pTintTo);
TintBy * pTintBy = TintBy::create(5.0f, -255, 20, 20);
//label->runAction(pTintBy);


//FadeTo 变暗到 create(运行时间f, 明亮度); 明亮度是0-255之间,初始时是255,有亮变暗。 
FadeTo * pFadeTo = FadeTo::create(3.0f, 30);
//label->runAction(pFadeTo);


//FadeOut 渐隐 create(运行时间f); 可以配合组合动画与淡出配合
FadeOut * pFadeOut = FadeOut::create(3.0f);
//label->runAction(pFadeOut);


//FadeIn 淡出 create(运行时间f); 可以配合组合动画与渐隐配合
FadeIn * pFadeIn = FadeIn::create(3.0);
//label->runAction(pFadeIn);


//3、组合动画 


//先建立Animation create(), 在建立Animate帧动画 create(Animation); 有几种创建方式,详细资料参考 https://my.oschina.net/Jacedy/blog/301360
auto sprite_Animate = Sprite::create("grossini_dance_01.png");
sprite_Animate->setPosition(Vec2(visibleSize.width/2, visibleSize.height/2));
this->addChild(sprite_Animate, 1);
Animation * pAnimation = Animation::create();
for(int i=1; i<=14; i++)
{
char array_Animate[50] = {0};
//"grossini_dance_%02d.png" 注意这里的%02d
sprintf(array_Animate, "grossini_dance_%02d.png", i);
pAnimation->addSpriteFrameWithFile(array_Animate);
}
//每一帧停留的时间,14秒时间完成14幅图片显示,切记要写成14.0f形式!
pAnimation->setDelayPerUnit(14.0f / 14);  
//播放完后回到第一帧
    pAnimation->setRestoreOriginalFrame(true);      
    Animate * pAnimate = Animate::create(pAnimation);
    sprite_Animate->runAction(RepeatForever::create(pAnimate));


//Sequence 序列(顺序执行) create(要运行的动作,以逗号隔开,...,NULL); 依次顺序执行各个动作,记得最后以NULL结束。 
Sequence * pSequence = Sequence::create(pFadeOut, pFadeIn, pBlink, NULL);
//label->runAction(pSequence);


//Spawn 同步执行 create(要运行的动作,以逗号隔开,...,NULL);  每个动作同时进行,记得最后以NULL结束。
Spawn * pSpawn = Spawn::create(pBlink, pScaleBy, pTintTo, NULL);
//label->runAction(pSpawn);


//Repeat 重复有限次数 create(要运行的动画,运行次数); 可以和其他动画嵌套使用。 
Repeat * pRepeat = Repeat::create(pSpawn, 3);
//label->runAction(pRepeat);


//RepeatForever 重复无限次数 create(要运行的动画); 可以和其他动画嵌套使用。
RepeatForever * pRepeatForever = RepeatForever::create(pSequence);
//sprite_flip->runAction(pRepeatForever);


//Reverse 反动作 (动作)action->reverse(); 最好使用序列组合,否则同步时不好观察。
//(注意:以(动作)actionTo 的动作没有反动作的,如pRotateTo, 大部分以(动作)actionBy 的动作有反动作,如pRotateBy 。使用没有反动作的出现中止错误。)
ActionInterval * pReverse = pRotateBy->reverse();
//label->runAction(Sequence::create(pRotateBy, pReverse, NULL));


//4、扩展动作


//DelayTime 延时 create(延时的时间); 继承ActionInterval,可以与其他动作组合使用,相当与暂定几秒,一般动画过程中调用此函数。
DelayTime * pDelayTime = DelayTime::create(3);
//label->runAction(Sequence::create(pRotateBy, pDelayTime, pReverse, NULL));


/**
 * CallFunc系列动作的后缀”N”表示Node参数,指的是执行动作的对象, “D”表示Data参数,指的是用户自定义的数据,
 * ”O”表示对象,指的是一个用户自定义的Ref参数。
*/


//CallFunc 无参数函数 create(CC_CALLBACK_0(函数名,this)) 或 create(this, callfunc_selector(函数名)); 
//可以用CC_CALLBACK_0来引用,也可以使用callfunc_selector。
//注意CC_CALLBACK_?中0表示无参数,1表示一个参数,2表示两个参数,3表示3个参数,并且了解其构造和用法。
CallFunc * pCallFunc = CallFunc::create(this, callfunc_selector(HelloWorld::test_CallFunc));
//label->runAction(Sequence::create(pRotateBy, pDelayTime, pReverse, pCallFunc, NULL));


//CallFuncN 带当前节点Node参数函数 create(CC_CALLBACK_1(函数名,this)) 或 create(this, callfuncN_selector(函数名)); 
//可以用CC_CALLBACK_1来引用,也可以使用callfunc_selector。
CallFuncN * pCallFuncN = CallFuncN::create(CC_CALLBACK_1(HelloWorld::test_CallFuncN, this));
//label->runAction(Sequence::create(pRotateBy, pDelayTime, pReverse, pCallFuncN, NULL));


//CCCallFuncND 带当前节点Node参数和函数指针参数的函数 create(this, callfuncN_selector(函数名), void *指针); 
//这里不能用CC_CALLBACK_? 是因为Node * 与 void * 参数转化问题。
CCCallFuncND * pCCCallFuncND = CCCallFuncND::create(this, callfuncND_selector(HelloWorld::test_CCCallFuncND), (void *)0xbebabeba);
//sprite_flip->runAction(Sequence::create(pRotateBy, pDelayTime, pReverse, pCCCallFuncND, NULL));


//5、速度变化


//EaseIn 由慢变快(速度线性变化) create(动作,末速率f); 这里的 in 表示由慢变快。 
EaseIn * pEaseIn = EaseIn::create(pMoveBy, 5.0f);
//label->runAction(pEaseIn);


//EaseOut 由快变慢(速度线性变化) create(动作,初速率f); 这里的 out 表示由快变慢。
EaseOut * pEaseOut = EaseOut::create(pSequence, 5.0f);
//sprite_flip->runAction(pEaseOut);


//EaseInOut 由慢变快再由快变慢(速度线性变化) create(动作,初末速率f); 这里 in/out 同上面2种。
EaseInOut * pEaseInOut = EaseInOut::create(Sequence::create(pRotateBy, pDelayTime, pReverse, NULL), 5.0f);
//label->runAction(pEaseInOut);


//EaseSineIn 由慢变快(速度正弦变化) create(动作); 这里的 in 表示由慢变快。
EaseSineIn * pEaseSineIn = EaseSineIn::create(pJumpBy);
//label->runAction(pEaseSineIn);


//EaseSineOut 由快变慢(速度正弦变化) create(动作); 这里的 out 表示由快变慢。
EaseSineOut * pEaseSineOut = EaseSineOut::create(pBezierBy);
//sprite_flip->runAction(pEaseSineOut);


//EaseSineInOut 由慢变快再由快变慢(速度正弦变化) create(动作); 这里 in/out 同上面2种。
EaseSineInOut * pEaseSineInOut = EaseSineInOut::create(pRotateBy);
//label->runAction(pEaseSineInOut);


//EaseExponentialIn 由慢变快(速度指数变化) create(动作); 这里的 in 表示由慢变快。
EaseExponentialIn * pEaseExponentialIn = EaseExponentialIn::create(pScaleBy);
//sprite_flip->runAction(pEaseExponentialIn);


//EaseExponentialOut 由快变慢(速度指数变化) create(动作); 这里的 out 表示由快变慢。
EaseExponentialOut * pEaseExponentialOut = EaseExponentialOut::create(pBlink);
sprite_flip->runAction(pEaseExponentialOut);


//EaseExponentialInOut 由慢变快再由快变慢(速度指数变化) create(动作); 这里 in/out 同上面2种。
EaseExponentialInOut * pEaseExponentialInOut = EaseExponentialInOut::create(pTintTo);
label->runAction(pEaseExponentialInOut);


//====================================================================================================================================================


    // add "HelloWorld" splash screen"
    auto sprite = Sprite::create("HelloWorld.png");


    // position the sprite on the center of the screen
    sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));


    // add the sprite as a child to this layer
    this->addChild(sprite, 0);
    
    return true;
}


///>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


void HelloWorld::test_CallFunc()
{
CCLOG("CallFunc!");
}


void HelloWorld::test_CallFuncN(Node * pSence)
{
CCLOG("CallFuncN!!");
}


void HelloWorld::test_CCCallFuncND(Node * pSence, void * data)
{
CCLOG("CCCallFuncND!!!");
}


///<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<


void HelloWorld::menuCloseCallback(Ref* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
    return;
#endif


    Director::getInstance()->end();


#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
}




装载请注明:创建人:哈哈沃 交流群:580072227

谢谢浏览!!!不懂或有问题尽管留言甩给我,我定会全然接受与解决。

0 0
原创粉丝点击