1. 程式人生 > >Cocos Creator中獲取和載入資源(官方文件摘錄)

Cocos Creator中獲取和載入資源(官方文件摘錄)

Cocos Creator 有一套統一的資源管理機制 ,在本篇教程,我們將介紹

  • 資源的分類
  • 如何在 屬性檢查器 裡設定資源
  • 動態載入 Asset
  • 動態載入 Raw Asset

資源的分類

目前的資源分成兩種,一種叫做 Asset,一種叫做 Raw Asset

Asset

Creator 提供了名為 "Asset" 的資源型別,cc.SpriteFramecc.AnimationClipcc.Prefab 等資源都屬於 Asset。Asset 的載入是統一併且自動化的,相互依賴的 Asset 能夠被自動預載入。

例如,當引擎在載入場景時,會先自動載入場景關聯到的資源,這些資源如果再關聯其它資源,其它也會被先被載入,等載入全部完成後,場景載入才會結束。

因此只要你拿到了一個 Asset 物件,這個物件一定是已經載入結束的,可以直接通過物件上的屬性訪問到資源的所有資料。當你要在引擎中使用這些資源,引擎的 API 接收的都必須是一個載入好的 Asset 物件。

指令碼中可以這樣定義一個 Asset 屬性:

// NewScript.js

cc.Class({
    extends: cc.Component,
    properties: {

        spriteFrame: {
            default: null,
            type: cc.SpriteFrame
        },

    }
});

Raw Asset

為了相容 Cocos2d 的一些既有 API,我們把保留原始資原始檔副檔名資源叫做 "Raw Asset"。圖片(cc.Texture2D),聲音(cc.AudioClip),粒子(cc.ParticleAsset)等資源都是 Raw Asset。Raw Asset 在腳本里由一個 url 字串來表示,當你要在引擎中使用 Raw Asset,只要把 url 傳給引擎的 API,引擎內部會自動載入這個 url 對應的資源。

當你在腳本里宣告一個型別是 cc.Texture2D 的 Raw Asset,一開始可能會想這樣定義:

cc.Class({
    extends: cc.Component,
    properties: {

        textureURL: {
            default
: null, type: cc.Texture2D } } });

這樣寫的問題在於,在程式碼中 textureURL 實際上是一個字串,而不是 cc.Texture2D 的例項。為了不混淆 type 的語義,在 CCClass 中宣告 Raw Asset 的屬性時,要用 url: cc.Texture2D 而不是 type: cc.Texture2D

cc.Class({
    extends: cc.Component,
    properties: {

        textureURL: {
            default: "",
            url: cc.Texture2D
        }

    }
});

如何在屬性檢查器裡設定資源

不論是 Asset 還是 Raw Asset,只要在指令碼中定義好型別,就能直接在 屬性檢查器 很方便地設定資源。假設我們有這樣一個元件:

// NewScript.js

cc.Class({
    extends: cc.Component,
    properties: {

        textureURL: {
            default: "",
            url: cc.Texture2D
        },
        spriteFrame: {
            default: null,
            type: cc.SpriteFrame
        },

    }
});

將它新增到場景後,屬性檢查器 裡是這樣的:

asset-in-properties-null

接下來我們從 資源管理器 裡面分別將一張貼圖和一個 SpriteFrame 拖到 屬性檢查器 的對應屬性中:

asset-in-properties-dnd

結果如下:

asset-in-properties-dnd

這樣就能在腳本里直接拿到設定好的資源:

    onLoad: function () {
        var spriteFrame = this.spriteFrame;
        var textureURL = this.textureURL;

        spriteFrame.setTexture(textureURL);
    }

在 屬性檢查器 裡設定資源雖然很直觀,但資源只能在場景裡預先設好,沒辦法動態切換。如果需要動態切換,你需要看看下面的內容。

動態載入

所有需要通過指令碼動態載入的資源,都必須放置在 resources 資料夾或它的子資料夾下。resources 需要在 assets 資料夾中手工建立,並且必須位於 assets 的根目錄,就像這樣:

asset-in-properties-null

這裡的 image/imageprefabanimfont 都是常見的 Asset,而 image, audio 則是常見的 Raw Asset。

resources 資料夾裡面的資源,可以關聯依賴到資料夾外部的其它資源,同樣也可以被外部場景或資源引用到。專案構建時,除了已在 構建釋出 面板勾選的場景外,resources 資料夾裡面的所有資源,連同它們關聯依賴的 resources 資料夾外部的資源,都會被匯出。所以如果一份資源不需要由指令碼直接動態載入,那麼不用放在 resources 資料夾裡。

動態載入 Asset

Creator 提供了 cc.loader.loadRes 這個 API 來專門載入那些位於 resources 目錄下的 Asset。和 cc.loader.load 不同的是,loadRes 一次只能載入單個 Asset。呼叫時,你只要傳入相對 resources 的路徑即可,並且路徑的結尾處不能包含副檔名。

// 載入 Prefab
cc.loader.loadRes("test assets/prefab", function (err, prefab) {
    var newNode = cc.instantiate(prefab);
    cc.director.getScene().addChild(newNode);
});

// 載入 AnimationClip
var self = this;
cc.loader.loadRes("test assets/anim", function (err, clip) {
    self.node.getComponent(cc.Animation).addClip(clip, "anim");
});

// 載入 SpriteAtlas(圖集),並且獲取其中的一個 SpriteFrame
// 注意 atlas 資原始檔(plist)通常會和一個同名的圖片檔案(png)放在一個目錄下, 所以需要在第二個引數指定資源型別
cc.loader.loadRes("test assets/sheep", cc.SpriteAtlas, function (err, atlas) {
    var frame = atlas.getSpriteFrame('sheep_down_0');
    sprite.spriteFrame = frame;
});

載入獨立的 SpriteFrame

圖片設定為 Sprite 後,將會在 資源管理器 中生成一個對應的 SpriteFrame。但如果直接載入 test assets/image,得到的型別將會是 cc.Texture2D。你必須指定第二個引數為資源的型別,才能載入到圖片生成的 cc.SpriteFrame:

// 載入 SpriteFrame
var self = this;
cc.loader.loadRes("test assets/image", cc.SpriteFrame, function (err, spriteFrame) {
    self.node.getComponent(cc.Sprite).spriteFrame = spriteFrame;
});

如果指定了型別引數,就會在路徑下查詢指定型別的資源。當你在同一個路徑下同時包含了多個重名資源(例如同時包含 player.clip 和 player.psd),或者需要獲取“子資源”(例如獲取 Texture2D 生成的 SpriteFrame),就需要宣告型別。

資源釋放

loadRes 載入進來的單個資源如果需要釋放,可以呼叫 cc.loader.releaseResreleaseRes 只能傳入一個和 loadRes 相同的路徑,不支援型別引數。

cc.loader.releaseRes("test assets/anim");

此外,你也可以使用 cc.loader.releaseAsset 來釋放一個具體的 Asset 例項。

cc.loader.releaseAsset(spriteFrame);

動態載入 Raw Asset

Raw Asset 可以直接使用 url 從遠端伺服器上載入,也可以從專案中動態載入。對遠端載入而言,原先 Cocos2d 的載入方式不變,使用 cc.loader.load 即可。對專案裡的 Raw Asset,載入方式和 Asset 一樣:

// 載入 Texture,不需要字尾名
cc.loader.loadRes("test assets/image", function (err, texture) {
    ...
});

cc.url.raw

Raw Asset 載入成功後,如果需要傳給一些 url 形式的 API,還是需要給出完整路徑才行。你需要用 cc.url.raw進行一次 url 的轉換:

// 原 url 會報錯!檔案找不到
var texture = cc.textureCache.addImage("resources/test assets/image.png");

// 用 cc.url.raw,此時需要宣告 resources 目錄和檔案字尾名
var realUrl = cc.url.raw("resources/test assets/image.png");
var texture = cc.textureCache.addImage(realUrl);

資源批量載入

cc.loader.loadResAll 可以載入相同路徑下的多個資源:

// 載入 test assets 目錄下所有資源
cc.loader.loadResAll("test assets", function (err, assets) {
    // ...
});

// 載入 sheep.plist 圖集中的所有 SpriteFrame
cc.loader.loadResAll("test assets/sheep", cc.SpriteFrame, function (err, assets) {
    // assets 是一個 SpriteFrame 陣列,已經包含了圖集中的所有 SpriteFrame。
    // 而 loadRes('test assets/sheep', cc.SpriteAtlas, function (err, atlas) {...}) 獲得的則是整個 SpriteAtlas 物件。
});