Skip to content

音频播放管理器示例

由于 Cocos Creator 3.x 移除了 v2.x cc.audioEngine 系列的 API,统一使用 AudioSource 控制音频播放。

但在实际项目开发中,我们仍然需要一个方便随时调用的音频播放管理器,可参考或直接使用以下代码:

typescript
//AudioMgr.ts
import { Node, AudioSource, AudioClip, resources, director } from "cc";
/**
 * @en
 * this is a sington class for audio play, can be easily called from anywhere in you project.
 * @zh
 * 这是一个用于播放音频的单件类,可以很方便地在项目的任何地方调用。
 */
export class AudioMgr {
  private static _inst: AudioMgr;
  public static get inst(): AudioMgr {
    if (this._inst == null) {
      this._inst = new AudioMgr();
    }
    return this._inst;
  }

  private _audioSource: AudioSource;
  constructor() {
    //@en create a node as audioMgr
    //@zh 创建一个节点作为 audioMgr
    let audioMgr = new Node();
    audioMgr.name = "__audioMgr__";

    //@en add to the scene.
    //@zh 添加节点到场景
    director.getScene().addChild(audioMgr);

    //@en make it as a persistent node, so it won't be destroied when scene change.
    //@zh 标记为常驻节点,这样场景切换的时候就不会被销毁了
    director.addPersistRootNode(audioMgr);

    //@en add AudioSource componrnt to play audios.
    //@zh 添加 AudioSource 组件,用于播放音频。
    this._audioSource = audioMgr.addComponent(AudioSource);
  }

  public get audioSource() {
    return this._audioSource;
  }

  /**
   * @en
   * play short audio, such as strikes,explosions
   * @zh
   * 播放短音频,比如 打击音效,爆炸音效等
   * @param sound clip or url for the audio
   * @param volume
   */
  playOneShot(sound: AudioClip | string, volume: number = 1.0) {
    if (sound instanceof AudioClip) {
      this._audioSource.playOneShot(sound, volume);
    } else {
      resources.load(sound, (err, clip: AudioClip) => {
        if (err) {
          console.log(err);
        } else {
          this._audioSource.playOneShot(clip, volume);
        }
      });
    }
  }

  /**
   * @en
   * play long audio, such as the bg music
   * @zh
   * 播放长音频,比如 背景音乐
   * @param sound clip or url for the sound
   * @param volume
   */
  play(sound: AudioClip | string, volume: number = 1.0) {
    if (sound instanceof AudioClip) {
      this._audioSource.stop();
      this._audioSource.clip = sound;
      this._audioSource.play();
      this.audioSource.volume = volume;
    } else {
      resources.load(sound, (err, clip: AudioClip) => {
        if (err) {
          console.log(err);
        } else {
          this._audioSource.stop();
          this._audioSource.clip = clip;
          this._audioSource.play();
          this.audioSource.volume = volume;
        }
      });
    }
  }

  /**
   * stop the audio play
   */
  stop() {
    this._audioSource.stop();
  }

  /**
   * pause the audio play
   */
  pause() {
    this._audioSource.pause();
  }

  /**
   * resume the audio play
   */
  resume() {
    this._audioSource.play();
  }
}