Add mission brief audio playback using AudioEngineV2
All checks were successful
Build / build (push) Successful in 1m53s
All checks were successful
Build / build (push) Successful in 1m53s
- Add mission_brief_audio field to CloudLevelEntry interface - Update missionBrief.ts to use AudioEngineV2.createSoundAsync() instead of legacy Sound class (fixes audio not playing) - Pass audioEngine to MissionBrief.initialize() from Level1 - Add welcome_rookie.mp3 audio file 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
c87b85de40
commit
e3422ef9f2
BIN
public/assets/themes/default/audio/voice/welcome_rookie.mp3
Normal file
BIN
public/assets/themes/default/audio/voice/welcome_rookie.mp3
Normal file
Binary file not shown.
@ -431,7 +431,7 @@ export class Level1 implements Level {
|
||||
log.info('[Level1] _missionBrief object:', this._missionBrief);
|
||||
log.info('[Level1] Ship exists:', !!this._ship);
|
||||
log.info('[Level1] Ship ID in scene:', DefaultScene.MainScene.getNodeById('Ship') !== null);
|
||||
this._missionBrief.initialize();
|
||||
this._missionBrief.initialize(this._audioEngine);
|
||||
log.info('[Level1] ========== MISSION BRIEF INITIALIZATION COMPLETE ==========');
|
||||
log.debug('Mission brief initialized');
|
||||
|
||||
|
||||
@ -28,6 +28,7 @@ export interface CloudLevelEntry {
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
reviewNotes?: string;
|
||||
missionBriefAudio?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,6 +56,7 @@ interface LevelRow {
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
review_notes?: string;
|
||||
mission_brief_audio?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -93,6 +95,7 @@ function rowToEntry(row: LevelRow): CloudLevelEntry {
|
||||
createdAt: row.created_at,
|
||||
updatedAt: row.updated_at,
|
||||
reviewNotes: row.review_notes,
|
||||
missionBriefAudio: row.mission_brief_audio,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ import {
|
||||
} from "@babylonjs/gui";
|
||||
import { DefaultScene } from "../../core/defaultScene";
|
||||
import {MeshBuilder, Vector3, Observable, Observer} from "@babylonjs/core";
|
||||
import type { AudioEngineV2, StaticSound } from "@babylonjs/core";
|
||||
import log from '../../core/logger';
|
||||
import { LevelConfig } from "../../levels/config/levelConfig";
|
||||
import { CloudLevelEntry } from "../../services/cloudLevelService";
|
||||
@ -22,11 +23,14 @@ export class MissionBrief {
|
||||
private _isVisible: boolean = false;
|
||||
private _onStartCallback: (() => void) | null = null;
|
||||
private _triggerObserver: Observer<void> | null = null;
|
||||
private _audioEngine: AudioEngineV2 | null = null;
|
||||
private _currentSound: StaticSound | null = null;
|
||||
|
||||
/**
|
||||
* Initialize the mission brief as a fullscreen overlay
|
||||
*/
|
||||
public initialize(): void {
|
||||
public initialize(audioEngine?: AudioEngineV2): void {
|
||||
this._audioEngine = audioEngine || null;
|
||||
log.info('[MissionBrief] ========== INITIALIZE CALLED ==========');
|
||||
const scene = DefaultScene.MainScene;
|
||||
log.info('[MissionBrief] Scene exists:', !!scene);
|
||||
@ -232,6 +236,21 @@ export class MissionBrief {
|
||||
this._container.isVisible = true;
|
||||
this._isVisible = true;
|
||||
|
||||
// Play mission brief audio if specified
|
||||
if (directoryEntry?.missionBriefAudio && this._audioEngine) {
|
||||
log.info('[MissionBrief] Playing audio:', directoryEntry.missionBriefAudio);
|
||||
this._audioEngine.createSoundAsync(
|
||||
"missionBriefAudio",
|
||||
directoryEntry.missionBriefAudio,
|
||||
{ loop: false, volume: 1.0 }
|
||||
).then(sound => {
|
||||
this._currentSound = sound;
|
||||
sound.play();
|
||||
}).catch(err => {
|
||||
log.error('[MissionBrief] Failed to load audio:', err);
|
||||
});
|
||||
}
|
||||
|
||||
log.info('[MissionBrief] ========== CONTAINER NOW VISIBLE ==========');
|
||||
log.info('[MissionBrief] Container.isVisible:', this._container.isVisible);
|
||||
log.info('[MissionBrief] _isVisible flag:', this._isVisible);
|
||||
@ -298,6 +317,10 @@ export class MissionBrief {
|
||||
* Clean up resources
|
||||
*/
|
||||
public dispose(): void {
|
||||
if (this._currentSound) {
|
||||
this._currentSound.dispose();
|
||||
this._currentSound = null;
|
||||
}
|
||||
if (this._advancedTexture) {
|
||||
this._advancedTexture.dispose();
|
||||
this._advancedTexture = null;
|
||||
@ -305,6 +328,7 @@ export class MissionBrief {
|
||||
this._container = null;
|
||||
this._onStartCallback = null;
|
||||
this._triggerObserver = null;
|
||||
this._audioEngine = null;
|
||||
this._isVisible = false;
|
||||
log.debug('[MissionBrief] Disposed');
|
||||
}
|
||||
|
||||
@ -138,6 +138,7 @@ create table public.levels
|
||||
tags text[] default '{}'::text[],
|
||||
config jsonb not null,
|
||||
mission_brief text[] default '{}'::text[],
|
||||
mission_brief_audio text,
|
||||
level_type text default 'private'::text not null
|
||||
constraint valid_level_type
|
||||
check (level_type = ANY
|
||||
|
||||
Loading…
Reference in New Issue
Block a user