如何使用拼合图播放一个序列帧动画

长平狐 发布于 2013/03/19 18:39
阅读 2K+
收藏 0

红孩儿Cocos2d-x学习园地教学资料由 [红孩儿游戏编程教学组] 组织编写.版权所有,盗文必究!



如何使用拼合图播放一个序列帧动画

                                              本节主讲:红孩儿
[注:本版使用Cocos2d-x 2.02版本]

   

   我们知道,使用拼合图可以更节省内存,那如何使用拼合图播放一个序列帧动画呢?本节我们以HelloCpp为例来讲解一下。

第一步,我们要在将序列帧各帧图片合并成为拼合图。


 我们使用红孩儿纹理打包器1.1版本来进行拼图制做,它具有使用方便,拼图率高的特点。

下载地址:http://download.csdn.net/detail/honghaier/4671677

    我们以之前讲解的操作方法为例:

http://blog.csdn.net/honghaier/article/details/8117963

    最后生成的文件为:



第二步,我们要将所用到的信息结构定义一下。

         我们在HelloWorldScene.h中加入:

//二进制文件头信息

struct SPackFileHeader

{

    int        m_Version;        //版本

    char       m_szBigTexName[64];  //大图名称

    int        m_nImageSize;     //大图的大小

    int        m_nBlockNum;      //图块数量

};

//二进制文件数据块

struct SPackNode

{

    RECT       m_Rect;             //对应图块矩形

    POINT      m_OffsetPt;         //中心点偏移

    bool       m_bRotated;          //是否顺时针旋转度

};

    这样我们就可以读取出拼图的相应纹理块了。

第三步,创建序列帧动画。

         我们需要在HelloWorld的初始化中来创建这个序列帧动画:

bool 	HelloWorld::init()
{
	//基类初始化
	 if ( !CCLayer::init() )
    {
        return false;
    }
    //取得可视区域的大小
    CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
	//取得左下角坐标
    CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
	//创建拼图批次
	CCSpriteBatchNode* pNewBatchNode = CCSpriteBatchNode::create("Big_0.png", 34 );
	//读取二进制文件,将数据读取到容器中
	this->addChild(pNewBatchNode,1);
	//取得资源目录字符串
	string	szResPath(CCFileUtils::sharedFileUtils()->getResourceDirectory());
	//结尾加上拼合图信息文件名称。
	szResPath += "Big_0.blo";
	//读取拼合图信息文件全路径名
	FILE*	hFile = fopen(szResPath.c_str(),"rb");
	if(hFile)
	{
		//读取头信息
		SPackFileHeader	tFileHeader;
		fread(&tFileHeader,sizeof(SPackFileHeader),1,hFile);
		//读取每个纹理块信息
		SPackNode	tPackNode;
		//创建精灵帧存放容器
		CCArray*	tSpriteFrameArray = CCArray::create();
		//for循环进行读取相应数量的纹理块信息
		for(int b = 0 ; b < tFileHeader.m_nBlockNum ; ++b)
		{
			fread(&tPackNode,sizeof(SPackNode),1,hFile);
			//当前纹理块在图集纹理中的矩形位置。
			CCRect		tRect;
			//创建精灵
			if(tPackNode.m_bRotated)
			{
				//如果有旋转,宽高做一个调换。
				tRect = CCRect(tPackNode.m_Rect.left,tPackNode.m_Rect.top,tPackNode.m_Rect.bottom-tPackNode.m_Rect.top,tPackNode.m_Rect.right-tPackNode.m_Rect.left);
			}
			else
			{
				tRect = CCRect(tPackNode.m_Rect.left,tPackNode.m_Rect.top,tPackNode.m_Rect.right-tPackNode.m_Rect.left,tPackNode.m_Rect.bottom-tPackNode.m_Rect.top);
			}
			//
			CCPoint		tOffset(0,0);
			
			//设置纹理不进行抗锯齿模糊,像素精细
			pNewBatchNode->getTexture()->setAliasTexParameters();
			//设置从对应纹理块中读取出一个精灵帧
			CCSpriteFrame*	tpSpriteFrame = CCSpriteFrame::frameWithTexture(pNewBatchNode->getTexture(), tRect, tPackNode.m_bRotated, tOffset, tRect.size);
			//将精灵帧放入容器。	
			tSpriteFrameArray->addObject(tpSpriteFrame);
			
		}
               从精灵帧容器创建一个序列帧动画。
		CCAnimation* animation = CCAnimation::createWithSpriteFrames(tSpriteFrameArray,1.0f);  
		//设置每两帧间时间间隔为1秒。 
		animation->setDelayPerUnit(1.0f);  
		//设置动画结束后仍保留动画帧信息。 
		animation->setRestoreOriginalFrame(true);  
		//由这个动画信息创建一个序列帧动画。 
		CCAnimate* action = CCAnimate::create(animation);  
		//创建精灵。
		CCSprite* pSprite = CCSprite::create();
		//设置精灵位置。
		pSprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
		//让演员演示这个动画。 
		pSprite->runAction(action);  
		this->addChild(pSprite, 0);

		fclose(hFile);
	}  

    return true;
}


运行后的效果如图示[自已用flash做的gif,大概表示个意思哈~]:


课后总结:

本节主要的关健是如何读取纹理块信息然后生成精灵帧和动画。




教学组介绍:

红孩儿游戏编程教学组:致力于游戏编程方面的教程编写,目前主要工作重心在Cocos2d-x方向,希望大家支持!

目前成员有:

 

红孩儿: 九年游戏程序开发经验,参与过多款游戏的开发并任职主程序。

Jivin: 在编程路上,以初学者身份慢慢爬行着。博客:http://blog.csdn.net/laijingyao881201

Jovi: 一年多的端游程序开发经验,初步接触cocos2dx引擎。正在开发一款引擎是cocos2dx的手游。

畏天命: 资深游戏策划,项目经理。参与设计多款iOS游戏是教程组内唯一的业余程序员

一年前开始接触C++及cocos2d-x

将讲解涉及cocos2d-x学习中容易遇到的初级问题,

适合零起点选手入门,博客: http://blog.csdn.net/jyzgo

 

同时也欢迎有精力有能力的朋友参与我们。



原文链接:http://blog.csdn.net/honghaier/article/details/8237123
加载中
返回顶部
顶部