基于上個http://blog.csdn.net/qxbailv15/article/details/17334825筆記的基礎,差不多就可以學習做個簡單的動畫了。
推薦閱讀地球人系列之二 http://www.cocoachina.com/gamedev/misc/2012/0528/4297.html
1.先通過可愛的TexturePacker 把我們需要用的所有資源圖檔打包成一個紋理檔案和plist配置檔案放到資源目錄
如下:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2QvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2LcFTRqR2csdVWphGWjZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DOygDMyYTMzEjNyITMzEDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
注意: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);