我们知道,使用拼合图可以更节省内存,那如何使用拼合图播放一个序列帧动画呢?本节我们以HelloCpp为例来讲解一下。
第一步,我们要在将序列帧各帧图片合并成为拼合图。
下载地址: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
同时也欢迎有精力有能力的朋友参与我们。