cocoscreator音频管理类

在游戏制作中都需要使用音乐和音效,但因为分散开使用并不规范,而且很占性能,所以封装好以下类,可以直接使用

使用方法:在游戏初始化的场景上添加一个节点,注意要在scene下,和Canvas并列,修改为AudioMgr,然后在游戏初始化时init改脚本,并按注释添加音乐

import { _decorator, Node, AudioClip, AudioSource, find, assetManager, director, resources, Button } from "cc";

import { Dictionary } from "../Common/Dictionary";

const { ccclass, property } = _decorator;

 

/**最多有几个音效播放器*/

const MAX_SOUNDS: number = 8

 

/**

 * 音效管理器

 */

@ccclass('AudioManager')

export class AudioManager {

 

    public static _instance: AudioManager = null;

    static get ins() {

        if (this._instance) {

            return this._instance;

        }

        this._instance = new AudioManager();

        return this._instance;

    }

 

    /**音效的常驻节点*/

    public _persistRootNode: Node = null;

    //bgm音效全局唯一一个

    public _music: AudioSource = null

    //sound音效可以有多个

    public _sounds: AudioSource[] = null

    /**bgm静音 0没静音 1静音*/

    public _music_muted: number = 0

    /**sound静音 0没静音 1静音*/

    public _sound_muted: number = 0

    /**bgm音量*/

    public _music_volume: number = 1

    /**sound音量*/

    public _sound_volume: number = 1

    /**当前播放的音效索引用以控制使用不同的AudioSource*/

    public _now_soundid: number = 0

    /**当前播放的bgm音效名字*/

    public _cur_music_name: string = ""

    //存储所有的音效片段

    public music_clips: Dictionary<string, AudioClip>

    // load(){

    //     AudioManager._instance = this;

    // }

    public init() {

       

        if (this._persistRootNode) return; //避免切换场景初始化报错

        this._persistRootNode = find("AudioMgr")

        director.addPersistRootNode(this._persistRootNode)

        this._sounds = []

        this.music_clips = new Dictionary<string, AudioClip>()

        /**

         * 读取本地存储的数据

         *

         */

        this._music = this._persistRootNode.addComponent(AudioSource)

        //获取bgm的音量

        this._music.volume = this._music_volume

        //获取bgm是否存储静音

        this._music.volume = this._music_muted == 1 ? 0 : this._music_volume

        //获取sounds列表

        for (let i = 0; i < MAX_SOUNDS; i++) {

            this._sounds[i] = this._persistRootNode.addComponent(AudioSource)

            this._sounds[i].volume = this._sound_volume

            this._sounds[i].volume = this._sound_muted == 1 ? 0 : this._sound_volume

        }

   

    }

 

    /**

     * @param audioName 音效名字

     * @param isLoop 是否循环播放

     * @protected 播放音效

     */

    playMusic(audioName: string, isLoop: boolean = true) {

        if (this._cur_music_name == audioName) {

            return

        }

        let call = (clip) => {

            this._music.clip = null

            this._music.clip = clip

            this._music.loop = isLoop

            this._music.play()

            if (!this.music_clips.containsKey(audioName)) {

                this.music_clips.add(audioName, clip)

            }

        }

        //查找到对应音频则直接获取

        if (this.music_clips.containsKey(audioName)) {

            call(this.music_clips.getValue(audioName))

        } else {

            //查找不到则加载资源

         //   let bundleName = "resources"

            let path = "audios/" + audioName

            // assetManager.loadBundle(bundleName,(err, bundle) => {

            //     bundle.load(path,AudioClip,(err: any, clip: AudioClip)=>{

            //         if (err) {

            //             console.error("loadAudioClip" + err);

            //         }else{

            //             call(clip)

            //         }

            //     });

               

            // })

            resources.load(path,AudioClip,(err: any, clip: AudioClip)=>{

                if (err) {

                    console.error("loadAudioClip" + err);

                }else{

                    call(clip)

                }

            });

        }

    }

 

    /**

     * @param audioName 音效名字

     * @param isLoop 是否循环播放

     * @protected 播放音效

     */

    playSound(audioName: string, isLoop: boolean = false) {

        let call = (clip) => {

            this._sounds[this._now_soundid].clip = null

            this._sounds[this._now_soundid].clip = clip

            this._sounds[this._now_soundid].loop = isLoop

            this._sounds[this._now_soundid].play()

            if (!this.music_clips.containsKey(audioName)) {

                this.music_clips.add(audioName, clip)

            }

            this._now_soundid = this._now_soundid + 1 >= this._sounds.length ? 0 : this._now_soundid + 1

        }

        if (this.music_clips.containsKey(audioName)) {

            call(this.music_clips.getValue(audioName))

        } else {

          //  let bundleName = "resources"

            let path ="audios/" + audioName

            // assetManager.loadBundle(bundleName,(err, bundle) => {

            //     bundle.load(path,AudioClip,(err: any, clip: any)=>{

            //         if (err) {

            //             console.error("loadAudioClip" + err);

            //         }else{

            //             call(clip)

            //         }

            //     });            

            // })

            resources.load(path,AudioClip,(err: any, clip: AudioClip)=>{

                if (err) {

                    console.error("loadAudioClip" + err);

                }else{

                    call(clip)

                }

            });

        }

    }

 

    /**

     * 停止播放bgm

     */

    stopMusic() {

        this._music.stop()

        this._music.clip = null

    }

 

    /**

     * 停止播放所有的sound

     */

    stopAllSound() {

        for (let i = 0; i < this._sounds.length; i++) {

            this._sounds[i].stop()

            this._sounds[i].clip = null

        }

        this._now_soundid = 0

    }

 

    /**

     *

     * @param mute 是否静音music

     */

    setMusicMute(mute: boolean) {

        if (mute == (this._music_muted == 1)) {

            return

        }

        this._music_muted = mute ? 1 : 0

        this._music.volume = mute ? this._music_volume : 0

        //存储music静音 this._music_muted

    }

 

    /**

     *

     * @param mute 是否静音sound

     */

    setSoundMute(mute: boolean) {

        if (mute == (this._sound_muted == 1)) {

            return

        }

        this._sound_muted = mute ? 1 : 0

        for (let i = 0; i < this._sounds.length; i++) {

            this._sounds[i].volume = mute ? this._sound_volume : 0

        }

        //存储sound静音 this._sound_muted

    }

 

    /**

     *

     * @param value 设置音乐声音大小

     */

    setMusicVolume(value: number) {

        this._music.volume = value

        this._music_volume = value

        //存储music音量大小 this._music_volume

    }

 

    /**

     *

     * @param value 设置sound声音大小

     */

    setSoundVolume(value: number) {

        this._sound_volume = value

        for (let i = 0; i < this._sounds.length; i++) {

            this._sounds[i].volume = value

        }

        //存储sound音量大小 this._sound_volume

    }

 

    /**

     *

     * @returns 返回bgm静音状态

     */

    getMusicMute() {

        return this._music_muted

    }

 

    /**

     *

     * @returns 返回sound音效静音状态

     */

    getSoundMute() {

        return this._sound_muted

    }

 

    /**

     *

     * @returns 返回bgm声音大小

     */

    getMusicVolume() {

        return this._music_volume

    }

 

    /**

     *

     * @returns 返回sound音效声音大小

     */

    getSoundVolume() {

        return this._sound_volume

    }

 

/**

 * 自定义字典类

 */

export class Dictionary<K, V>

{

    keys: K[] = [

    ];

    values: V[] = [

    ];

 

    /**

     * 获取所有值

     */

    public getList() {

        let self = this;

        return self.values;

    }

    /**

     * 根据键得到值

     */

    public getValue(key: K): V {

        let self = this;

        let index = self.keys.indexOf(key);

        if (index != -1)

            return self.values[index];

        return null!;

    }

 

    /**根据值得到键 */

    public getKey(value: V): K {

        let self = this;

        let index = self.values.indexOf(value);

        if (index != -1)

            return self.keys[index];

        return null!;

    }

 

    /**改变值 */

    public changeValue(key: K, changeValue: V): void {

        let self = this;

        let index = self.keys.indexOf(key);

        if (index != -1)

            self.values[index] = changeValue;

    }

    /**改变键 */

    public changeKey(key: K, changeKey: K): void {

        let self = this;

        let index = self.keys.indexOf(key);

        if (index != -1)

            self.keys[index] = changeKey;

    }

    /** 根据键刷新值 */

    public updateValue(key: K, value: V) {

        let self = this;

        let index = self.keys.indexOf(key);

        if (index != -1)

            self.values[index] = value;

        else

            self.add(key, value);

    }

 

    /**

     * 添加键值

     */

    public add(key: K, value: V, name?: string): void {

        let self = this;

        if (self.keys.indexOf(key) != -1) {

            // console.log("same key in dic", name);

            return;

        }

        self.keys.push(key);

        self.values.push(value);

    }

 

    /**

     * 根据键添加值

     * type: 0:values是数组往里面添加值

     *       1:values是number,用来统计数量的

     */

    public addValue(key: K, value: any, type: number = 0) {

        let self = this;

        let index = self.keys.indexOf(key);

        if (index < 0) {

            self.keys.push(key);

            self.addValue(key, value, type);

        } else {

            let values = self.getValue(key) as any;

            if(type == 0) {

                if(values) {

                    values.push(value);

                } else {

                    values = [value];

                }

            } else {

                if(values) {

                    values += value;

                } else {

                    values = 1;

                }

            }

            self.changeValue(key, values);

        }

    }

 

    /**

     * 清空

     */

    public clear(): void {

        let self = this;

        self.keys.length = 0;

        self.values.length = 0;

    }

 

    /**

     * 根据键移除对象

     */

    public removeKey(key: K): void {

        let self = this;

        let index = self.keys.indexOf(key);

        if (index < 0) return;

        self.keys.splice(index, 1);

        self.values.splice(index, 1);

    }

 

    /**

     * 根据值移除对象

     */

    public removeValue(value: V): void {

        let self = this;

        let index = self.values.indexOf(value);

        self.keys.splice(index, 1);

        self.values.splice(index, 1);

    }

 

    /**

     * 根据键检测是否存在对象

     */

    public containsKey(key: K) {

        if (this.keys.indexOf(key, 0) == -1) {

            return false;

        }

        return true;

    }

 

    /**

     * 根据值检测是否存在对象

     */

    public containsValue(value: V) {

        if (this.values.indexOf(value, 0) == -1) {

            return false;

        }

        return true;

    }

 

    /**突出最后一个对象 */

    public pop(): void {

        let self = this;

        self.keys.pop();

        self.values.pop();

    }

 

    /**根据索引交换位置 */

    public swap(num1: number, num2: number): void {

        let self = this;

        if (self.keys.length <= num1 ||

            self.keys.length <= num2)

            return;

        //交换

        let tmpK = self.keys[num1];

        self.keys[num1] = self.keys[num2];

        self.keys[num2] = tmpK;

        let tmpV = self.values[num1];

        self.values[num1] = self.values[num2];

        self.values[num2] = tmpV;

    }

    /** 交换两个索引对应的值*/

    public cutValue(num1: K, num2: K): void {

        let self = this;

        if (self.keys.indexOf(num1) < -1 ||

            self.keys.indexOf(num1) < -2)

            return;

        let tmpV = self.getValue(num1);

        self.changeValue(num1, self.getValue(num2));

        self.changeValue(num2, tmpV);

    }

 

    /**长度 */

    public get size(): number {

        return this.keys.length;

    }

}

 

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Cocos Creator使用JavaScript语言,其内存管理由JavaScript引擎自动处理。开发者需要注意的是,避免出现内存泄漏的情况,比如及时释放不再需要的对象、避免循环引用等。可以使用Chrome浏览器的开发者工具进行内存分析和调试。 ### 回答2: Cocos Creator是一个基于Cocos2d-x引擎的游戏开发工具,用于创建高性能的跨平台游戏。在Cocos Creator中,内存管理是非常重要的一部分,它直接影响游戏的性能和稳定性。 Cocos Creator提供了一套内存管理机制,用于有效地管理游戏资源和对象的内存使用情况。这套机制主要有以下几个方面: 1. 引用计数:Cocos Creator使用引用计数方式来管理对象的内存。每当一个对象被创建或者被其他对象引用时,引用计数会加1;当对象不再被引用时,引用计数会减1。当引用计数为0时,对象会被自动释放。 2. 缓存池:Cocos Creator提供了对象的缓存池机制,用于重用对象,减少对象的创建和销毁带来的内存开销。通过将不再使用的对象放入缓存池中,可以在需要时快速获取该对象,提高了游戏的性能。 3. 资源管理器:Cocos Creator内置了资源管理器,用于管理游戏中的图片、音频、动画等资源。通过资源管理器,可以方便地加载和释放游戏资源,避免过多的内存占用。 4. 内存优化:Cocos Creator提供了一些内存优化的方式,以减少游戏内存的使用。例如,在使用图片资源时,可以合理地选择压缩格式和图片尺寸,以减小图片的内存占用;同时,可以对不再需要的资源进行及时的释放,以避免内存的浪费。 总结起来,Cocos Creator内存管理主要依靠引用计数、缓存池和资源管理器等机制来进行。通过合理地使用这些机制,可以有效地管理游戏资源和对象的内存使用,提升游戏的性能和稳定性。 ### 回答3: Cocos Creator是一款流行的游戏开发引擎,也为内存管理提供了一些方便的工具和功能。在Cocos Creator中,内存管理非常重要,可以提高游戏的性能和稳定性。 首先,Cocos Creator内置了垃圾回收机制,帮助开发者自动释放不再使用的内存。当游戏对象不再被引用或引用被清除时,垃圾回收机制会自动回收这些对象所占用的内存资源,有效避免了内存泄露的问题。 另外,Cocos Creator还提供了对象池的功能。对象池允许开发者重复使用之前创建的游戏对象,而不是频繁地创建和销毁对象。通过对象池,可以减少内存分配和释放的开销,提高游戏的性能。 此外,开发者还可以手动管理内存,通过一些方法来优化内存使用。例如,释放不再需要的资源、合并多个小的纹理为一个大的纹理、减少不必要的数据拷贝等等。通过这些优化措施,可以减少内存占用,提高游戏的性能。 总的来说,Cocos Creator提供了一系列的内存管理工具和功能,帮助开发者有效地管理游戏的内存。通过合理使用这些工具和优化内存使用,可以提高游戏的性能和稳定性,同时减少内存泄露和卡顿的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值