Learning Cocos2d-x for WP8(8)——动作Action

游戏很大程度上是由动作画面支撑起来的。

动作分为两大类:瞬间动作和延时动作。

瞬间动作基本等同于设置节点的属性,延时动作会执行一段时间,不需要清除这两种动作,一旦动作完成,就会从节点上清除并释放所占内存。

 

封装CCSpriteBatchNode的使用方法

BatchAnimatitonSprite
 1 CCSprite* SpriteActionLayer::BatchAnimatitonSprite(CCLayer* pLayer,CCSprite *pSprite, CCPoint* spriteStartPoint, const char *strFramesFileName,const char *strFramesFileNameImg,const char *strFirstFrameName,const char *strEachFrameName,int frameCount,float frameDelay)
 2 {
 3     //CCSpriteBatchNode
 4     //创建批处理节点,读取plist文件
 5     CCSpriteFrameCache* cache=CCSpriteFrameCache::sharedSpriteFrameCache();
 6     cache->addSpriteFramesWithFile(strFramesFileName,strFramesFileNameImg);
 7 
 8     //起始精灵
 9     pSprite=CCSprite::spriteWithSpriteFrameName(strFirstFrameName);//纹理plist中包含strfirstFrameName
10     pSprite->setPosition(ccp(spriteStartPoint->x,spriteStartPoint->y));    
11     
12     CCSpriteBatchNode* spritebatch = CCSpriteBatchNode::batchNodeWithFile(strFramesFileNameImg);//与CCSpriteFrameCache同一纹理
13     spritebatch->addChild(pSprite);
14     pLayer->addChild(spritebatch,1);
15 
16     //创建逐帧数组
17     CCMutableArray<CCSpriteFrame*>* animFrames1=new CCMutableArray<CCSpriteFrame*>(frameCount);
18     char str1[100]={0};
19     for(int i=0;i<frameCount;i++)
20     {
21         sprintf(str1,strEachFrameName,i);
22         CCSpriteFrame* pFrame=cache->spriteFrameByName( str1 );
23         animFrames1->addObject(pFrame);
24     }
25 
26     CCAnimation* animation1=CCAnimation::animationWithFrames(animFrames1,frameDelay);
27     pSprite->runAction(CCRepeatForever::actionWithAction(CCAnimate::actionWithAnimation(animation1,false)));
28 
29     animFrames1->release();
30     return pSprite;
31 }


重复动作

可以使一个动作或一系列的动作不停地重复无限循环,除非“外力”使其停止。

实例

1     //重复动作
2     CCSprite *role0=CCSprite::spriteWithFile("Sprite/Role.png");
3     role0->setPosition(ccp(100,s.height-100));
4     addChild(role0,1);
5     CCRotateBy* role0RotateBy=CCRotateBy::actionWithDuration(2.0f,360);
6     CCRepeatForever* role0Repeat=CCRepeatForever::actionWithAction(role0RotateBy);
7     role0->runAction(role0Repeat);

Sprite循环不停地旋转

流畅动画

CCEaseAction类能在一段时间内动作的流畅执行,使得更强大。而非简单地执行简单动画效果。

在实际运动过程中,匀速运动在启动和结束时往往会有一定的加速和减速的效果,这样更加的真实。

cocoos2d-x引擎提供了相关的API,免除了我们编写相关的算法实现的烦恼,实现起来相当的方便。

实现该方法的是CCActionEase中CCEaseRateAction系列,大体分成三类:

In:开始时候的加速度

Out:结束时候的加速度

InOut:开始结束时候的加速度

(以下图片来源其他博文,具体地址忘记了,以后再加上)

1.指数缓冲

EaseExponentialIn

EaseExponentialOut

EaseExponentialInOut

2.赛因缓冲

EaseSineIn

EaseSineOut

EaseSineInOut

3.弹性缓冲

EaseElasticIn

EaseElasticOut

EaseElasticInOut

4.跳跃缓冲

EaseBounceIn

EaseBounceOut

EaseBounceInOut

5.回震缓冲

EaseBackIn

EaseBackOut

EaseBackInOut

 

实例

1     //流畅动画
2     CCSprite* role1=NULL;
3     role1=SpriteActionLayer::BatchAnimatitonSprite(this,role1,new CCPoint(100,s.height/2),"Sprite/Plist/RoleRun.plist","Sprite/Plist/RoleRun.png","RoleRun0.png","RoleRun%d.png",10,0.2f);
4     CCMoveTo* role1Move=CCMoveTo::actionWithDuration(5,CCPointMake(s.width-100,s.height/2));//CCMoveTo绝对位置移动
5     CCEaseInOut* role1MoveEase=CCEaseInOut::actionWithAction(role1Move,4);//rate=4,决定流畅动画的明显程度,只有当它大于1时才能看到效果
6     role1->runAction(role1MoveEase);

可见,Sprite开始缓慢移动——加速——缓慢停止。

动作序列

通常情况下,Action动作执行添加多个动作时,它们会在同一时间运行,如上面的动作。但有时我们需要让动作一个接着一个运行。CCSequence将实现该功能。

实例

1     //动作序列
2     CCSprite* role2=NULL;
3     role2=SpriteActionLayer::BatchAnimatitonSprite(this,role2,new CCPoint(100,s.height/4),"Sprite/Plist/Role2Run.plist","Sprite/Plist/Role2Run.png","Role2Run0.png","Role2Run%d.png",10,0.3f);
4     CCMoveBy* role2MoveBy=CCMoveBy::actionWithDuration(5,CCPointMake(500,0));//CCMoveBy相对位置移动
5     CCJumpBy* role2JumpBy=CCJumpBy::actionWithDuration(1,CCPointMake(-500,0),100,1);//CCJumpBy相当位置jump
6     role2->runAction(CCSequence::actions(role2MoveBy,role2JumpBy,NULL));

Sprite跑动到指定位置后,下个动作就是弹跳回起始位置

瞬间动作

有时在一串动作中,需要改变Sprite的属性,然后在继续执行下个动作。瞬间动作将实现该功能,通常情况下依赖与CCCallFunc动作。

实例

1     //瞬时动作
2     CCSprite* role3=CCSprite::spriteWithFile("Sprite/Role.png");
3     role3->setPosition(ccp(s.width-100,s.height-100));
4     addChild(role3,1);
5     CCScaleTo * role3ScaleTo=CCScaleTo::actionWithDuration(2,2.0f);
6     CCCallFuncN* role3FunN=CCCallFuncN::actionWithTarget(this,callfuncN_selector(SpriteActionLayer::repeatForever));
7     role3->runAction(CCSequence::actions(role3ScaleTo,role3FunN,NULL));

repeatForever方法

1 void SpriteActionLayer::repeatForever(CCNode* pSender)
2 {
3     CCRepeatForever* repeat=CCRepeatForever::actionWithAction(CCSkewBy::actionWithDuration(5, 37.2f, -37.2f));//歪斜
4     pSender->runAction(repeat);
5 }

执行完ScaleTo后执行SkewBy

 

完整源码

SpriteActionTest.h
 1 #ifndef _SPRITE_ACTION_TEST_
 2 #define _SPRITE_ACTION_TEST_
 3 
 4 #include "cocos2d.h"
 5 using namespace cocos2d;
 6 
 7 class SpriteActionScene:public CCScene
 8 {
 9 public:
10     SpriteActionScene();
11     ~SpriteActionScene();
12 
13     virtual void onEnter();
14     
15 };
16 
17 
18 
19 class SpriteActionLayer:public CCLayer
20 {
21 public:
22     SpriteActionLayer();
23     ~SpriteActionLayer();
24 
25 public:
26     void repeatForever(CCNode* pTarget);
27     CCSprite* BatchAnimatitonSprite(CCLayer* pLayer,CCSprite *pSprite,CCPoint* spriteStartPoint,const char *strFramesFileName,const char *strFramesFileNameImg,const char *strFirstFrameName,const char *strEachFrameName,int frameCount,float frameDelay);
28 };
29 
30 
31 
32 #endif
SpriteActionTest.cpp
  1 #include "pch.h"
  2 #include "Classes\SpriteActionTest.h"
  3 
  4 
  5 //----------------------------------------
  6 //
  7 //SpriteActionLayer
  8 //
  9 //----------------------------------------
 10 SpriteActionLayer::SpriteActionLayer()
 11 {        
 12     CCSize s=CCDirector::sharedDirector()->getWinSize();
 13     
 14     //重复动作
 15     CCSprite *role0=CCSprite::spriteWithFile("Sprite/Role.png");
 16     role0->setPosition(ccp(100,s.height-100));
 17     addChild(role0,1);
 18     CCRotateBy* role0RotateBy=CCRotateBy::actionWithDuration(2.0f,360);
 19     CCRepeatForever* role0Repeat=CCRepeatForever::actionWithAction(role0RotateBy);
 20     role0->runAction(role0Repeat);
 21 
 22     //流畅动画
 23     CCSprite* role1=NULL;
 24     role1=SpriteActionLayer::BatchAnimatitonSprite(this,role1,new CCPoint(100,s.height/2),"Sprite/Plist/RoleRun.plist","Sprite/Plist/RoleRun.png","RoleRun0.png","RoleRun%d.png",10,0.2f);
 25     CCMoveTo* role1Move=CCMoveTo::actionWithDuration(5,CCPointMake(s.width-100,s.height/2));//CCMoveTo绝对位置移动
 26     CCEaseInOut* role1MoveEase=CCEaseInOut::actionWithAction(role1Move,4);//rate=4,决定流畅动画的明显程度,只有当它大于1时才能看到效果
 27     role1->runAction(role1MoveEase);
 28 
 29     //动作序列
 30     CCSprite* role2=NULL;
 31     role2=SpriteActionLayer::BatchAnimatitonSprite(this,role2,new CCPoint(100,s.height/4),"Sprite/Plist/Role2Run.plist","Sprite/Plist/Role2Run.png","Role2Run0.png","Role2Run%d.png",10,0.3f);
 32     CCMoveBy* role2MoveBy=CCMoveBy::actionWithDuration(5,CCPointMake(500,0));//CCMoveBy相对位置移动
 33     CCJumpBy* role2JumpBy=CCJumpBy::actionWithDuration(1,CCPointMake(-500,0),100,1);//CCJumpBy相当位置jump
 34     role2->runAction(CCSequence::actions(role2MoveBy,role2JumpBy,NULL));
 35 
 36     //瞬时动作
 37     CCSprite* role3=CCSprite::spriteWithFile("Sprite/Role.png");
 38     role3->setPosition(ccp(s.width-100,s.height-100));
 39     addChild(role3,1);
 40     CCScaleTo * role3ScaleTo=CCScaleTo::actionWithDuration(2,2.0f);
 41     CCCallFuncN* role3FunN=CCCallFuncN::actionWithTarget(this,callfuncN_selector(SpriteActionLayer::repeatForever));
 42     role3->runAction(CCSequence::actions(role3ScaleTo,role3FunN,NULL));
 43 }
 44 
 45 void SpriteActionLayer::repeatForever(CCNode* pSender)
 46 {
 47     CCRepeatForever* repeat=CCRepeatForever::actionWithAction(CCSkewBy::actionWithDuration(5, 37.2f, -37.2f));//歪斜
 48     pSender->runAction(repeat);
 49 }
 50 
 51 SpriteActionLayer::~SpriteActionLayer()
 52 {}
 53 
 54 CCSprite* SpriteActionLayer::BatchAnimatitonSprite(CCLayer* pLayer,CCSprite *pSprite, CCPoint* spriteStartPoint, const char *strFramesFileName,const char *strFramesFileNameImg,const char *strFirstFrameName,const char *strEachFrameName,int frameCount,float frameDelay)
 55 {
 56     //CCSpriteBatchNode
 57     //创建批处理节点,读取plist文件
 58     CCSpriteFrameCache* cache=CCSpriteFrameCache::sharedSpriteFrameCache();
 59     cache->addSpriteFramesWithFile(strFramesFileName,strFramesFileNameImg);
 60 
 61     //起始精灵
 62     pSprite=CCSprite::spriteWithSpriteFrameName(strFirstFrameName);//纹理plist中包含strfirstFrameName
 63     pSprite->setPosition(ccp(spriteStartPoint->x,spriteStartPoint->y));    
 64     
 65     CCSpriteBatchNode* spritebatch = CCSpriteBatchNode::batchNodeWithFile(strFramesFileNameImg);//与CCSpriteFrameCache同一纹理
 66     spritebatch->addChild(pSprite);
 67     pLayer->addChild(spritebatch,1);
 68 
 69     //创建逐帧数组
 70     CCMutableArray<CCSpriteFrame*>* animFrames1=new CCMutableArray<CCSpriteFrame*>(frameCount);
 71     char str1[100]={0};
 72     for(int i=0;i<frameCount;i++)
 73     {
 74         sprintf(str1,strEachFrameName,i);
 75         CCSpriteFrame* pFrame=cache->spriteFrameByName( str1 );
 76         animFrames1->addObject(pFrame);
 77     }
 78 
 79     CCAnimation* animation1=CCAnimation::animationWithFrames(animFrames1,frameDelay);
 80     pSprite->runAction(CCRepeatForever::actionWithAction(CCAnimate::actionWithAnimation(animation1,false)));
 81 
 82     animFrames1->release();
 83     return pSprite;
 84 }
 85 
 86 //----------------------------------------
 87 //
 88 //SpriteActionScene
 89 //
 90 //----------------------------------------
 91 
 92 SpriteActionScene::SpriteActionScene()
 93 {}
 94 
 95 SpriteActionScene::~SpriteActionScene()
 96 {}
 97 
 98 void SpriteActionScene::onEnter()
 99 {
100     CCScene::onEnter();
101     CCLayer* spriteActionLayer=new SpriteActionLayer();
102     addChild(spriteActionLayer);
103     spriteActionLayer->release();
104 }

 

著作权声明:本文由http://www.cnblogs.com/suguoqiang 原创,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!

posted @ 2013-04-22 09:33 Ghost Soar 阅读(...) 评论(...) 编辑 收藏