原文: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 原创,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!