super-hero/assets/cc-game/scripts/audio/UMAudioController.ts

369 lines
12 KiB
TypeScript
Raw Permalink Normal View History

2024-05-29 19:24:12 -07:00
import { _decorator, AudioClip, AudioSource, Component, instantiate, Node, Prefab } from 'cc';
import { log } from 'cc';
import { UmStorageManager } from '../../../cc-common/cc-util/UmStorageManager';
import { UMAudioSource } from './UMAudioSource';
import { UmLog } from '../../../cc-common/cc-util/UmLog';
import { UmUtil } from '../../../cc-common/cc-util/UmUtil';
const { ccclass, property } = _decorator;
// sound type enum
export const SFX_AUDIO_TYPE = {
BUTTON_CLICK: 'btn_click',
SFX_BATTLE_END: 'battle0_end',
SFX_BATTLE_LOSE: 'battle1_lose',
SFX_BATTLE_OPEN: 'sbattle2_open',
SFX_BATTLE_WIN: 'battle3_win',
SFX_REWARD_BOX_APPEAR: 'reward0_box_appear',
SFX_REWARD_BOX_OPEN: 'reward1_box_open',
SFX_REWARD_CHEST_APPEAR: 'reward2_chest_appear',
SFX_REWARD_CHEST_OPEN: 'reward3_chest_open',
SFX_REWARD_COIN_APPEAR: 'reward4_coin_appear',
SFX_REWARD_COIN_COLLECT: 'reward5_coin_collect',
SFX_DOOR_APPEAR: 'reward0_box_appear',
SFX_DOOR_PASS: 'reward1_box_open',
SFX_COUNTDOWN: 'countdown',
SFX_POPUP_SHOW: 'popup_show',
SFX_CARD_FLIP: 'card_flip',
}
export const MUSIC_AUDIO_TYPE = {
BGM_HOME: 0,
BGM_BATTLE: 1,
BGM_END: 2,
BGM_LOSE: 3,
BGM_WIN: 4,
}
@ccclass('UMAudioController')
export class UMAudioController extends Component {
@property({ type: Prefab }) umAudioSourcePrefab: Prefab = null!;
//audio flip
@property(AudioSource) musicAudioSource: AudioSource = null!;
@property(AudioClip) bgmClips: AudioClip[] = [];
@property(AudioClip) btnClickClip: AudioClip = null!;
@property(AudioClip) screenBattleClips: AudioClip[] = [];
@property(AudioClip) rewardClips: AudioClip[] = [];
@property(AudioClip) countdownClip: AudioClip = null!;
@property(AudioClip) popupClip: AudioClip = null!;
@property(AudioClip) cardFlipClip: AudioClip = null!;
private _mapAudioSource = new Map<string, UMAudioSource>();
private sfxVolume: number = 0.5;
private musicVolume: number = 0.5;
KEY_ALL_SOUNDS_ENABLE = "KEY_ALL_SOUNDS_ENABLE";
KEY_SFX_ENABLE = "KEY_SFX_ENABLE";
KEY_MUSIC_ENABLE = "KEY_MUSIC_ENABLE";
public static instance: UMAudioController = null!;
onLoad() {
UMAudioController.instance = this;
this.playAudioByType(SFX_AUDIO_TYPE.BUTTON_CLICK, false, 0);
this.playHomeMusic();
}
//Music background
public playBackgroundMusic(type: number, loop: boolean = true, volumeScale: number = 1) {
UmLog.log("[playBackgroundMusic] => ", type);
if (this.musicAudioSource.clip)
this.musicAudioSource.stop();
this.musicAudioSource.clip = this.getMusicAudioClipByType(type);
this.musicAudioSource.loop = loop;
this, this.musicAudioSource.volume = this.musicVolume * volumeScale;
this.musicAudioSource.play();
}
public stopBackgroundMusic(type: number) {
if (this.musicAudioSource.clip == this.getMusicAudioClipByType(type))
this.musicAudioSource.stop();
}
public stopAllBackgroundMusic() {
this.musicAudioSource.stop();
}
public playHomeMusic()
{
this.playBackgroundMusic(MUSIC_AUDIO_TYPE.BGM_HOME);
}
public playBattleMusic()
{
this.playBackgroundMusic(MUSIC_AUDIO_TYPE.BGM_BATTLE, true, 0.65);
}
//SFX
public playSfxByType(type: string, loop: boolean = false, volumeScale: number = 1)
{
UmLog.log("[playSfxByType]: ", type.toString());
this.playAudioByType(type, loop, volumeScale);
}
public stopSfxByType(type: string)
{
this.stopAudioByType(type);
}
public stopAllSfx()
{
this.stopAllAudio();
}
playSfxByKeyAndClip(key: string, clip: AudioClip, loop: boolean = false, volumeScale: number = 1) {
this.playAudioByClip(key, clip, loop, volumeScale);
}
stopSfxByKey(key: string) {
UmLog.log("[stopSfxByKey]: ", key);
this.stopAudioByKey(key);
}
private playAudioByType(type: string, loop: boolean = false, volumeScale: number = 1) {
let clip = this.getSfxAudioClipByName(type);
if (clip == null) return;
UmLog.log("[playAudio]: ", type);
if (this._mapAudioSource.has(type)) {
let audioSource = this._mapAudioSource.get(type);
if (audioSource) {
audioSource.setVolume(this.sfxVolume * volumeScale);
audioSource.playAudio(loop);
}
else {
this.playClipByAddAudioSource(clip, loop, type, volumeScale);
}
}
else {
UmLog.log("==> create audio: ", type);
this.playClipByAddAudioSource(clip, loop, type, volumeScale);
}
}
private playAudioByClip(key: string, clip: AudioClip, loop: boolean = false, volumeScale: number = 1) {
if (clip == null) return;
UmLog.log("[playAudio]: ", key);
if (this._mapAudioSource.has(key)) {
let audioSource = this._mapAudioSource.get(key);
if (audioSource) {
audioSource.setVolume(this.sfxVolume * volumeScale);
audioSource.clip = clip;
audioSource.playAudio(loop);
}
else {
this.playClipByAddAudioSource(clip, loop, key, volumeScale);
}
}
else {
UmLog.log("==> create audio: ", key);
this.playClipByAddAudioSource(clip, loop, key, volumeScale);
}
}
private stopAudioByType(type: string) {
if (this._mapAudioSource.has(type.toString())) {
this._mapAudioSource.get(type.toString())?.stop();
}
}
private stopAudioByKey(key: string) {
if (this._mapAudioSource.has(key)) {
UmLog.log("[stopAudioByKey]: ", key);
this._mapAudioSource.get(key)?.stop();
}
}
private stopAllAudio() {
this.musicAudioSource.stop();
this._mapAudioSource.forEach((audio: UMAudioSource, key: string) => {
audio.stopAudio();
}, this);
}
private removeAudio(type: string) {
this.musicAudioSource.play();
if (this._mapAudioSource.has(type.toString())) {
this._mapAudioSource.get(type.toString())?.removeAudio();
}
}
private removeAllAudio() {
this._mapAudioSource.forEach((audio: UMAudioSource, key: string) => {
audio.removeAudio();
this._mapAudioSource.delete(key);
}, this);
}
private playClipByAddAudioSource(clip: AudioClip, loop: boolean, audioName: string, volumeScale: number = 1) {
log("playClipByAddAudioSource = " + audioName);
let item = instantiate(this.umAudioSourcePrefab) as Node;
let audioSource = item.getComponent(UMAudioSource)!;
this._mapAudioSource.set(audioName, audioSource);
audioSource.playAudioClip(clip, loop, audioName, this.sfxVolume * volumeScale);
}
public playAudioOneShot(type: string, volumeScale: number = 1) {
log("==> PLAY AUDIO: ", type.toString());
let volume = volumeScale * this.sfxVolume;
this.playAudioByType(type, false, volume);
}
public playChatSound(type: string, volumeScale: number = 1) {
log("==> PLAY CHAT SOUND: ", type.toString());
// let clip: any = this.listSoundEffecs[type];
// if (clip) {
// this.chatSound.playOneShot(clip, volumeScale * this.chatValume);
// }
let volume = volumeScale * this.musicVolume;
this.playAudioByType(type, false, volume);
}
setSfxVolume(volume: number) {
this.sfxVolume = volume;
this.musicAudioSource.volume = volume;
for (let [key, value] of this._mapAudioSource) {
if (value.playing) {
value.setVolume(this.sfxVolume);
}
}
}
setMusicVolume(volume: number) {
this.musicVolume = volume;
this.musicAudioSource.volume = volume;
}
setMusicEnable(isEnable: boolean) {
UmStorageManager.instance.setBooleanByKey(this.KEY_MUSIC_ENABLE, isEnable);
if (isEnable) {
this.setMusicVolume(1);
UmStorageManager.instance.setBooleanByKey(this.KEY_ALL_SOUNDS_ENABLE, true);
}
else {
this.setMusicVolume(0);
if (!UmStorageManager.instance.getBooleanByKey(this.KEY_SFX_ENABLE, true)) {
UmStorageManager.instance.setBooleanByKey(this.KEY_ALL_SOUNDS_ENABLE, false);
}
}
}
setGameplaySoundEnable(isEnable: boolean) {
UmStorageManager.instance.setBooleanByKey(this.KEY_SFX_ENABLE, isEnable);
if (isEnable) {
this.setSfxVolume(1);
UmStorageManager.instance.setBooleanByKey(this.KEY_ALL_SOUNDS_ENABLE, true);
}
else {
this.setSfxVolume(0);
if (!UmStorageManager.instance.getBooleanByKey(this.KEY_MUSIC_ENABLE, true)) {
UmStorageManager.instance.setBooleanByKey(this.KEY_ALL_SOUNDS_ENABLE, false);
}
}
}
public setAllSoundEnable(isEnable: boolean) {
if (isEnable) {
this.setMusicVolume(1);
this.setSfxVolume(1);
}
else {
this.setMusicVolume(0);
this.setSfxVolume(0);
}
UmStorageManager.instance.setBooleanByKey(this.KEY_ALL_SOUNDS_ENABLE, isEnable);
UmStorageManager.instance.setBooleanByKey(this.KEY_MUSIC_ENABLE, isEnable);
UmStorageManager.instance.setBooleanByKey(this.KEY_SFX_ENABLE, isEnable);
}
setMuteAudio(isMute: boolean) {
this.setSfxVolume(isMute ? 0 : this.getVolumeFromStorageByKey(this.KEY_SFX_ENABLE));
this.setMusicVolume(isMute ? 0 : this.getVolumeFromStorageByKey(this.KEY_MUSIC_ENABLE));
}
getVolumeFromStorageByKey(key: string): number {
let isOn = UmStorageManager.instance.getBooleanByKey(key, true);
return isOn ? 1 : 0;
}
public getSfxAudioClipByName(type: string): AudioClip {
switch (type)
{
case SFX_AUDIO_TYPE.BUTTON_CLICK:
return this.btnClickClip;
case SFX_AUDIO_TYPE.SFX_BATTLE_END:
case SFX_AUDIO_TYPE.SFX_BATTLE_LOSE:
case SFX_AUDIO_TYPE.SFX_BATTLE_OPEN:
case SFX_AUDIO_TYPE.SFX_BATTLE_END:
return this.screenBattleClips[this.getIndexNumberFromType(type)];
case SFX_AUDIO_TYPE.SFX_REWARD_BOX_APPEAR:
case SFX_AUDIO_TYPE.SFX_REWARD_BOX_OPEN:
case SFX_AUDIO_TYPE.SFX_REWARD_CHEST_APPEAR:
case SFX_AUDIO_TYPE.SFX_REWARD_CHEST_OPEN:
case SFX_AUDIO_TYPE.SFX_REWARD_COIN_APPEAR:
case SFX_AUDIO_TYPE.SFX_REWARD_COIN_COLLECT:
return this.rewardClips[this.getIndexNumberFromType(type)];
case SFX_AUDIO_TYPE.SFX_DOOR_APPEAR:
case SFX_AUDIO_TYPE.SFX_DOOR_PASS:
return this.rewardClips[this.getIndexNumberFromType(type)];
case SFX_AUDIO_TYPE.SFX_POPUP_SHOW:
return this.popupClip;
case SFX_AUDIO_TYPE.SFX_COUNTDOWN:
return this.countdownClip;
case SFX_AUDIO_TYPE.SFX_CARD_FLIP:
return this.cardFlipClip;
}
return null;
}
public getMusicAudioClipByType(type: number): AudioClip {
if (this.bgmClips.length <= 0)
return null;
var index = type.claim(0, this.bgmClips.length - 1);
return this.bgmClips[index];
}
public playBtnClickSound()
{
this.playAudioByType(SFX_AUDIO_TYPE.BUTTON_CLICK);
}
public playPopupShowSound() {
this.playAudioByType(SFX_AUDIO_TYPE.SFX_POPUP_SHOW);
}
getIndexNumberFromType(type: string)
{
var index = UmUtil.removeAllNonDigit(type);
if (Number.isNaN(index))
index = 0;
return index;
}
}