V7投稿 | CocosCreator开源框架oops-framework 之 音频管理(六)

引擎: CocosCreator 3.8.0

环境: Mac

Gitee: oops-game-kit


引言


oops-framework是由作者dgflash编写,基于CocosCreator 3.x而实现的开源框架。

该框架以插件形式存在,主要目的是为了降低与项目的耦合,并且通过插件内部的命令快速的获取最新版本。

该框架的特性有:

  • 提供游戏常用的功能库,提高开发效率
  • 提供业务模块代码模版,降低程序设计难度
  • 内置模块低耦合,可根据需要自行删减,以适应不同的类型
  • 提供了常用的插件工具,支持Excel表转Json、支持热更新、AB包
  • 增加了ECS、MVVM框架相关,以及常用的屏幕适配,UI管理,多语言等等

为了方便大家更好的学习和使用该框架,作者很贴心的准备了一些学习资料:

dgflash-哔哩视频

dgflash CSDN博客

dgflash-cocos论坛

Gitee dgflash项目仓库

注:oops-framework框架QQ群: 628575875

在CocosCreator官方商店,可以通过 oops 搜索更多的框架项目Demo进行学习。

1_2


音频管理


在CocosCreator中, 音频的播放格式支持:

音频格式 说明
.ogg 有损音频压缩格式, 比.mp3小,音质好
.mp3 有损音频压缩格式,被大量软硬件支持,应用广泛,是目前的主流
.wav 音频格式未经过压缩。但文件占用相对较大
.mp4 是一套用于音频、视频信息的压缩编码标准,对于不同的对象可采用不同的编码算法
.m4a 是仅有音频的 MP4 文件,音频质量是压缩格式中非常高的

在CocosCreator中被管理的音频资源叫做:AudioClip, 播放音频的组件叫做 AudioSource 。该组件提供的主要接口:

  • play() 用于播放音乐
  • playOneShot() 用于播放音效

为保证音频在切换场景的正常播放, CocosCreator提供了常驻根节点, 将音频组件添加到 常驻跟节点 中,并添加音频管理器控制音频组件,以实现对音乐、音效的更好管理。


AudioManger


oops-framework框架中,音频管理通过 AudioManager 来实现的, 在Oops.ts中调用的入口:

export class oops {
  /** 游戏音乐管理 */
  static audio: AudioManager;
}

AudioManager主要通过封装的两个对象管理音频的:

  • AudioMusic 音乐对象
  • AudioEffect 音效对象

对象的继承结构如下:
6_1

类提供的主要参数或接口有:

参数或接口 返回类型 说明
progressMusic number 设置/获取音乐的播放进度
volumeMusic number 设置/获取音乐的音量,范围在[0, 1]之间
switchMusic boolean 设置/获取音乐开关
volumeEffect number 设置/获取音效音量大小,范围在[0, 1]之间
switchEffect boolean 设置/获取音效开关
save() void 本地存储音乐音效的音量、开关等配置数据
playMusic(url, callback?) void 播放音乐,可添加音乐播放完成回调
playerMusicLoop(url) void 循环播放音乐
setMusicComplete(callback) void 设置背景音乐播放完成回调
playEffect(url) void 播放音效
resumeAll() void 恢复当前暂停的音乐与音效播放
pauseAll() void 暂停当前音乐与音效的播放
stopAll() void 停止当前音乐与音效的播放

使用的简单示例:

// 播放音效
oops.audio.playEffect("game/audio/click");
// 循环播放背景音乐
oops.audio.playerMusicLoop("game/audio/background");

初始化

框架的音频管理是同CocosCreator音频管理是类似的,在项目启动时,会将AudioManager添加到常驻根节点中, 并通过监听项目是否进入前台、后台来控制声音的播放或暂停。

// ../oops-plugin-framework/assets/core/Root.ts
// 框架显示层根节点
protected init() {
  // 创建持久根节点
  this.persistRootNode = new Node("PersistRootNode");
  director.addPersistRootNode(this.persistRootNode);

  // 添加音频管理模块
  oops.audio = this.persistRootNode.addComponent(AudioManager);
  // 初始化音乐和音效对象
  oops.audio.load();

  // 游戏显示事件
  game.on(Game.EVENT_SHOW, () => {
    oops.audio.resumeAll();
  });

  // 游戏隐藏事件
  game.on(Game.EVENT_HIDE, () => {
    oops.audio.pauseAll();
  });
}

管理类中的音乐和音效对象,主要通过oops.audio.load()进行初始化,主要逻辑如下:

load() {
  // 获取或添加音乐音效对象
  this.music = this.getComponent(AudioMusic) || this.addComponent(AudioMusic)!;
  this.effect = this.getComponent(AudioEffect) || this.addComponent(AudioEffect)!;
	// 获取本地存储数据,设置音乐音效的音量大小和开关
  let data = oops.storage.get(LOCAL_STORE_KEY);
  if (data) {
    try {
      this.local_data = JSON.parse(data);
      this._volume_music = this.local_data.volume_music;
      this._volume_effect = this.local_data.volume_effect;
      this._switch_music = this.local_data.switch_music;
      this._switch_effect = this.local_data.switch_effect;
    }
    catch (e) {
      this.local_data = {};
      this._volume_music = 1;
      this._volume_effect = 1;
      this._switch_music = true;
      this._switch_effect = true;
    }
		// 根据数据设置声音大小
    if (this.music) this.music.volume = this._volume_music;
    if (this.effect) this.effect.volume = this._volume_effect;
  }
}

初始化主要做的事:

  • 获取或添加音乐、音效的对象
  • 获取本地存储数据,设置音量大小、音量开关、音效大小、音效开关,如果没有则设置默认值

注: 音频管理的初始化,不需要开发者调用,框架已经在 Root.ts 中调用; 本地存储相关下篇博客讲解。


播放

音乐和音效的播放是类似的,主要做的事情:

  1. 通过开关标记检测是否允许加载播放
// 播放音乐
playMusic(url: string, callback?: Function) {
  if (this._switch_music) {
    this.music.load(url, callback);
  }
}

// 播放音效
playEffect(url: string) {
  if (this._switch_effect) {
    this.effect.load(url);
  }
}
  1. 加载指定资源路径播放,以音效为例
// 音乐的播放
public load(url: string, callback?: Function) {
  oops.res.load(url, AudioClip, (err: Error | null, data: AudioClip) => {
    if (err) {
      error(err);
    }
		// 检测音乐是否播放中,如果播放则停止
    if (this.playing) {
      this._isPlay = false;
      this.stop();
    }
    if (this._url) {
      oops.res.release(this._url);
    }
		// 设置要播放的音频
    this.enabled = true;
    this.clip = data;

    // 注:事件定义在这里,是为了在播放前设置初始播放位置数据
    callback && callback();
		// 开始播放
    this.play();

    this._url = url;
  });
}

// 音效的播放
load(url: string, callback?: Function) {
  oops.res.load(url, AudioClip, (err: Error | null, data: AudioClip) => {
    if (err) {
      error(err);
    }

    this.effects.set(url, data);
    this.playOneShot(data, this.volume);
    callback && callback();
  });
}

注: 音乐音效播放的加载,走的是资源管理那一套实现


示例汇总


// 设置音乐的播放
oops.audio.volumeMusic = 0.5;
oops.audio.playerMusicLoop("audio/bgm");
// 设置音效的播放
oops.audio.switchEffect = true;
oops.audio.playEffect("audio/click");
// 设置暂停
oops.audio.pauseAll();
// 保存数据
oops.audio.save();

注:数据不要忘记调用 save() 保存

最后,祝大家学习生活工作愉快!