end
This commit is contained in:
162
src/scenes/EndScene.ts
Normal file
162
src/scenes/EndScene.ts
Normal file
@@ -0,0 +1,162 @@
|
||||
import Phaser from 'phaser';
|
||||
|
||||
/**
|
||||
* Scène de fin : lit une vidéo de victoire en mode paysage puis retourne au menu
|
||||
*/
|
||||
export class EndScene extends Phaser.Scene {
|
||||
private video?: Phaser.GameObjects.Video;
|
||||
private hasFinished: boolean = false;
|
||||
|
||||
constructor() {
|
||||
super({ key: 'EndScene' });
|
||||
}
|
||||
|
||||
create(): void {
|
||||
const { width, height } = this.cameras.main;
|
||||
this.cameras.main.setBackgroundColor('#000000');
|
||||
|
||||
console.log('[EndScene] Création de la scène de fin');
|
||||
console.log('[EndScene] Dimensions:', width, 'x', height);
|
||||
|
||||
// Lancer directement la vidéo de fin
|
||||
this.playEndVideo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lit la vidéo de fin
|
||||
*/
|
||||
private playEndVideo(): void {
|
||||
const { width, height } = this.cameras.main;
|
||||
|
||||
console.log('[EndScene] Vidéo dans cache?', this.cache.video.exists('end'));
|
||||
|
||||
if (!this.cache.video.exists('end')) {
|
||||
console.warn('[EndScene] Vidéo de fin non trouvée → passage au menu.');
|
||||
this.gotoMenu();
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('[EndScene] Création de l\'objet vidéo');
|
||||
this.video = this.add.video(width / 2, height / 2, 'end');
|
||||
this.video.setOrigin(0.5);
|
||||
this.video.setDepth(1000);
|
||||
|
||||
// Attendre que les métadonnées soient chargées
|
||||
this.video.on('metadata', () => {
|
||||
if (!this.video) return;
|
||||
|
||||
const videoWidth = this.video.video?.videoWidth || 324;
|
||||
const videoHeight = this.video.video?.videoHeight || 720;
|
||||
|
||||
console.log('[EndScene] Métadonnées vidéo chargées:', videoWidth, 'x', videoHeight);
|
||||
|
||||
this.video.setSize(videoWidth, videoHeight);
|
||||
this.updateVideoSize();
|
||||
});
|
||||
|
||||
// Activer l'audio
|
||||
this.video.setMute(false);
|
||||
this.video.setLoop(false);
|
||||
|
||||
console.log('[EndScene] Démarrage de la lecture');
|
||||
const started = this.video.play(true); // Autoplay
|
||||
console.log('[EndScene] Lecture démarrée?', started);
|
||||
|
||||
if (!started) {
|
||||
console.warn('[EndScene] Lecture vidéo bloquée → passage au menu.');
|
||||
this.gotoMenu();
|
||||
return;
|
||||
}
|
||||
|
||||
// Événement de fin de vidéo
|
||||
this.video.once('complete', () => {
|
||||
console.log('[EndScene] Vidéo terminée (événement complete) → passage au menu');
|
||||
this.gotoMenu();
|
||||
});
|
||||
|
||||
// Événement alternatif 'stop' au cas où 'complete' ne se déclenche pas
|
||||
this.video.once('stop', () => {
|
||||
console.log('[EndScene] Vidéo arrêtée (événement stop) → passage au menu');
|
||||
this.gotoMenu();
|
||||
});
|
||||
|
||||
this.video.once('error', (err: any) => {
|
||||
console.error('[EndScene] Erreur lecture vidéo:', err);
|
||||
this.gotoMenu();
|
||||
});
|
||||
|
||||
// Sécurité : timer basé sur la durée de la vidéo + 2 secondes
|
||||
// Si la vidéo n'est pas finie après sa durée, forcer le passage au menu
|
||||
this.video.on('metadata', () => {
|
||||
if (!this.video || !this.video.video) return;
|
||||
const duration = this.video.getDuration();
|
||||
console.log('[EndScene] Durée de la vidéo:', duration, 'secondes');
|
||||
|
||||
// Timer de sécurité : durée vidéo + 2 secondes
|
||||
this.time.delayedCall((duration + 2) * 1000, () => {
|
||||
if (!this.hasFinished) {
|
||||
console.warn('[EndScene] Timer de sécurité déclenché → passage au menu');
|
||||
this.gotoMenu();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Ajuster si resize
|
||||
this.scale.on('resize', (gameSize: Phaser.Structs.Size) => {
|
||||
if (this.video && this.video.isPlaying()) {
|
||||
this.updateVideoSize(gameSize.width, gameSize.height);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajuste la vidéo à l'écran en mode paysage en respectant le ratio
|
||||
*/
|
||||
private updateVideoSize(targetW?: number, targetH?: number): void {
|
||||
if (!this.video) return;
|
||||
const w = targetW ?? this.cameras.main.width;
|
||||
const h = targetH ?? this.cameras.main.height;
|
||||
|
||||
// Dimensions natives de la vidéo
|
||||
const nativeW = this.video.video?.videoWidth || 324;
|
||||
const nativeH = this.video.video?.videoHeight || 720;
|
||||
|
||||
console.log('[EndScene] updateVideoSize - Écran:', w, 'x', h);
|
||||
console.log('[EndScene] updateVideoSize - Vidéo native:', nativeW, 'x', nativeH);
|
||||
|
||||
// Ratio vidéo et écran
|
||||
const videoRatio = nativeW / nativeH;
|
||||
const screenRatio = w / h;
|
||||
|
||||
let scale: number;
|
||||
|
||||
// Mode "contain" : adapter pour que toute la vidéo soit visible
|
||||
if (screenRatio > videoRatio) {
|
||||
// L'écran est plus large que la vidéo → adapter à la HAUTEUR
|
||||
scale = h / nativeH;
|
||||
} else {
|
||||
// L'écran est plus étroit que la vidéo → adapter à la LARGEUR
|
||||
scale = w / nativeW;
|
||||
}
|
||||
|
||||
const finalWidth = nativeW * scale;
|
||||
const finalHeight = nativeH * scale;
|
||||
|
||||
console.log('[EndScene] updateVideoSize - Scale:', scale.toFixed(2));
|
||||
console.log('[EndScene] updateVideoSize - Taille finale:', Math.round(finalWidth), 'x', Math.round(finalHeight));
|
||||
|
||||
this.video.setScale(scale);
|
||||
this.video.setPosition(w / 2, h / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Passe au menu
|
||||
*/
|
||||
private gotoMenu(): void {
|
||||
if (this.hasFinished) return;
|
||||
this.hasFinished = true;
|
||||
this.video?.stop();
|
||||
this.video?.destroy();
|
||||
this.scene.start('MenuScene');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user