在游戏制作中都需要使用音乐和音效,但因为分散开使用并不规范,而且很占性能,所以封装好以下类,可以直接使用
使用方法:在游戏初始化的场景上添加一个节点,注意要在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;
}
}