235 lines
6.4 KiB
TypeScript
235 lines
6.4 KiB
TypeScript
|
import { _decorator, Node, AudioClip, AudioSource, director } from "cc";
|
||
|
import { StorageManager } from "./storageManager";
|
||
|
import { ResourceUtil } from "./resourceUtil";
|
||
|
import { Lodash } from './lodash';
|
||
|
const { ccclass, property } = _decorator;
|
||
|
|
||
|
interface AudioData {
|
||
|
source: AudioSource;
|
||
|
isMusic: boolean;
|
||
|
}
|
||
|
|
||
|
interface AudioDataMap {
|
||
|
[name: string]: AudioData;
|
||
|
}
|
||
|
|
||
|
@ccclass("AudioManager")
|
||
|
export class AudioManager {
|
||
|
private _persistRootNode: Node = null!;
|
||
|
private _audioSources: AudioSource[] = [];
|
||
|
static _instance: AudioManager;
|
||
|
dictWeaponSoundIndex: any = {};
|
||
|
|
||
|
static get instance() {
|
||
|
if (this._instance) {
|
||
|
return this._instance;
|
||
|
}
|
||
|
|
||
|
this._instance = new AudioManager();
|
||
|
return this._instance;
|
||
|
}
|
||
|
|
||
|
musicVolume: number = 0.8;
|
||
|
soundVolume: number = 1;
|
||
|
audios: AudioDataMap = {};
|
||
|
arrSound: AudioData[] = [];
|
||
|
|
||
|
init() {
|
||
|
if (this._persistRootNode) return; //避免切换场景初始化报错
|
||
|
this._persistRootNode = new Node('audio');
|
||
|
this.openAudio();
|
||
|
director.getScene()!.addChild(this._persistRootNode);
|
||
|
director.addPersistRootNode(this._persistRootNode)
|
||
|
|
||
|
this.musicVolume = this.getAudioSetting(true) ? 0.8 : 0;
|
||
|
this.soundVolume = this.getAudioSetting(false) ? 1 : 0;
|
||
|
}
|
||
|
|
||
|
private _getAudioSource(clip: AudioClip) {
|
||
|
let result: AudioSource | undefined;
|
||
|
for (let i = 0; i < this._audioSources.length; ++i) {
|
||
|
let audioSource = this._audioSources[i];
|
||
|
if (!audioSource.playing) {
|
||
|
result = audioSource;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (!result) {
|
||
|
result = this._persistRootNode.addComponent(AudioSource);
|
||
|
result.playOnAwake = false;
|
||
|
this._audioSources.push(result);
|
||
|
}
|
||
|
result.node.off(AudioSource.EventType.ENDED);
|
||
|
result.clip = clip;
|
||
|
result.currentTime = 0;
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
getAudioSetting(isMusic: boolean) {
|
||
|
let state;
|
||
|
if (isMusic) {
|
||
|
state = StorageManager.instance.getGlobalData('music');
|
||
|
} else {
|
||
|
state = StorageManager.instance.getGlobalData('sound');
|
||
|
}
|
||
|
|
||
|
return !state || state === 'true' ? true : false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 播放音乐
|
||
|
* @param {String} name 音乐名称可通过Constant.AUDIO_MUSIC 获取
|
||
|
* @param {Boolean} loop 是否循环播放
|
||
|
*/
|
||
|
playMusic(name: string, loop: boolean) {
|
||
|
let path = 'audio/music/' + name;
|
||
|
ResourceUtil.loadRes(path, AudioClip, (err: any, clip: any) => {
|
||
|
let source = this._getAudioSource(clip);
|
||
|
let tmp: AudioData = {
|
||
|
source,
|
||
|
isMusic: true,
|
||
|
};
|
||
|
this.audios[name] = tmp;
|
||
|
source.volume = this.musicVolume;
|
||
|
source.loop = loop;
|
||
|
source.play();
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 播放音效
|
||
|
* @param {String} name 音效名称可通过Constant.AUDIO_SOUND 获取
|
||
|
* @param {Boolean} loop 是否循环播放
|
||
|
*/
|
||
|
playSound(name: string, loop: boolean = false) {
|
||
|
if (!this.soundVolume) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//音效一般是多个的,不会只有一个
|
||
|
let path = 'audio/sound/';
|
||
|
ResourceUtil.loadRes(path + name, AudioClip, (err: any, clip: any) => {
|
||
|
let source = this._getAudioSource(clip);
|
||
|
let tmp: AudioData = {
|
||
|
source,
|
||
|
isMusic: false,
|
||
|
};
|
||
|
this.arrSound.push(tmp);
|
||
|
|
||
|
if (loop) {
|
||
|
this.audios[name] = tmp;
|
||
|
}
|
||
|
|
||
|
source.volume = this.soundVolume;
|
||
|
source.loop = loop;
|
||
|
source.play();
|
||
|
|
||
|
source.node.on(AudioSource.EventType.ENDED, () => {
|
||
|
Lodash.remove(this.arrSound, (obj: AudioData) => {
|
||
|
return obj.source === tmp.source;
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
|
||
|
stop(name: string) {
|
||
|
if (this.audios.hasOwnProperty(name)) {
|
||
|
let audio = this.audios[name];
|
||
|
audio.source.stop();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
stopAll() {
|
||
|
for (const i in this.audios) {
|
||
|
if (this.audios.hasOwnProperty(i)) {
|
||
|
let audio = this.audios[i];
|
||
|
audio.source.stop();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
getMusicVolume() {
|
||
|
return this.musicVolume;
|
||
|
}
|
||
|
|
||
|
setMusic(flag: number) {
|
||
|
this.musicVolume = flag;
|
||
|
for (let item in this.audios) {
|
||
|
if (this.audios.hasOwnProperty(item) && this.audios[item].isMusic) {
|
||
|
let audio = this.audios[item];
|
||
|
audio.source.volume = this.musicVolume;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//看广告时先将音乐暂停
|
||
|
pauseAll() {
|
||
|
for (let item in this.audios) {
|
||
|
if (this.audios.hasOwnProperty(item)) {
|
||
|
let audio = this.audios[item];
|
||
|
audio.source.pause();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
resumeAll() {
|
||
|
for (let item in this.audios) {
|
||
|
if (this.audios.hasOwnProperty(item)) {
|
||
|
let audio = this.audios[item];
|
||
|
audio.source.play();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
openMusic() {
|
||
|
this.setMusic(0.8);
|
||
|
StorageManager.instance.setGlobalData('music', 'true');
|
||
|
}
|
||
|
|
||
|
closeMusic() {
|
||
|
this.setMusic(0);
|
||
|
StorageManager.instance.setGlobalData('music', 'false');
|
||
|
}
|
||
|
|
||
|
openSound() {
|
||
|
this.setSound(1);
|
||
|
StorageManager.instance.setGlobalData('sound', 'true');
|
||
|
}
|
||
|
|
||
|
closeSound() {
|
||
|
this.setSound(0);
|
||
|
StorageManager.instance.setGlobalData('sound', 'false');
|
||
|
}
|
||
|
|
||
|
openAudio() {
|
||
|
this.openMusic();
|
||
|
this.openSound();
|
||
|
}
|
||
|
|
||
|
closeAudio() {
|
||
|
this.closeMusic();
|
||
|
this.closeSound();
|
||
|
}
|
||
|
|
||
|
setSound(flag: number) {
|
||
|
this.soundVolume = flag;
|
||
|
for (let item in this.audios) {
|
||
|
if (this.audios.hasOwnProperty(item) && !this.audios[item].isMusic) {
|
||
|
let audio = this.audios[item];
|
||
|
audio.source.volume = this.soundVolume;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (let idx = 0; idx < this.arrSound.length; idx++) {
|
||
|
let audio = this.arrSound[idx];
|
||
|
audio.source.volume = this.soundVolume;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
stopSingleSound(name: string) {
|
||
|
if (this.audios.hasOwnProperty(name) && !this.audios[name].isMusic) {
|
||
|
let audio = this.audios[name];
|
||
|
audio.source.stop();
|
||
|
}
|
||
|
}
|
||
|
}
|