楓葉天空Cocos2d-x3.0系列教程二 序列幀動畫
更新日誌:
2014-01-31 增加了cocoStudio動畫編輯器的說明
內容概述:
從今天開始,我們就正式進入cocos2d-x3.0的開發教程了,本篇的核心內容是序列幀動畫。
準備工作1、首先我們建立一個新的場景類,作為我們本系列教程的一個主場景。
建立方法就是在TestGame中右鍵選擇“新增”-》“新建項”,然後分別建立我們的.h檔案和.cpp檔案,我將他們命名為"GameScene",如圖:
注意紅框的設定,我之所以選擇這種做法是因為我們建立的類必須要存在於Classes目錄下,否則是無法被訪問到的。如果我們使用了“新增“-》”類”這個操作,我們就會發現新建的類會自動的進入“F:\TestGame\proj.win32”目錄下,而無法被AppDelegate.cpp等檔案所識別,所以此處我只有使用“新建項”這個方法。當然,用這個方法也有一個弊端,那就是全部的程式碼都要手寫。例如類名,引入包之類的,此處我誠心的向各位大牛求教,你們是否有更好的辦法。相對於flashbuilder,我只能說vs這個地方做的太差了。
2、編寫GameScene.h檔案,程式碼如下:
#include "cocos2d.h"
class GameScene : public cocos2d::Scene
{
public:
//初始化方法
virtual bool init();
//呼叫巨集CREATE_FUNC,使系統自動的為GameScene類建立一個create方法
CREATE_FUNC(GameScene);
private:
//定義一個私有方法,用來執行動畫播放函式
void runAnimation();
};
3、編寫GameScene.cpp,程式碼如下:
#include "GameScene.h" //使用cocos2d-x的名稱空間 USING_NS_CC; bool GameScene::init(){ //呼叫父類的初始化方法 if (!Scene::init()){ return false; } runAnimation(); return true; } //以後將在這裡進行動畫函式的呼叫 void GameScene::runAnimation(){ }
4、修改AppDelegate.cpp,使其呼叫我們的主場景,程式碼如下:
//將AppDelegate.cpp的29行程式碼註釋掉,替換成GameScene的create方法建立一個GameScene
//auto scene = HelloWorld::createScene();
auto scene = GameScene::create();
5、重新生成,除錯。至此我們的準備工作就做完了。
序列幀動畫教程 一、序列幀動畫的基本原理
1、編寫AnimationManager.h檔案,程式碼如下:
#include "cocos2d.h" //此處的繼承不知道是否是最合適的,目前幾個容器的關係我還沒有弄得太懂,待後期我會重新整理 class AnimationManager :public cocos2d::Sprite{ public: //呼叫巨集CREATE_FUNC,使系統自動的為GameScene類建立一個create方法 CREATE_FUNC(AnimationManager); //基礎序列幀動畫播放 void testAnimationOne(); //plist序列幀動畫播放 void testAnimationTwo(); //應用級序列幀動畫播放 void testAnimationThree(); };
2、編寫AnimationManager.cpp,程式碼如下:
#include "AnimationManager.h"
//使用cocos2d-x的名稱空間
USING_NS_CC;
void AnimationManager::testAnimationOne(){
//列印日誌
CCLOG("run testAnimationOne");
//此處使用了一組序列幀圖片,改組圖片存放於專案的Resource/actor目錄下。圖片的名稱是從00001.png開始,至00008.png結束,
//程式碼與資源請參見教程索引頁面的下載地址,索引頁面的連結在文章的底部
Sprite* sp = Sprite::create("actor/00001.png");
sp->setPosition(ccp(170, 200));
addChild(sp);
//建立一個動畫物件
Animation* animation = Animation::create();
char str[100] = { 0 };
//圖片的總長度為8
for (int i = 1; i <= 8; i++){
//下面的方法是將迴圈中的索引拼成我們序列幀的資源名稱
sprintf(str, "actor/0000%i.png", i);
animation->addSpriteFrameWithFileName(str);
}
animation->setDelayPerUnit(0.03f);//必須設定否則不會動態播放
animation->setRestoreOriginalFrame(true);//是否回到第一幀
animation->setLoops(-1);//重複次數 (-1:無限迴圈)
FiniteTimeAction * animate = Animate::create(animation);
sp->runAction(animate);
}
3、在GameScene.cpp中呼叫動畫播放方法,程式碼如下:
//以後將在這裡進行動畫函式的呼叫
void GameScene::runAnimation(){
AnimationManager *sprite = AnimationManager::create();
addChild(sprite);
//執行基礎序列幀動畫播放
sprite->testAnimationOne();
}
上面的這個方法是動畫播放最基礎的一個原理展示方法,其核心思想就是將一組序列幀載入如記憶體,然後迴圈播放。大家可以注意到,此處使用了很多的硬編碼,例如資源名稱,資源長度等,另外,獨立的載入每一張圖片資源對於效能來說也是極其消耗的,我們在實際的專案中是不會這樣去進行開發的。下面我介紹一種進階方法。
二、使用plist檔案播放序列幀動畫有關plist檔案,網上的介紹很多,這裡不作贅述。我們只需要把它理解成xml檔案即可。
本方法的原理就是,將原本細碎的序列幀拼接成一張大圖,同時將各碎圖的資訊儲存在plist檔案或者其他格式的檔案中,然後在程式碼中對碎圖的資訊進行解析,最後播放。這樣做的好處是一次載入,減少I/O,提高速度。
1、本段使用TexturePacker工具生成了actor.png和actor.plist檔案。其中actor.png就是拼接後的大圖。同上,需要將這兩個檔案考入專案的Resource目錄。
2、編寫AnimationManager.cpp中的testAnimationTwo方法,程式碼如下:
void AnimationManager::testAnimationTwo(){
CCLOG("run testTwo");
Texture2D::PVRImagesHavePremultipliedAlpha(true);
SpriteFrameCache *spriteFrameCache = SpriteFrameCache::sharedSpriteFrameCache();
spriteFrameCache->addSpriteFramesWithFile("actor.plist");
//此處是一種優化做法,但是具體的優化度,本人尚未測試,待後期給大家一個答覆
CCSpriteBatchNode *spriteBatchNode = CCSpriteBatchNode::create("actor.png");
addChild(spriteBatchNode);
//利用幀快取建立精靈
Sprite* sp = Sprite::createWithSpriteFrameName("00001.png");
sp->setPosition(ccp(170, 200));
spriteBatchNode->addChild(sp);
//建立一個序列幀的vector
Vector<SpriteFrame *> spriteFrame;
char str[100] = { 0 };
for (int i = 1; i <= 8; i++){
sprintf(str, "0000%i.png", i);
SpriteFrame *frame = spriteFrameCache->getSpriteFrameByName(str);
//將每幀的動畫資訊存入vector
spriteFrame.pushBack(frame);
}
Animation* animation = Animation::createWithSpriteFrames(spriteFrame, 0.03f);
animation->setLoops(-1);
sp->runAction(Animate::create(animation));
spriteFrameCache->removeSpriteFrameByName("actor.plist");
}
3、在GameScene.cpp中呼叫動畫播放方法,程式碼如下:
//以後將在這裡進行動畫函式的呼叫
void GameScene::runAnimation(){
AnimationManager *sprite = AnimationManager::create();
addChild(sprite);
//執行plist序列幀動畫播放
sprite->testAnimationTwo();
}
看到此處,大家可能發現了問題,在上面的程式碼中依然有些資料是硬編碼,例如資源的長度8。的確,我查了很久,也沒有在api找到如何才能獲取plist檔案長度的方法。同樣上面的方法也不適用於實際的開發,僅能作為原理示例程式碼,畢竟我們要懂得原理才能進行深入的開發。下面,我將介紹一種真正的播放方法,而這種方法將是我們在實際開發中最常用的一種。
三、使用紅孩兒工具箱進行序列幀動畫的製作在這裡,我給大家介紹一款工具——“紅孩兒工具箱”,官網地址:http://www.game2z.com/ QQ群:20970366。該工具是我繼mornUI之後,所見到的第二款國人制作的優秀開發工具,在這裡,我向作者表示衷心的感謝,感謝他的無私奉獻。
1、利用紅孩兒工具箱,的拼圖和動畫編輯功能,我生成了三個檔案,分別是“actor_0.plist”,“actor_0.png”,“testani.plist”。具體的做法這裡就不贅述,大家可以參考工具箱的使用說明。前兩個檔案與方法二所用的檔案相同,是用來描述各碎圖序列幀的資訊的。第三個檔案,才是本方法的重點,他在裡面儲存了具體的動畫資訊,大家可以使用工具生成後,自行檢視。
2、編寫AnimationManager的testAnimationThree方法,程式碼如下:
void AnimationManager::testAnimationThree(){
CCLOG("run testAnimationThree");
//讀取拼接圖片的資訊plist檔案
CCSpriteFrameCache *frameCache = CCSpriteFrameCache::sharedSpriteFrameCache();
frameCache->addSpriteFramesWithFile("actor_0.plist");
// Purge previously loaded animation
CCAnimationCache::purgeSharedAnimationCache();
CCAnimationCache *animCache = CCAnimationCache::sharedAnimationCache();
// 向快取中增加動畫資訊
animCache->addAnimationsWithFile("testani.plist");
//讀取名稱為testAni的動畫資訊
CCAnimation *testAni = animCache->animationByName("testAni");
testAni->setRestoreOriginalFrame(true);
//建立動畫
CCAnimate *anim1 = CCAnimate::create(testAni);
//建立動畫序列
CCSequence *seq = (CCSequence*)CCSequence::create(anim1, NULL);
CCSprite *yezhu = CCSprite::create();
CCSpriteFrame *frame = frameCache->spriteFrameByName("00001.png");
yezhu->setDisplayFrame(frame);
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
yezhu->setPosition(ccp(winSize.width / 2, winSize.height / 2));
addChild(yezhu);
// run the animation
yezhu->runAction(seq);
}
3、在GameScene.cpp中呼叫動畫播放方法,程式碼如下:
//以後將在這裡進行動畫函式的呼叫
void GameScene::runAnimation(){
AnimationManager *sprite = AnimationManager::create();
addChild(sprite);
sprite->testAnimationThree();
}
至此,一個適用於應用級的動畫播放就完成了。雖然其中還有一些硬編碼的內容,但是這已經不再影響,我們可以通過具體的資源管理來處理這個問題。我在此再來解釋一遍,首先我們的做法與方法二相同,是將“actor_0.plist”與“actor_0.png‘ 載入進來,這兩個檔案儲存了每個序列幀的資訊,然後我們再將儲存動畫資訊的”testAni.plist"載入進來,這裡儲存了每個動畫的序列幀的順序及動畫間隔,然後再對照前兩個檔案找出當前序列幀的偏移,寬高等資訊,最終播放出來。
怎麼樣,你們發現問題了嗎?那就是,為什麼要使用兩個plist檔案才能播放動畫?這個問題我百思不得其解,不過參考蘋果以往那些反人類的做法,我也就釋然了。所以,至此我決定自己進行第四種方法的製作,那就是將序列幀的圖片資訊和動畫資訊組合在一起成為一個檔案的方法。
但是,不是在現在。在節後,我會將這件事情的優先順序排到最高,儘快給出一個高效的工具。
四、使用CocoStudio進行序列幀動畫的製作最後講解一下CocoStudio的動畫編輯器。該工具也提供了強大的動畫編輯功能,操作簡單。具體的操作方法,可以參見CocoStudio的手冊說明,簡單的說來,就是將一組序列幀拖拽到舞臺,然後匯出專案,此刻就會生成三個檔案,一個png檔案,一個plist檔案,一個ExportJson檔案。png檔案是拼合的大圖檔案,plist檔案儲存的是每一張序列幀圖片的資訊,ExportJson檔案儲存的則是動畫的資訊,這三個檔案的功用基本與方法三的三個檔案雷同,在此也不再進行贅述。
好了,本節教程到此結束,下一節,我將給大家講解Cocos2d-x的ui元件。
相關推薦
楓葉天空Cocos2d-x3.0系列教程二 序列幀動畫
更新日誌: 2014-01-31 增加了cocoStudio動畫編輯器的說明 內容概述: 從今天開始,我們就正式進入cocos2d-x3.0的開發教程了,本篇的核心內容是序列幀動畫。 準備工作 1、首先我們建立一個新的場景類,作為我們本系列教程的一
JXLS 2.4.0系列教程(二)——循環導出一個鏈表的數據
教程 super 最簡 com arraylist port 至少 ron mod 請務必先看上一篇文章,本文在上一篇文章的代碼基礎上修改而成。 JXLS 2.4.0系列教程(一)——最簡單的模板導出 上一篇文章我們介紹了JXLS和模板導出最簡單的應用,現在我們要更進一
OAuth 2.0系列教程(二) 綜述
作者:Jakob Jenkov 譯者:林浩 校對:郭蕾 如引言所說的,OAuth 2.0是一個能夠使應用彼此訪問資料的開放授權協議,這裡我們將闡述該協議是怎麼工作的以及規範中提到的概念。該圖說明了整個授權過程: OAuth 2.0怎樣被用來在應用間共享資料的例子 第一步,使用者訪
solr 6.2.0系列教程(二)IK中文分詞器配置及新增擴充套件詞、停止詞、同義詞
前言 2、solr的不同版本,對應不同版本的IK分詞器。由於IK 2012年停止更新了。所以以前的版本不適合新版的solr。 有幸在網上扒到了IK原始碼自己稍微做了調整,用來相容solr6.2.0版本。IK原始碼下載地址 步驟 1、解壓下載的src.rar壓縮包,這是我建
cocos2d-x3.0/2.0 win7第一次建立專案需要呼叫到的指令碼(不斷更新維護)//cocos2d-x 教程一
第一步: github上最新的引擎,值得注意的是官網上釋出的引擎是穩定版。選擇哪種就看個人喜好了。但是最新功能你都體驗不到。建議下載git工具然後clone到本地來更新 第二步: 下載後 用cmd終端裡面進入cocos2d-x\tools\project-creator
Ubuntu14.04+eclipse下cocos2d-x3.0正式版環境的搭建
div 新版 文件中 function ngs method ont alt src 環境: ubuntu14.04 adt-bundle-linux-x86_64 android-ndk-r9d-linux-x86_64 cocos2d-x-3.0正式版 apach
Cocos2d-x3.0 從代碼中獲取cocostudio編輯的UI控件
ucid 編輯 top ica sans sce nero val -i 依據名字查找控件 須要包括的頭文件及名字空間: #include "cocostudio/CocoStudio.h"#include "ui/CocosGUI.h"using namespac
Cocos2d-x3.0 載入Cocostudio的UI後,button無法點擊的解決方法
archive nor tar console 大小 接下來 variant set http 近期發現不少朋友都遇到這個問題,用Cocostudio的UI編輯器創建好UI後。在代碼中載入UI,然後給button(Button)加入點擊監聽事件。發現不管怎樣都點擊不了bu
JXLS 2.4.0系列教程(四)——多sheet是怎麽做到的
while director write 教程 == 模板 phy sheet ack 註:本文代碼在第一篇文章基礎上修改而成,請務必先閱讀第一篇文章。 http://www.cnblogs.com/foxlee1024/p/7616987.html 本文也不會過多的講解模
JXLS 2.4.0系列教程(四)——拾遺 如何做頁面小計
進行 line http spa shee shel nes 默認 閱讀 註:閱讀本文前,請先閱讀第四篇文章。 http://www.cnblogs.com/foxlee1024/p/7619845.html 前面寫了第四篇教程,發現有些東西忘了講了,這裏補
JXLS 2.4.0系列教程(五)——更進一步的應用和bug修復
erl dir 問題 create sna 過程 idl es2017 cal 註:本文代碼建立於前面寫的代碼。不過不看也不要緊。 前面的文章把JXLS 2.4.0 的基本使用寫了一遍,現在講講一些更進一步的使用方法。我只寫一些我用到過的方法,更多的高級使用方法請參
【Python3.6+Django2.0+Xadmin2.0系列教程一】環境搭建及項目創建
添加 tran div 先來 ans 好的項目 tty 文件 mac 由於工作需要,接觸了大半年時間的Django+xadmin框架,一直沒空對這塊對進行相關的梳理。最近在同事的慫恿下,就在這分享下筆者的學習及工作經驗吧。 好了,話不多說,下面開始進入正題: 環境
MySQL系列教程二---觸發器
1. 觸發器簡介 觸發器是一個特殊的儲存過程,執行儲存過程需要使用CALL語句來呼叫,但是觸發器的執行不需要用CALL語句呼叫,也不需要手工啟動,只要的當一個預定義的事件發生時,就會被MYSQL自動呼叫。比如當對fruits表進行INSERT,DELETE或UPDATE操作時就會啟用它。
Spring Boot2.0系列教程合集、Spring Cloud系列教程合集、Spring Boot常見錯誤合集、Spring Cloud常見錯誤合集
以下內容結合實際專案和工作經驗整理的Spring Boot和Spring Cloud學習教程和一些常見錯誤,希望能幫助到剛學習到童鞋,學習過程遇到問題評論回覆,第一時間會回覆! Spring Boot2.0系列教程合集 1、Spring Boot2.0系列教程之idea下新
WordPress系列教程(二)----WordPress基本使用和常用設定
接著上文,上篇文章已經把網站搭建好了,這篇主要講WordPress基本使用與常用設定。 一、前後臺頁面 預設前臺頁面是這個樣子: 後臺是這個樣子: 後臺包含以下這些模組: 下面我們就來講講上面的功能。 二、文章 文章欄目下包括,寫文章,分類目
內網***系列教程二(ping和tracertroute命令的使用)
一、ICMP協議ICMP是在RFC792定義的網際網路協議,通常用於返回錯誤資訊和分析路由。為了有效的提好轉發IP資料報和提高交付的機會。ICMP是IP層協議,ICMP的報文包含在IP資料包中,作為其中的資料部分。當其加上了IP資料包的首部(20位元組)便組成了IP資料報傳送出去。他通常不由網路程式直接使用,
OAuth 2.0系列教程
作者:Jakob Jenkov 譯者:林浩 校對:郭蕾 OAuth(開放授權)是一個開放標準,允許使用者讓第三方應用訪問該使用者在某一網站上儲存的私密的資源(如照片,視訊,聯絡人列表),而無需將使用者名稱和密碼提供給第三方應用。 OAuth允許使用者提供一個令牌,而不是使用者名稱和密
OAuth 2.0系列教程(四) 客戶端型別
作者:Jakob Jenkov 譯者:林浩 校對:郭蕾 OAuth 2.0客戶端角色被細分為一系列型別和配置,本節將闡述這些型別和配置。 OAuth 2.0規範定義了兩種客戶端型別: 保密的 公有的 保密的客戶端能夠對外部保持客戶端密碼保密。該客戶端密碼是由授權伺服器分配給客戶
OAuth 2.0系列教程(十一) 客戶端證書請求和響應
作者:Jakob Jenkov 譯者:林浩 校對:郭蕾 客戶端證書授權包含下面的引數: grant_type 必須。必須設定到客戶端證書中。 scope 可選。授權的作用域。 客戶端授權響應: 客戶端授權響應包含下面的引數: { "access_token" :
OAuth 2.0系列教程(三) 角色
作者:Jakob Jenkov 譯者:林浩 校對:郭蕾 OAuth 2.0為使用者和應用定義瞭如下角色: 資源擁有者 資源伺服器 客戶端應用 授權伺服器 這些角色在下圖中表示為: OAuth 2.0規範中的角色定義 資源擁有者是指擁有共享資料的人或應用。比如Facebook或