mirror of
https://gitee.com/dgflash/oops-plugin-framework.git
synced 2026-05-08 03:16:49 +08:00
音效模块支持扩展分类
This commit is contained in:
@@ -2,36 +2,16 @@ import { AudioClip, Node, NodePool } from "cc";
|
||||
import { oops } from "../../Oops";
|
||||
import { resLoader } from "../loader/ResLoader";
|
||||
import { AudioEffect } from "./AudioEffect";
|
||||
import { IAudioParams } from "./IAudio";
|
||||
import { AudioEffectType } from "./AudioManager";
|
||||
import { IAudioData, IAudioParams } from "./IAudio";
|
||||
|
||||
/** 音乐效缓冲编号最大值 */
|
||||
const AE_ID_MAX = 30000;
|
||||
|
||||
/** 音效池 */
|
||||
export class AudioEffectPool {
|
||||
private _switch: boolean = true;
|
||||
/** 音效开关 */
|
||||
get switch(): boolean {
|
||||
return this._switch;
|
||||
}
|
||||
set switch(value: boolean) {
|
||||
this._switch = value;
|
||||
if (value) this.stop();
|
||||
}
|
||||
|
||||
private _volume: number = 1;
|
||||
/** 所有音效音量 */
|
||||
get volume(): number {
|
||||
return this._volume;
|
||||
}
|
||||
set volume(value: number) {
|
||||
this._volume = value;
|
||||
|
||||
this.effects.forEach(ae => {
|
||||
ae.volume = value;
|
||||
});
|
||||
}
|
||||
|
||||
/** 音效配置数据 */
|
||||
private data: { [node: string]: IAudioData } = null!;
|
||||
/** 音效播放器节点对象池 */
|
||||
private pool: NodePool = new NodePool();
|
||||
/** 对象池集合 */
|
||||
@@ -49,6 +29,61 @@ export class AudioEffectPool {
|
||||
return this._aeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册音效类型
|
||||
* @param type
|
||||
*/
|
||||
register(type: string) {
|
||||
this.data[type] = { switch: true, volume: 1 };
|
||||
}
|
||||
|
||||
/**
|
||||
* 音效开关
|
||||
* @param type 音效类型
|
||||
* @returns 音效开关
|
||||
*/
|
||||
getSwitch(type: string) {
|
||||
let iad = this.data[type];
|
||||
if (iad == null) console.error(`类型为【${type}】的音效配置不存在`);
|
||||
return iad.switch;
|
||||
}
|
||||
/**
|
||||
* 音效音量设置
|
||||
* @param type 音效类型
|
||||
* @param value 音效开关
|
||||
*/
|
||||
setSwitch(type: string, value: boolean) {
|
||||
let iad = this.data[type];
|
||||
if (iad == null) console.error(`类型为【${type}】的音效配置不存在`);
|
||||
iad.switch = value;
|
||||
|
||||
if (!value) this.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* 音效音量获取
|
||||
* @param type 音效类型
|
||||
* @returns 音效音量
|
||||
*/
|
||||
getVolume(type: string) {
|
||||
let iad = this.data[type];
|
||||
if (iad == null) console.error(`类型为【${type}】的音效配置不存在`);
|
||||
return iad.volume;
|
||||
}
|
||||
|
||||
/**
|
||||
* 音效音量设置
|
||||
* @param type 音效类型
|
||||
* @param value 音效音量
|
||||
*/
|
||||
setVolume(type: string, value: number) {
|
||||
let iad = this.data[type];
|
||||
if (iad == null) console.error(`类型为【${type}】的音效配置不存在`);
|
||||
iad.volume = value;
|
||||
|
||||
this.effects.forEach(ac => ac.volume = value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载与播放音效
|
||||
* @param path 音效资源地址与音效资源
|
||||
@@ -57,21 +92,26 @@ export class AudioEffectPool {
|
||||
*/
|
||||
async loadAndPlay(path: string | AudioClip, params?: IAudioParams): Promise<number> {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
if (!this.switch) return resolve(-1);
|
||||
|
||||
if (params == null) {
|
||||
params = {
|
||||
bundle: resLoader.defaultBundleName,
|
||||
volume: this.volume,
|
||||
loop: false,
|
||||
type: AudioEffectType.Effect
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (params.bundle == null) params.bundle = resLoader.defaultBundleName;
|
||||
if (params.volume == null) params.volume = this.volume;
|
||||
if (params.loop == null) params.loop = false;
|
||||
if (params.type == null) params.type = AudioEffectType.Effect;
|
||||
}
|
||||
|
||||
let iad = this.data[params.type!];
|
||||
if (iad == null) console.error(`类型为【${params.type!}】的音效配置不存在`);
|
||||
|
||||
if (!iad.switch) return resolve(-1);
|
||||
|
||||
if (params.volume == null) params.volume = iad.volume;
|
||||
|
||||
let bundle = params.bundle!;
|
||||
|
||||
let key: string = null!;
|
||||
@@ -157,7 +197,7 @@ export class AudioEffectPool {
|
||||
const bundle = ae.params!.bundle!;
|
||||
this.put(ae.aeid, ae.path, bundle); // 播放完回收对象
|
||||
ae.params && ae.params.onPlayComplete && ae.params.onPlayComplete(ae.aeid, ae.path, bundle);
|
||||
// console.log(`【音效】回收,池中剩余音效播放器【${this.pool.size()}】`);
|
||||
console.log(`【音效】回收,池中剩余音效播放器【${this.pool.size()}】`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,19 +229,27 @@ export class AudioEffectPool {
|
||||
|
||||
/** 停止播放所有音效 */
|
||||
stop() {
|
||||
this.effects.forEach(ae => ae.stop());
|
||||
this.effects.forEach(ae => {
|
||||
ae.stop();
|
||||
this.onAudioEffectPlayComplete(ae);
|
||||
});
|
||||
this.effects.clear();
|
||||
}
|
||||
|
||||
/** 恢复所有音效 */
|
||||
play() {
|
||||
if (!this.switch) return;
|
||||
// if (!this.switch) return;
|
||||
this.effects.forEach(ae => ae.play());
|
||||
}
|
||||
|
||||
/** 暂停所有音效 */
|
||||
pause() {
|
||||
if (!this.switch) return;
|
||||
this.effects.forEach(ae => ae.pause());
|
||||
// if (!this.switch) return;
|
||||
this.effects.forEach(ae => {
|
||||
ae.pause();
|
||||
this.onAudioEffectPlayComplete(ae);
|
||||
});
|
||||
this.effects.clear();
|
||||
}
|
||||
|
||||
/** 释放所有音效资源与对象池中播放器 */
|
||||
|
||||
@@ -2,10 +2,18 @@ import { AudioClip, Component } from "cc";
|
||||
import { oops } from "../../Oops";
|
||||
import { AudioEffectPool } from "./AudioEffectPool";
|
||||
import { AudioMusic } from "./AudioMusic";
|
||||
import { IAudioParams } from "./IAudio";
|
||||
import { IAudioData, IAudioParams } from "./IAudio";
|
||||
|
||||
const LOCAL_STORE_KEY = "game_audio";
|
||||
|
||||
/** 音乐音效默认类型 */
|
||||
export enum AudioEffectType {
|
||||
/** 背景音乐 */
|
||||
Music = "music",
|
||||
/** 音乐音效 */
|
||||
Effect = "effect",
|
||||
}
|
||||
|
||||
/**
|
||||
* 音频管理
|
||||
* @help https://gitee.com/dgflash/oops-framework/wikis/pages?sort_id=12037893&doc_id=2873565
|
||||
@@ -20,7 +28,7 @@ export class AudioManager extends Component {
|
||||
effect: AudioEffectPool = new AudioEffectPool();
|
||||
|
||||
/** 音乐管理状态数据 */
|
||||
private localData: any = {};
|
||||
private data: { [node: string]: IAudioData } = {};
|
||||
|
||||
/**
|
||||
* 播放音效
|
||||
@@ -38,13 +46,12 @@ export class AudioManager extends Component {
|
||||
|
||||
/** 恢复当前暂停的音乐与音效播放 */
|
||||
resumeAll() {
|
||||
if (!this.music.playing && this.music.progress > 0) this.music.play();
|
||||
this.effect.play();
|
||||
this.music.resume();
|
||||
}
|
||||
|
||||
/** 暂停当前音乐与音效的播放 */
|
||||
pauseAll() {
|
||||
if (this.music.playing) this.music.pause();
|
||||
this.music.pause();
|
||||
this.effect.pause();
|
||||
}
|
||||
|
||||
@@ -56,20 +63,15 @@ export class AudioManager extends Component {
|
||||
|
||||
/** 保存音乐音效的音量、开关配置数据到本地 */
|
||||
save() {
|
||||
this.localData.volume_music = this.music.volume;
|
||||
this.localData.volume_effect = this.effect.volume;
|
||||
this.localData.switch_music = this.music.switch;
|
||||
this.localData.switch_effect = this.effect.switch;
|
||||
|
||||
oops.storage.set(LOCAL_STORE_KEY, this.localData);
|
||||
oops.storage.set(LOCAL_STORE_KEY, this.data);
|
||||
}
|
||||
|
||||
/** 本地加载音乐音效的音量、开关配置数据并设置到游戏中 */
|
||||
load() {
|
||||
this.music = this.getComponent(AudioMusic) || this.addComponent(AudioMusic)!;
|
||||
|
||||
this.localData = oops.storage.getJson(LOCAL_STORE_KEY);
|
||||
if (this.localData) {
|
||||
this.data = oops.storage.getJson(LOCAL_STORE_KEY);
|
||||
if (this.data) {
|
||||
try {
|
||||
this.setState();
|
||||
}
|
||||
@@ -83,17 +85,37 @@ export class AudioManager extends Component {
|
||||
}
|
||||
|
||||
private setState() {
|
||||
this.music.volume = this.localData.volume_music;
|
||||
this.effect.volume = this.localData.volume_effect;
|
||||
this.music.switch = this.localData.switch_music;
|
||||
this.effect.switch = this.localData.switch_effect;
|
||||
for (let type in this.data) {
|
||||
let iad = this.data[type];
|
||||
switch (type) {
|
||||
case "music":
|
||||
this.music.switch = this.data.music.switch;
|
||||
this.music.volume = this.data.music.volume;
|
||||
break;
|
||||
default:
|
||||
this.effect.setSwitch(type, iad.switch);
|
||||
this.effect.setVolume(type, iad.volume);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private setStateDefault() {
|
||||
this.localData = {};
|
||||
this.data = {
|
||||
music: { switch: true, volume: 1 },
|
||||
effect: { switch: true, volume: 1 },
|
||||
};
|
||||
|
||||
//@ts-ignore
|
||||
this.music.data = this.data;
|
||||
this.music.switch = true
|
||||
this.music.volume = 1;
|
||||
this.effect.volume = 1;
|
||||
this.music.switch = true;
|
||||
this.effect.switch = true;
|
||||
|
||||
//@ts-ignore
|
||||
this.effect.data = this.data;
|
||||
this.effect.setSwitch(AudioEffectType.Effect, true);
|
||||
this.effect.setVolume(AudioEffectType.Effect, 1);
|
||||
|
||||
this.save();
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,8 @@
|
||||
*/
|
||||
import { AudioClip, AudioSource, _decorator } from 'cc';
|
||||
import { resLoader } from '../loader/ResLoader';
|
||||
import { IAudioParams } from './IAudio';
|
||||
import { AudioEffectType } from './AudioManager';
|
||||
import { IAudioData, IAudioParams } from './IAudio';
|
||||
|
||||
const { ccclass } = _decorator;
|
||||
|
||||
@@ -16,22 +17,50 @@ const { ccclass } = _decorator;
|
||||
*/
|
||||
@ccclass('AudioMusic')
|
||||
export class AudioMusic extends AudioSource {
|
||||
/** 音效配置数据 */
|
||||
private data: { [node: string]: IAudioData } = null!;
|
||||
|
||||
private _progress: number = 0;
|
||||
private _isLoading: boolean = false;
|
||||
private _nextUrl: string = null!;
|
||||
private _nextParams: IAudioParams = null!;
|
||||
private _params: IAudioParams = null!;
|
||||
|
||||
/** 背景音乐开关 */
|
||||
private _switch: boolean = true;
|
||||
get switch(): boolean {
|
||||
return this._switch;
|
||||
/**
|
||||
* 音效开关
|
||||
* @param type 音效类型
|
||||
* @returns 音效开关
|
||||
*/
|
||||
get switch() {
|
||||
return this.data[AudioEffectType.Music].switch;
|
||||
}
|
||||
/**
|
||||
* 音效音量设置
|
||||
* @param type 音效类型
|
||||
* @param value 音效开关
|
||||
*/
|
||||
set switch(value: boolean) {
|
||||
this._switch = value;
|
||||
this.data[AudioEffectType.Music].switch = value;
|
||||
if (!value) this.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* 音效音量获取
|
||||
* @param type 音效类型
|
||||
* @returns 音效音量
|
||||
*/
|
||||
get volume() {
|
||||
return this.data[AudioEffectType.Music].volume;
|
||||
}
|
||||
/**
|
||||
* 音效音量设置
|
||||
* @param value 音效音量
|
||||
*/
|
||||
set volume(value: number) {
|
||||
this.data[AudioEffectType.Music].volume = value;
|
||||
super.volume = value;
|
||||
}
|
||||
|
||||
/** 获取音乐播放进度 */
|
||||
get progress(): number {
|
||||
if (this.duration > 0)
|
||||
@@ -125,6 +154,17 @@ export class AudioMusic extends AudioSource {
|
||||
}
|
||||
}
|
||||
|
||||
/** 恢复当前暂停的音乐与音效播放 */
|
||||
resume() {
|
||||
if (!this.playing && this.progress > 0) super.play();
|
||||
}
|
||||
|
||||
/** 暂停当前音乐与音效的播放 */
|
||||
pause() {
|
||||
if (this.playing) super.pause();
|
||||
}
|
||||
|
||||
/** 停止当前音乐与音效的播放 */
|
||||
stop(): void {
|
||||
if (this.switch && this.playing) {
|
||||
super.stop();
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export interface IAudioParams {
|
||||
/** 音乐分类 */
|
||||
type?: string,
|
||||
/** 资源包名 */
|
||||
bundle?: string,
|
||||
/** 是否循环播放 */
|
||||
@@ -7,4 +9,11 @@ export interface IAudioParams {
|
||||
volume?: number;
|
||||
/** 播放完成事件 */
|
||||
onPlayComplete?: Function;
|
||||
}
|
||||
|
||||
export interface IAudioData {
|
||||
/** 音乐开关 */
|
||||
switch: boolean;
|
||||
/** 音量 */
|
||||
volume: number;
|
||||
}
|
||||
Reference in New Issue
Block a user