cocos2d-x学习笔记03——动画

基于上个http://blog.csdn.net/qxbailv15/article/details/17334825笔记的基础,差不多就可以学习做个简单的动画了。

推荐阅读地球人系列之二 http://www.cocoachina.com/gamedev/misc/2012/0528/4297.html

1.先通过可爱的TexturePacker 把我们需要用的所有资源图片打包成一个纹理文件和plist配置文件放到资源目录

如下:

 

 

注意:girl.png 天生就是一个多个帧组成的资源,由于没有与girl.png 对应的plsit配置文件,那么就没办法用Anti_TexturePacker工具来“反打包”,即拆包,拆成一张张的小图。所以接下来的介绍的制作动画的方法是需要自己用程序拆的情况。

 

 images2.png感觉浪费了好多空间,才刚开始学习使用TexturePacker 工具,好多参数还需要设置。

2.写一个获取纹理块上的所需要的一个帧的函数

// 获取一个帧
CCSpriteFrame * spriteFrameWithStrip(const char *name, int col, int row, int startingRow, int startingCol)
{
	CCSpriteFrameCache* pCache = CCSpriteFrameCache::sharedSpriteFrameCache();
	CCSpriteFrame* pStrip = pCache->spriteFrameByName(name);  // pStrip 是纹理块对应的精灵帧,需要拆分
	CCTexture2D* pTexture = pStrip->getTexture();             // 整个纹理
	CCSize originalSize = pStrip->getOriginalSize();          // 取得纹理块的大小
	bool bRotated = pStrip->isRotated();

	float w = originalSize.width/col;       // 单位帧的宽度
	float h = originalSize.height/row;      // 单位帧的高度

	float xx = startingCol*w;               // 裁剪的当前坐标xx
	float yy = startingRow*h;               // 裁剪的当前坐标yy

	CCSpriteFrame *frame = CCSpriteFrame::frameWithTexture(pTexture, CCRectMake(xx, yy, w, h));
	frame->setRotated(bRotated);
	
	return frame;
}

 

3.写一个获取纹理块上的所需要的多个帧的函数(暂不支持旋转90度后的纹理块)

// 获取多个帧组成的动画
// count 是想要生成的动画的帧数
// name 是动画使用的纹理块,col是指纹理块一共多少个列,row是指纹理块一共多少个行,
// startingRow 是指动画使用的纹理快开始的行索引frame,startingCol是动画开始的纹理块的列索引frame
CCAnimation * animationWithStrip(const char *name, int count, float delay, int col, int row, int startingRow,int startingCol)
{
	CCArray* array_spriteFrames = new CCArray(count);
	CCSpriteFrameCache* pCache = CCSpriteFrameCache::sharedSpriteFrameCache();
	CCSpriteFrame* pStrip = pCache->spriteFrameByName(name);  // pStrip 是纹理块对应的精灵帧,需要拆分
	CCTexture2D* pTexture = pStrip->getTexture();             // 整个纹理
	CCSize originalSize = pStrip->getOriginalSize();          // 取得纹理块的大小
	bool bRotated = pStrip->isRotated();
	CCRect stripRect = pStrip->getRect();                     // 取得纹理快的矩形区域

	float w = originalSize.width/col;       // 单位帧的宽度
	float h = originalSize.height/row;      // 单位帧的高度

	float x = stripRect.origin.x;           // 纹理块的左上x坐标
	float y = stripRect.origin.y;           // 纹理块的左上y坐标

	int n = 0;

	float xx = startingCol*w;                               // 裁剪的当前坐标xx
	float yy = startingRow*h;                               // 裁剪的当前坐标yy

	for (int n=0;n<count;n++)
	{
		CCSpriteFrame *frame = CCSpriteFrame::frameWithTexture(pTexture, CCRectMake(xx, yy, w, h));
		frame->setRotated(bRotated);
		array_spriteFrames->addObject(frame);
		n++;
		xx+=w;
	}

	CCAnimation *animation = CCAnimation::animationWithSpriteFrames(array_spriteFrames, delay);

	return animation;
}

4. 利用用上面的自定义工具函数在场景的init函数留写代码(以后可以封装到一个类,作为常用工具类)

		CCSize size = CCDirector::sharedDirector()->getWinSize();
		CCSpriteFrameCache* pCache = CCSpriteFrameCache::sharedSpriteFrameCache();
		pCache->addSpriteFramesWithFile("src02/images2.plist","src02/images2.png");
		
		CCTexture2D* pTexture =  CCTextureCache::sharedTextureCache()->textureForKey("src02/images2.png");
		CCSpriteBatchNode* pSpriteBatch = CCSpriteBatchNode::batchNodeWithTexture(pTexture);
		addChild(pSpriteBatch);

		CCSprite* pBk = CCSprite::spriteWithSpriteFrameName("bk.jpg");
		CC_BREAK_IF(! pBk);
		pBk->setPosition(ccp(size.width/2, size.height/2));
		pSpriteBatch->addChild(pBk);

		CCAnimation *animation = animationWithStrip("girl.png",8,0.1,10,5,1,2);
		CCSpriteFrame* pFirstFrame = spriteFrameWithStrip("girl.png",10,5,1,2);
		CCSprite* pSprite = CCSprite::spriteWithSpriteFrame(pFirstFrame);
		CC_BREAK_IF(! pSprite);
		pSprite->setPosition(ccp(size.width/2, size.height/2));
		pSpriteBatch->addChild(pSprite);

		pSprite->runAction( CCRepeatForever::actionWithAction( CCAnimate::actionWithAnimation(animation)) );

CCSpriteFrame* pFirstFrame = spriteFrameWithStrip("girl.png",10,5,1,2);

CCSprite* pSprite = CCSprite::spriteWithSpriteFrame(pFirstFrame);

这个调用是取第1行,第2列的那个帧,来作为原始帧,然后利用它生成一个精灵。

 

CCAnimation *animation = animationWithStrip("girl.png",8,0.1,10,5,1,2);

这个调用是取得一系列的帧信息,然后保存到animation里。

 

5.运行代码:

 

哈哈,可以看见一个小姑娘在原地不断切换自己的脚步了。

 

下一次再帮她移动位置好了,边移动位置,边切换脚步,才不会看起来那么奇怪。


好了,再说说另一种情况,那就是假如我有一张组合图,它有对应的plist,

那么就简单很多了,不需要自己用程序写切图的代码来生成动画。

// 初始玩家精灵,用于运行动画
		CCSprite* sprite = CCSprite::createWithSpriteFrameName("player_01.png");  
		CC_BREAK_IF(! sprite);
		sprite->setPosition(XSystem::xccp(SCREEN_DEFAULT_WIDTH / 2, SCREEN_DEFAULT_HEIGHT/8));

	   //*创建一个帧动画,让玩家有动态感,可以逐张图片添加方式去添加动画 */ 
	   CCSpriteFrameCache* pCache = CCSpriteFrameCache::sharedSpriteFrameCache();  
	   CCArray* frames = new CCArray();  
	   // 帧图片
	   CCSpriteFrame* pSpriteFrame = NULL;  
	   // 通过几张独立的帧图片去组成动画   
	   char szImageName[128] = {0};  
	   for (int i=1; i<=3; i++)
	   {  
	      sprintf(szImageName,"player_%02d.png",i);
	      pSpriteFrame = pCache->spriteFrameByName(szImageName);
	      frames->addObject(pSpriteFrame);  
	   }  
	   //创建动画,第二个参数默认delay为0.0f,请不要以为0表示没有延迟,而是直接停止了。   
	   CCAnimation* anim = CCAnimation::animationWithSpriteFrames(frames, 3.0f);  
	   //播放动画
	   sprite->runAction(CCRepeatForever::actionWithAction(CCAnimate::actionWithAnimation(anim)));  
	   batchNode->addChild(sprite);
	   this->setVisual(sprite);







 


 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值