同步主站 Cocos 当前工程:关卡资源、运行脚本与打包工具。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -5,7 +5,6 @@ const CLIPS = {
|
||||
background: 'audio/Backgroud',
|
||||
move: 'audio/Move',
|
||||
jump: 'audio/Jump',
|
||||
vehicleMove: 'audio/FlyingCarpetMove',
|
||||
fail: 'audio/Fail',
|
||||
success: 'audio/Success',
|
||||
coins: 'audio/GetCoins',
|
||||
@@ -21,6 +20,17 @@ export class GameAudio {
|
||||
private static readonly cache = new Map<string, AudioClip>();
|
||||
private static readonly loading = new Map<string, Promise<AudioClip | null>>();
|
||||
private static sfxHost: Node | null = null;
|
||||
private static muted = false;
|
||||
|
||||
static isMuted(): boolean {
|
||||
return GameAudio.muted;
|
||||
}
|
||||
|
||||
/** HUD / JS callMute:静音后背景与全部音效都不再出声 */
|
||||
static setMuted(mute: boolean) {
|
||||
GameAudio.muted = mute;
|
||||
GameAudio.applyVolumeToScene();
|
||||
}
|
||||
|
||||
static async preload(): Promise<void> {
|
||||
await Promise.all(Object.values(CLIPS).map((p) => GameAudio.loadClip(p)));
|
||||
@@ -64,37 +74,40 @@ export class GameAudio {
|
||||
src.clip = clip;
|
||||
src.loop = true;
|
||||
src.playOnAwake = false;
|
||||
src.volume = 1;
|
||||
src.volume = GameAudio.currentVolume();
|
||||
if (!src.playing) {
|
||||
src.play();
|
||||
}
|
||||
}
|
||||
|
||||
static playSfx(key: SfxKey, host?: Node) {
|
||||
if (GameAudio.muted) return;
|
||||
void GameAudio.playSfxAsync(key, host);
|
||||
}
|
||||
|
||||
/** 对齐 Unity:同一 AudioSource 播放中则不重复触发移动/跳跃音效 */
|
||||
static async playSfxOnSource(src: AudioSource, key: SfxKey): Promise<boolean> {
|
||||
if (!src?.node?.isValid || src.playing) return false;
|
||||
if (GameAudio.muted || !src?.node?.isValid || src.playing) return false;
|
||||
const clip = await GameAudio.loadClip(CLIPS[key]);
|
||||
if (!clip) return false;
|
||||
if (!clip || GameAudio.muted || !src.node?.isValid) return false;
|
||||
src.clip = clip;
|
||||
src.loop = false;
|
||||
src.volume = 1;
|
||||
src.volume = GameAudio.currentVolume();
|
||||
src.play();
|
||||
return true;
|
||||
}
|
||||
|
||||
private static async playSfxAsync(key: SfxKey, host?: Node) {
|
||||
if (GameAudio.muted) return;
|
||||
const clip = await GameAudio.loadClip(CLIPS[key]);
|
||||
if (!clip) return;
|
||||
if (!clip || GameAudio.muted) return;
|
||||
|
||||
const root = host?.isValid ? host : GameAudio.ensureSfxHost();
|
||||
if (!root?.isValid) return;
|
||||
|
||||
const src = root.getComponent(AudioSource) ?? root.addComponent(AudioSource);
|
||||
src.playOneShot(clip, 1);
|
||||
src.volume = GameAudio.currentVolume();
|
||||
src.playOneShot(clip, GameAudio.currentVolume());
|
||||
}
|
||||
|
||||
private static ensureSfxHost(): Node | null {
|
||||
@@ -116,8 +129,23 @@ export class GameAudio {
|
||||
static resumeAll() {
|
||||
const scene = director.getScene();
|
||||
if (!scene) return;
|
||||
const vol = GameAudio.currentVolume();
|
||||
for (const src of scene.getComponentsInChildren(AudioSource)) {
|
||||
src.volume = vol;
|
||||
if (src.clip && !src.playing) src.play();
|
||||
}
|
||||
}
|
||||
|
||||
private static currentVolume(): number {
|
||||
return GameAudio.muted ? 0 : 1;
|
||||
}
|
||||
|
||||
private static applyVolumeToScene() {
|
||||
const scene = director.getScene();
|
||||
if (!scene) return;
|
||||
const vol = GameAudio.currentVolume();
|
||||
for (const src of scene.getComponentsInChildren(AudioSource)) {
|
||||
src.volume = vol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user