Compare commits
4 Commits
c4370815f2
...
84cd04a4cf
| Author | SHA1 | Date | |
|---|---|---|---|
| 84cd04a4cf | |||
| dab95812cc | |||
| ab4372c57c | |||
| d36c025cf2 |
69
client/js/guideVoice.js
Normal file
69
client/js/guideVoice.js
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
guideVoice.js
|
||||||
|
|
||||||
|
Vocalise les instructions recues du serveur via la synthese vocale du navigateur
|
||||||
|
*/
|
||||||
|
|
||||||
|
let currentUtterance = null;
|
||||||
|
let voixChoisie = null;
|
||||||
|
let voixPretes = false;
|
||||||
|
let texteEnAttente = null;
|
||||||
|
|
||||||
|
const NOM_VOIX_PREFERE = "French (France)+female1";
|
||||||
|
|
||||||
|
function resoudreVoix() {
|
||||||
|
if (voixPretes) return; // deja fait, evite le travail en double
|
||||||
|
|
||||||
|
const voix = speechSynthesis.getVoices();
|
||||||
|
if (voix.length === 0) return; // toujours pas chargees
|
||||||
|
|
||||||
|
voixChoisie =
|
||||||
|
voix.find(v => v.name === NOM_VOIX_PREFERE) ||
|
||||||
|
voix.find(v => v.lang.startsWith("fr")) ||
|
||||||
|
voix[0];
|
||||||
|
|
||||||
|
voixPretes = true;
|
||||||
|
console.log("Voix sélectionnée:", voixChoisie?.name);
|
||||||
|
|
||||||
|
if (texteEnAttente) {
|
||||||
|
const texte = texteEnAttente;
|
||||||
|
texteEnAttente = null;
|
||||||
|
jouer(texte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Piste 1 : l'event, au cas ou il se declenche sur d'autres navigateurs
|
||||||
|
speechSynthesis.onvoiceschanged = resoudreVoix;
|
||||||
|
|
||||||
|
// Piste 2 : sondage en secours, car onvoiceschanged n'est pas fiable sur Firefox/LibreWolf
|
||||||
|
const intervalleSondage = setInterval(() => {
|
||||||
|
resoudreVoix();
|
||||||
|
if (voixPretes) clearInterval(intervalleSondage);
|
||||||
|
}, 200);
|
||||||
|
|
||||||
|
resoudreVoix(); // au cas ou les voix sont deja dispo au chargement du module
|
||||||
|
|
||||||
|
function jouer(texte) {
|
||||||
|
if (speechSynthesis.speaking) {
|
||||||
|
speechSynthesis.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
currentUtterance = new SpeechSynthesisUtterance(texte);
|
||||||
|
currentUtterance.voice = voixChoisie;
|
||||||
|
currentUtterance.lang = "fr-FR";
|
||||||
|
currentUtterance.onstart = () => console.log("Lecture démarrée");
|
||||||
|
currentUtterance.onend = () => console.log("Lecture terminée");
|
||||||
|
currentUtterance.onerror = (e) => console.error("Erreur synthèse:", e.error, e);
|
||||||
|
|
||||||
|
speechSynthesis.speak(currentUtterance);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function speakInstruction(texte) {
|
||||||
|
if (!voixPretes) {
|
||||||
|
console.log("Voix pas encore prêtes, mise en attente:", texte);
|
||||||
|
texteEnAttente = texte;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
jouer(texte);
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ import { roleState } from "./role.js";
|
|||||||
import { render, drawBlind } from "./canvas.js";
|
import { render, drawBlind } from "./canvas.js";
|
||||||
import { setupMovement } from "./movement.js";
|
import { setupMovement } from "./movement.js";
|
||||||
import { showGameOver, showVictory, updateTimerDisplay } from "./ui.js";
|
import { showGameOver, showVictory, updateTimerDisplay } from "./ui.js";
|
||||||
|
import { speakInstruction} from "./guideVoice.js";
|
||||||
|
|
||||||
setupMovement();
|
setupMovement();
|
||||||
|
|
||||||
@@ -48,3 +49,8 @@ socket.on("victory", () => {
|
|||||||
socket.on("timer", (timeLeft) => {
|
socket.on("timer", (timeLeft) => {
|
||||||
updateTimerDisplay(timeLeft);
|
updateTimerDisplay(timeLeft);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socket.on("instruction", (data) => {
|
||||||
|
console.log("Payload recu", data);
|
||||||
|
speakInstruction(data.texte);
|
||||||
|
})
|
||||||
|
|||||||
27
server/guideInstruction.js
Normal file
27
server/guideInstruction.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
guideInstruction.js
|
||||||
|
|
||||||
|
sert a envoyer au client guide les instructions
|
||||||
|
*/
|
||||||
|
|
||||||
|
const INSTRUCTION_GUIDE = "instruction";
|
||||||
|
const INSTRUCTION_INTERVAL_MS = 5000;
|
||||||
|
|
||||||
|
|
||||||
|
function startInstructionLoop(wSS, socket, partnerSocket, pairState, getInstructionText) {
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
if (pairState.gameOver) {
|
||||||
|
clearInterval(interval);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const guideSocket = socket.data.role === "guide" ? socket : partnerSocket;
|
||||||
|
|
||||||
|
const texte = getInstructionText();
|
||||||
|
guideSocket.emit(INSTRUCTION_GUIDE, { texte });
|
||||||
|
}, INSTRUCTION_INTERVAL_MS);
|
||||||
|
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { startInstructionLoop };
|
||||||
@@ -8,6 +8,7 @@ const gameState = require("./gameState");
|
|||||||
const { GAME_DURATION } = require("./config");
|
const { GAME_DURATION } = require("./config");
|
||||||
const { handleDoorReached } = require("./doorLogic");
|
const { handleDoorReached } = require("./doorLogic");
|
||||||
const { startTimer } = require("./timer");
|
const { startTimer } = require("./timer");
|
||||||
|
const { startInstructionLoop } = require("./guideInstruction");
|
||||||
|
|
||||||
function registerSocketHandlers(wSS, socket) {
|
function registerSocketHandlers(wSS, socket) {
|
||||||
console.log(`Un client s'est connecté : ${socket.id}`);
|
console.log(`Un client s'est connecté : ${socket.id}`);
|
||||||
@@ -38,6 +39,9 @@ function registerSocketHandlers(wSS, socket) {
|
|||||||
partner.emit("status", "Partie prête !");
|
partner.emit("status", "Partie prête !");
|
||||||
|
|
||||||
startTimer(socket, partner, pairState);
|
startTimer(socket, partner, pairState);
|
||||||
|
startInstructionLoop(wSS, socket , partner, pairState, () => {
|
||||||
|
return "Descendre de quatre cases, aller a droite de une case, descendre de 1 case";
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.on("door_reached", (position) => handleDoorReached(wSS, socket, position));
|
socket.on("door_reached", (position) => handleDoorReached(wSS, socket, position));
|
||||||
|
|||||||
Reference in New Issue
Block a user