当前位置: 首页 > news >正文

Cocos Creator资源自动释放之2.x和3.x版本的使用及区别

2.x

封装:

// 2.x
import { ccclass, menu, disallowMultiple } from 'cc';

// 定义 AutoReleaseAssets 类
@ccclass
@menu('资源管理/AutoReleaseAssets/自动释放资源')
@disallowMultiple
export class AutoReleaseAssets extends cc.Component {
    // 存储动态资源的数组
    private dynamicsAssets: cc.Asset[] = [];

    /**
     * 添加单个资源到自动释放列表
     * @param _asset 要添加的资源
     */
    public addAutoReleaseAsset(_asset: cc.Asset): void {
        // 检查资源是否有效
        if (cc.isValid(_asset)) {
            // 增加资源引用计数
            _asset.addRef();
            // 将资源添加到动态资源数组
            this.dynamicsAssets.push(_asset);
        }
    }

    /**
     * 添加多个资源到自动释放列表
     * @param _assets 要添加的资源数组
     */
    public addAutoReleaseAssets(_assets: cc.Asset[]): void {
        // 遍历资源数组
        for (const _asset of _assets) {
            // 调用添加单个资源的方法
            this.addAutoReleaseAsset(_asset);
        }
    }

    /**
     * 组件销毁时自动释放资源
     */
    onDestroy(): void {
        // 遍历动态资源数组
        for (const asset of this.dynamicsAssets) {
            // 检查资源是否有效
            if (cc.isValid(asset)) {
                // 减少资源引用计数
                asset.decRef();
            }
        }
        // 清空动态资源数组
        this.dynamicsAssets = [];
    }
}

// 为 cc.Component 原型添加扩展方法
declare global {
    interface CCComponent {
        addAutoReleaseAsset(_asset: cc.Asset): void;
        addAutoReleaseAssets(_assets: cc.Asset[]): void;
    }
}

cc.Component.prototype.addAutoReleaseAsset = function (_asset: cc.Asset): void {
    // 获取节点上的 AutoReleaseAssets 组件
    let autoReleaseComponent = this.node.getComponent(AutoReleaseAssets);
    // 如果组件无效,则添加该组件
    if (!cc.isValid(autoReleaseComponent)) {
        autoReleaseComponent = this.node.addComponent(AutoReleaseAssets);
    }
    // 调用组件的添加单个资源方法
    autoReleaseComponent.addAutoReleaseAsset(_asset);
};

cc.Component.prototype.addAutoReleaseAssets = function (_assets: cc.Asset[]): void {
    // 获取节点上的 AutoReleaseAssets 组件
    let autoReleaseComponent = this.node.getComponent(AutoReleaseAssets);
    // 如果组件无效,则添加该组件
    if (!cc.isValid(autoReleaseComponent)) {
        autoReleaseComponent = this.node.addComponent(AutoReleaseAssets);
    }
    // 调用组件的添加多个资源方法
    autoReleaseComponent.addAutoReleaseAssets(_assets);
};

使用:

import { _decorator, Component } from 'cc';
import { AutoReleaseAssets } from './path/to/AutoReleaseAssets'; // 根据实际路径调整

const { ccclass, property } = _decorator;

@ccclass('MyComponent')
export class MyComponent extends Component {
    start() {
        const resourcePaths = ['textures/myTexture1', 'textures/myTexture2'];
        const assets: cc.Asset[] = [];

        // 加载单个资源
        cc.resources.load('textures/myTexture', cc.Texture2D, (err, texture: cc.Texture2D) => {
            if (err) {
                console.error('资源加载失败:', err);
                return;
            }
            // 添加单个资源到自动释放列表
            this.addAutoReleaseAsset(texture);
            // 使用资源,例如设置精灵的纹理
            const sprite = this.node.getComponent(cc.Sprite);
            if (sprite) {
                sprite.spriteFrame = new cc.SpriteFrame(texture);
            }
        });

        // 批量加载资源
        cc.resources.loadDir('textures', cc.Texture2D, (err, textures: cc.Texture2D[]) => {
            if (err) {
                console.error('资源加载失败:', err);
                return;
            }
            // 将加载的资源添加到数组中
            assets.push(...textures);
            // 添加多个资源到自动释放列表
            this.addAutoReleaseAssets(assets);
            // 使用资源,例如设置多个精灵的纹理
            const sprites = this.node.getComponentsInChildren(cc.Sprite);
            for (let i = 0; i < sprites.length && i < textures.length; i++) {
                sprites[i].spriteFrame = new cc.SpriteFrame(textures[i]);
            }
        });
    }
}

3.x

封装

// AutoReleaseAssets.ts
import { _decorator, Component, Asset } from 'cc';
const { ccclass, menu, disallowMultiple } = _decorator;

@ccclass
@menu('资源管理/AutoReleaseAssets/自动释放资源')
@disallowMultiple
export class AutoReleaseAssets extends Component {
    private dynamicsAssets: Asset[] = [];

    /**
     * 添加单个资源到自动释放列表
     * @param _asset 要添加的资源
     */
    public addAutoReleaseAsset(_asset: Asset): void {
        if (_asset) {
            _asset.addRef();
            this.dynamicsAssets.push(_asset);
        }
    }

    /**
     * 添加多个资源到自动释放列表
     * @param _assets 要添加的资源数组
     */
    public addAutoReleaseAssets(_assets: Asset[]): void {
        for (const _asset of _assets) {
            this.addAutoReleaseAsset(_asset);
        }
    }

    /**
     * 组件销毁时自动释放资源
     */
    onDestroy(): void {
        for (const asset of this.dynamicsAssets) {
            if (asset) {
                asset.decRef();
            }
        }
        this.dynamicsAssets = [];
    }
}

// 为 Component 原型添加扩展方法
declare global {
    interface Component {
        addAutoReleaseAsset(_asset: Asset): void;
        addAutoReleaseAssets(_assets: Asset[]): void;
    }
}

Component.prototype.addAutoReleaseAsset = function (_asset: Asset): void {
    let autoReleaseComponent = this.node.getComponent(AutoReleaseAssets);
    if (!autoReleaseComponent) {
        autoReleaseComponent = this.node.addComponent(AutoReleaseAssets);
    }
    autoReleaseComponent.addAutoReleaseAsset(_asset);
};

Component.prototype.addAutoReleaseAssets = function (_assets: Asset[]): void {
    let autoReleaseComponent = this.node.getComponent(AutoReleaseAssets);
    if (!autoReleaseComponent) {
        autoReleaseComponent = this.node.addComponent(AutoReleaseAssets);
    }
    autoReleaseComponent.addAutoReleaseAssets(_assets);
};

使用

// MyComponent.ts
import { _decorator, Component, Sprite, SpriteFrame, resources, Texture2D } from 'cc';
import { AutoReleaseAssets } from './AutoReleaseAssets'; // 根据实际路径调整

const { ccclass } = _decorator;

@ccclass('MyComponent')
export class MyComponent extends Component {
    start() {
        // 加载单个资源
        resources.load('textures/myTexture', Texture2D, (err, texture: Texture2D) => {
            if (err) {
                console.error('资源加载失败:', err);
                return;
            }
            // 添加单个资源到自动释放列表
            this.addAutoReleaseAsset(texture);
            // 使用资源,例如设置精灵的纹理
            const sprite = this.node.getComponent(Sprite);
            if (sprite) {
                sprite.spriteFrame = new SpriteFrame(texture);
            }
        });

        // 加载多个资源
        const resourcePaths = ['textures/myTexture1', 'textures/myTexture2'];
        const assets: Texture2D[] = [];
        resources.loadDir('textures', Texture2D, (err, textures: Texture2D[]) => {
            if (err) {
                console.error('资源加载失败:', err);
                return;
            }
            // 将加载的资源添加到数组中
            assets.push(...textures);
            // 添加多个资源到自动释放列表
            this.addAutoReleaseAssets(assets);
            // 使用资源,例如设置多个精灵的纹理
            const sprites = this.node.getComponentsInChildren(Sprite);
            for (let i = 0; i < sprites.length && i < textures.length; i++) {
                sprites[i].spriteFrame = new SpriteFrame(textures[i]);
            }
        });
    }
}

说明

命名空间和导入方式:在 Cocos Creator 3.x 系列中,很多类和模块的导入方式有所不同,使用

import { ... } from 'cc' 来导入所需的类。

API 调整:cc.resources 现在变为 resources,可以直接从 cc 命名空间中导入使用。

cc.isValid 调整:在这个场景中,直接使用简单的真值判断(如 if (_asset))来检查资源是否有效,简化了代码。

相关文章:

  • 数值分析与科学计算导引——误差与算法举例
  • 深入解析Qt事件循环
  • Java中的Spliterator与并行计算
  • MongoDB数据导出工具mongoexport
  • LeetCode刷题---哈希表---387
  • 【机器学习】线性回归 多元线性回归
  • 【嵌入式Linux应用开发基础】fork()函数
  • vue事件修饰符的实现
  • 作用域链精讲
  • Ubuntu 下 nginx-1.24.0 源码分析 - ngx_save_argv函数
  • docker下部署kong+consul+konga 报错问题处理
  • 蓝桥杯班级活动
  • Springboot集成Spring AI和Milvus,验证RAG构建过程
  • 【Java线程中断】线程中断后为什么要调用interrupt()?
  • 超低失真、超高清晰度的远心工业镜头
  • 20250217-POMO笔记
  • STM32 CubeMx配置串口收发使用DMA并调用Idle模式(二)
  • 详解CountDownlatch
  • MaxKB + Ollama + DeepSeek本地部署
  • 输入网址到网页显示,发生了什么?
  • 上海网站建设优/快速优化网站排名的方法
  • 建设免费网站模板/写手接单平台
  • 静态页面网站站标代码写进到静态页面了 怎么不显示呢?/灰色行业推广平台
  • 塘沽网站建设/软件拉新推广平台
  • 标识设计公司网站/识别关键词软件
  • 淘宝客网站建设视频教程/最大的推广平台