TexturePacker是紋理資源打包工具,支持Cocos2dx的游戲資源打包。
如果用過的同學可以直接看下面的資源的異步加載處理
首先為什么用TexturePacker?
1,節省圖片資源實際大小
2,減少我們游戲中大量資源帶來的內存負荷
3,方便游戲對紋理資源的內存管理
游戲開發到后期,我們或許都會遇到的瓶頸就是需要對游戲包進行“瘦身”和內存優化。那么使用TexturePacker
就能達到我們的目的;
我們以一組技能特效圖片來舉例,進行TexturePacker的圖片打包,然后在程序中使用:
我們對這些文件進行打包成一張大圖.png和cocos2dx-JS中會使用到的.plist文件
打包注意一下幾點:
1,文件格式,選擇cocos2d
2,設置導出文件的plist和png路徑
3,圖片格式,一般使用RGBA8888,但根據平台需求現在也可以導出Pvr格式圖片類型;
使用:1)Textuer Format 選擇Pvr圖片類型 2)Image Format 選擇 PVRCT4 這種類型的;
可大大節省圖片的大小!
4,每張大圖的png尺寸一定不能大於2048*2048!因為目前比較低端的android手機是不支持加載這么大的圖片的!
所以我們的游戲要被大部分機型適配,那就最好不要用太大的圖片包
OK。我們打包完成后將文件拷貝到我們的Gofinght目錄中,繼續我們上一節知識點開始寫我們這節知識點的代碼:
我們需要實現圖片資源的加載!這個是我們的目的。
那么我們就需要書寫一個GameFrameCache.js的類,來單獨處理我們的圖片資源加載;
GameFrameCache.js:

/** * Created by yangshengjiepro on 15/5/11. */
/** * 游戲資源加載處理 */
var GameFrameCache = function () { this.flag = 0; } var LOADINGBARPROALLNUM=0; //異步加載
GameFrameCache.setAllCache = function (obj,objcallback) { //異步加載所有游戲資源
var texCache = cc.textureCache; //遍歷所有的資源
var reslist = res; var allnum = 0; for (var key = 0 in reslist) { Mlog.c("reslist key"+key+"value:"+reslist[key]); allnum++; } LOADINGBARPROALLNUM = allnum; Mlog.c("LOADINGBARPROALLNUM>>",LOADINGBARPROALLNUM); var readnum = 0; for (var key = 0 in reslist) { //開始裝載
texCache.addImageAsync(reslist[key], objcallback, obj); } }; //資源加載
GameFrameCache.setCache = function (plist) { if (jsb.fileUtils.isFileExist(plist) == true) { cc.SpriteFrameCache.getInstance().addSpriteFrames(plist); } else { Mlog.c("No Add File>>",plist); } }; //獲取Frame
GameFrameCache.getCache = function (name) { var frame; frame = cc.SpriteFrameCache.getInstance().getSpriteFrame(name); return frame; }; //移除Plist
GameFrameCache.removeCache = function(plist){ if (jsb.fileUtils.isFileExist(plist) == true) { cc.SpriteFrameCache.getInstance().removeSpriteFramesFromFile(plist); } }
代碼中有三個方法:
GameFrameCache.setCache
GameFrameCache.getCache
GameFrameCache.removeCache
顧名思義就是,添加,獲取,和刪除
添加一張大圖資源方法:
cc.SpriteFrameCache.getInstance().addSpriteFrames(plist);
我們知道SpriteFrameCache可以幫我們預加載plist圖片,並且能大大提高我們游戲對圖片的渲染效率
所以我們盡可能的使用這樣的方式去做圖片的渲染,而且我們能更方便的,在合適的地方去添加,獲取,刪除;
從而達到我們內存資源最佳管理的方式!就不會導致我們因為加載過多圖片導致程序效率緩慢甚至卡死的情況!
那么下面我們來使用SpriteFrameCache這個類,我們需要在我們上一節課中的基類中添加一個方法
setGameFrameCache:function(plistfile){ GameFrameCache.setCache(plistfile); },
很簡單,就是調用我們GameFrameCache的set方法!
在我們MainLayer中添加調用方法,直接:
this.setGameFrameCache("plist文件路徑");
就能調用到我們基類的加載大圖方法!
然后我們來嘗試調用一下我們的大圖紋理使用,我們新建一個PFuns.js動作類來播放我們的技能特效!
PFun.js

/** * Created by yangshengjiepro on 15/5/11. */
var PFuns = function () { this.flag = 0; } //執行某個特效
PFuns.runEFFAttack_SP = function (sp , Url , name , num, speed , loop , delay , zorder , scale , tag , cp) { var sprite = sp; var sp_eff = new cc.Sprite(); var animation = new cc.Animation(); for (var i = 1; i <= num; i++) { var toi=""; if(i<10) { toi = "0"+i; } else { toi = i; } var frameName = Url + "/" + name + toi + ".png"; Mlog.c("frameName>>"+frameName); var frame =GameFrameCache.getCache(frameName); if(frame!=null) { Mlog.c("frameName>ok>>"+frameName); animation.addSpriteFrame(frame); } } var usetime =1 / parseInt(speed); animation.setDelayPerUnit(usetime); animation.setRestoreOriginalFrame(true); animation.setLoops(loop); var action = cc.animate(animation); var actdelay2 = cc.DelayTime.create(delay); if(delay>0) { sp_eff.runAction(cc.Sequence(actdelay2,action,cc.callFunc(PFuns.effremove, sp_eff))); } else { sp_eff.runAction(cc.Sequence(action,cc.callFunc(PFuns.effremove, sp_eff))); } if(cp!=null) { sp_eff.setPosition(cc.p(cp.x,cp.y)); } else { sp_eff.setPosition(cc.p(sprite.getContentSize().width/2,sprite.getContentSize().height/2)); } sp_eff.setScale(scale); sprite.addChild(sp_eff,zorder,tag); }; //移除
PFuns.effremove = function () { this.removeFromParent(); };
我們使用幀動畫的方式來進行技能特效的播放,幀動畫的每幀的Frame獲取方式使用:
var frame =GameFrameCache.getCache(frameName);
OK,我們可以Run起來看一下效果:
我們的技能幀動畫已經非常漂亮的渲染出來了!看起來非常不錯!那么這個小知識點就完了!
好,那么下面我們來講解一下我們所有圖片的異步加載!我們知道在Cocos2dx中提供了textureCache來
幫助我們實現圖片資源文件的管理,和使用。
試想我們是需要使用圖片時臨時加載圖片快,還是先通過一個Loading界面將資源加載完畢后,在從textureCache中
取出來快呢?
答案當然是后者!
那么我們現在來進行LoadIng異步加載的實現方式,GameFrameCache.js類中有
GameFrameCache.setAllCache
這樣一個方法,通過遍歷我們的res目錄中所有的png文件來獲取文件路徑,並且加載所有的圖片;
這里要注意一下:res這個數組中只能填寫png,jpg等圖片文件類型
可以這樣來寫我們的各種文件路徑。
接下來我們就來實現一個進度條的實現來異步加載我們的所有程序資源,在MainLayer中添加兩個方法:
//加載進度條
initloadingbar:function(sp_loading){ //加載Loading條
var sp_loadingtiao = new cc.Sprite(res.UILOADINGBD_png); sp_loadingtiao.attr({ x: sp_loading.getContentSize().width/2,
y: sp_loading.getContentSize().height/2-180,
scale: 1, rotation: 0 }); sp_loading.addChild(sp_loadingtiao,1); var loadingBar = new ccui.LoadingBar(res.UILOADINGBAR_png); loadingBar.x = sp_loading.getContentSize().width/2;
loadingBar.y = sp_loading.getContentSize().height/2-180;
sp_loading.addChild(loadingBar,2,LOADINGBAR_TAG); loadingBar.setPercent(0); },
//資源loadding buffer進度回調
setloadingbar:function(){ var pernum = parseInt(LOADINGBARPRONUM/LOADINGBARPROALLNUM *100);
Mlog.c("pernum >>" +pernum); LOADINGBARPRONUM++; var loadingBar = this.getChildByTag(LOADINGBAR_TAG); if(loadingBar!=null) { loadingBar.setPercent(pernum); } //進度條加載完畢進行跳轉
if(pernum==100) { //加載完畢
Mlog.c("異步加載資源完畢"); PFuns.runEFFAttack_SP(this , "skill_dianjin" , "000" , 13, 6 , 3 ,1 , 11111 , 1 ,1000 , null); } },
setloadingbar這個方法是我們的回調;在GameFrameCache會使用addImageAsync方法來進行資源加載成功的回調!
並且獲取兩個值:
var LOADINGBARPRONUM = 1; var LOADINGBARPROALLNUM=0;
和LOADINGBARPROALLNUM來進行進度條的計算和更新;
最后進度條的比例為100時,那么播放我們的技能動畫:
texCache.addImageAsync(reslist[key], objcallback, obj);
在構造函數尾部,直接加上調用方法:
//加載進度條調用
this.initloadingbar(this); //異步加載所有資源調用
GameFrameCache.setAllCache(this,this.setloadingbar);
這樣就實現了我們整個項目的圖片資源的異步加載
我們可以跑起來看看效果!
好了,本章知識點在我們游戲開發中是非常的常用,也是非常重要的!所以我覺得會對大家一定有幫助!
本節知識點源碼:
自己創建新工程,解壓下載的文件,將所有文件拷貝到你新工程的目錄下全部覆蓋既可以運行!