DP-Logopedicka-Platforma/js/pexeso/pexeso1.js
2026-04-23 15:41:11 +02:00

1178 lines
31 KiB
JavaScript

/**
* Pexeso hra s integráciou do level systému
* Obsahuje rečové cvičenia, systém hodnotenia a navigáciu
* Autor: Adam Reňak
*/
// ===============================================
// GLOBÁLNE PREMENNÉ PRE PEXESO HRU
// ===============================================
let currentLevelConfig = null; // Konfigurácia aktuálneho levelu
let isCustomLevel = false; // Či je to custom level
// Herné premenné
let gameCards = []; // Pole všetkých kariet v hre
let flippedCards = []; // Aktuálne otočené karty (max 2)
let matchedPairs = 0; // Počet nájdených párov
let totalPairs = 0; // Celkový počet párov v hre
let gameAttempts = 0; // Počet pokusov
let gameStartTime = null; // Čas začatku hry
let gameTimer = null; // Timer pre hru
let currentTime = 0; // Aktuálny čas v sekundách
// Hráči
let players = []; // Pole hráčov
let currentPlayer = 0; // Index aktuálneho hráča
// Rečové cvičenie
let speechRecognition = null; // Web Speech API
let isListening = false; // Či práve počúvame
let currentWord = ''; // Aktuálne slovo na vyslovenie
let speechAttempts = 0; // Počet pokusov pre rečové cvičenie
let maxSpeechAttempts = 3; // Maximálny počet pokusov
// Audio elementy
let sounds = {
cardFlip: null,
correct: null,
wrong: null,
victory: null
};
// ===============================================
// INICIALIZÁCIA HRY
// ===============================================
/**
* Hlavná inicializačná funkcia
* Spúšťa sa pri načítaní stránky
*/
function initializePexesoGame() {
console.log('Inicializujem pexeso hru...');
// Načítaj level konfiguráciu z URL
loadLevelFromURL();
// Inicializuj audio
initializeAudio();
// Inicializuj rečové rozpoznávanie
initializeSpeechRecognition();
// Nastav pozadie sveta
setWorldBackground();
// Skry loading screen
hideLoadingScreen();
// Spusti hru
startGame();
}
/**
* Načítanie level konfigurácie z URL parametrov
*/
function loadLevelFromURL() {
const urlParams = new URLSearchParams(window.location.search);
const worldId = urlParams.get('worldId');
const levelId = urlParams.get('levelId');
const training = urlParams.get('training') === 'true';
console.log('URL parametre:', { worldId, levelId, training });
if (training) {
// Pre tréningové levely - zatiaľ základná konfigurácia
isCustomLevel = true;
currentLevelConfig = {
id: 'training_pexeso',
worldId: worldId || 'world_r',
name: 'Tréningové pexeso',
gameType: 'pexeso',
words: ['rak', 'ryba', 'ruka', 'ruža'],
gameConfig: {
pairs: 4,
timeLimit: null
}
};
} else if (levelId && window.getLevelConfig) {
// Načítaj konfiguráciu z levels.js
currentLevelConfig = window.getLevelConfig(levelId);
isCustomLevel = false;
} else {
// Predvolená konfigurácia
console.warn('Žiadna level konfigurácia, používam predvolenú');
currentLevelConfig = {
id: 'default_pexeso',
worldId: 'world_r',
name: 'Základné pexeso',
gameType: 'pexeso',
words: ['rak', 'ryba', 'ruka', 'ruža'],
gameConfig: {
pairs: 4,
timeLimit: null
}
};
isCustomLevel = true;
}
console.log('Načítaná level konfigurácia:', currentLevelConfig);
}
/**
* Nastavenie pozadia sveta
*/
function setWorldBackground() {
const gameCanvas = document.getElementById('gameCanvas');
if (!gameCanvas || !currentLevelConfig) return;
const worldId = currentLevelConfig.worldId;
// Mapa pozadí pre jednotlivé svety
const worldBackgrounds = {
'world_z': '../images/worlds/world_z.jpg',
'world_s': '../images/worlds/world_s.png',
'world_r': '../images/worlds/world_r.png',
'world_l': '../images/worlds/world_l.png',
'world_c': '../images/worlds/world_c.png',
'world_š': '../images/worlds/world_sh.png',
'world_ž': '../images/worlds/world_zh.png',
'world_č': '../images/worlds/world_ch.png',
'world_d': '../images/worlds/world_d.png',
'world_t': '../images/worlds/world_t.png',
'world_n': '../images/worlds/world_n.png',
'world_k': '../images/worlds/world_k.png',
'world_g': '../images/worlds/world_g.png'
};
const backgroundImage = worldBackgrounds[worldId] || '../images/pozadie.jpg';
gameCanvas.style.backgroundImage = `url('${backgroundImage}')`;
console.log(`Nastavené pozadie pre svet ${worldId}: ${backgroundImage}`);
}
/**
* Inicializácia audio elementov
*/
function initializeAudio() {
sounds.cardFlip = document.getElementById('cardFlipSound') || new Audio('zvuky/effects/kopanie.wav');
sounds.correct = document.getElementById('correctSound') || new Audio('zvuky/effects/spravne.mp3');
sounds.wrong = document.getElementById('wrongSound') || new Audio('zvuky/effects/zle.mp3');
sounds.victory = document.getElementById('victorySound') || new Audio('zvuky/effects/vyhra.mp3');
// Nastav hlasitosť
Object.values(sounds).forEach(sound => {
if (sound) sound.volume = 0.7;
});
}
/**
* Skrytie loading screen
*/
function hideLoadingScreen() {
setTimeout(() => {
const loadingScreen = document.getElementById('loading-screen');
if (loadingScreen) {
loadingScreen.style.opacity = '0';
setTimeout(() => {
loadingScreen.style.display = 'none';
}, 500);
}
}, 1500);
}
// ===============================================
// SPUSTENIE HRY
// ===============================================
/**
* Spustenie novej hry
*/
function startGame() {
console.log('Spúšťam novú hru pexesa...');
if (!currentLevelConfig) {
console.error('Žiadna level konfigurácia!');
return;
}
// Reset herných premenných
resetGameVariables();
// Inicializuj hráčov
initializePlayers();
// Vytvor karty
createGameCards();
// Vygeneruj karty na obrazovke
generateCardsHTML();
// Spusti časomeru
startGameTimer();
console.log('Hra spustená!');
}
/**
* Reset herných premenných
*/
function resetGameVariables() {
gameCards = [];
flippedCards = [];
matchedPairs = 0;
gameAttempts = 0;
currentTime = 0;
currentPlayer = 0;
// Aktualizuj UI
updateAttemptsDisplay();
updateTimeDisplay();
}
/**
* Inicializácia hráčov
*/
function initializePlayers() {
// Pre teraz jeden hráč, neskôr môžeme pridať multiplayer
players = [
{ name: 'Hráč', score: 0, color: 'player-1' }
];
// Aktualizuj UI hráčov
updatePlayersDisplay();
}
/**
* Vytvorenie kariet pre hru
*/
function createGameCards() {
const words = currentLevelConfig.words;
const pairsCount = currentLevelConfig.gameConfig.pairs || Math.min(words.length, 8);
// Vyber slová pre hru
const selectedWords = words.slice(0, pairsCount);
totalPairs = selectedWords.length;
// Vytvor páry kariet
gameCards = [];
selectedWords.forEach((word, index) => {
// Prvá karta páru
gameCards.push({
id: `card_${index}_1`,
word: word,
image: `images/slova/${word}.png`,
pairId: index,
isFlipped: false,
isMatched: false
});
// Druhá karta páru
gameCards.push({
id: `card_${index}_2`,
word: word,
image: `images/slova/${word}.png`,
pairId: index,
isFlipped: false,
isMatched: false
});
});
// Zamiešaj karty
shuffleArray(gameCards);
console.log(`Vytvorených ${gameCards.length} kariet (${totalPairs} párov)`);
}
/**
* Zamiešanie poľa
*/
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
/**
* Generovanie HTML pre karty
*/
function generateCardsHTML() {
const gameCanvas = document.getElementById('gameCanvas');
if (!gameCanvas) return;
// Nastav CSS triedu pre responzívnosť
const cardCount = gameCards.length;
gameCanvas.className = `cards-${cardCount}`;
// Vymaž existujúci obsah
gameCanvas.innerHTML = '';
// Vygeneruj karty
gameCards.forEach((card, index) => {
const cardElement = createCardElement(card, index);
gameCanvas.appendChild(cardElement);
});
console.log(`Vygenerovaných ${gameCards.length} kariet v HTML`);
}
/**
* Vytvorenie HTML elementu karty
*/
function createCardElement(card, index) {
const cardDiv = document.createElement('div');
cardDiv.className = 'card-container';
cardDiv.dataset.cardId = card.id;
cardDiv.dataset.cardIndex = index;
// Obrázok (skrytý na začiatku)
const img = document.createElement('img');
img.src = card.image;
img.alt = card.word;
img.style.display = 'none';
// Text
const span = document.createElement('span');
span.textContent = 'PEXESO';
cardDiv.appendChild(img);
cardDiv.appendChild(span);
// Event listener pre kliknutie
cardDiv.addEventListener('click', () => handleCardClick(index));
return cardDiv;
}
// ===============================================
// LOGIKA KARIET
// ===============================================
/**
* Spracovanie kliknutia na kartu
*/
function handleCardClick(cardIndex) {
const card = gameCards[cardIndex];
const cardElement = document.querySelector(`[data-card-index="${cardIndex}"]`);
// Kontroly - karta už otočená, matchovaná alebo príliš veľa otočených kariet
if (card.isFlipped || card.isMatched || flippedCards.length >= 2) {
return;
}
console.log(`Kliknutie na kartu: ${card.word}`);
// Otočenie karty
flipCard(cardIndex, cardElement);
// Pridaj do otočených kariet
flippedCards.push({ index: cardIndex, card: card, element: cardElement });
// Ak sú otočené 2 karty, skontroluj pár
if (flippedCards.length === 2) {
gameAttempts++;
updateAttemptsDisplay();
setTimeout(() => {
checkForMatch();
}, 1000);
}
}
/**
* Otočenie karty
*/
function flipCard(cardIndex, cardElement) {
const card = gameCards[cardIndex];
// Nastav stav karty
card.isFlipped = true;
// Vizuálne otočenie
cardElement.classList.add('flipped');
// Zobraz obrázok a aktualizuj text
const img = cardElement.querySelector('img');
const span = cardElement.querySelector('span');
if (img) img.style.display = 'block';
if (span) span.textContent = card.word;
// Zahraj zvuk
if (sounds.cardFlip) {
sounds.cardFlip.play().catch(e => console.log('Audio chyba:', e));
}
console.log(`Karta otočená: ${card.word}`);
}
/**
* Kontrola páru
*/
function checkForMatch() {
if (flippedCards.length !== 2) return;
const [first, second] = flippedCards;
const isMatch = first.card.pairId === second.card.pairId;
console.log(`Kontrola páru: ${first.card.word} vs ${second.card.word} = ${isMatch ? 'MATCH' : 'NO MATCH'}`);
if (isMatch) {
handleSuccessfulMatch(first, second);
} else {
handleFailedMatch(first, second);
}
// Vymaž otočené karty
flippedCards = [];
}
/**
* Spracovanie úspešného páru
*/
function handleSuccessfulMatch(first, second) {
console.log('Úspešný pár!');
// Označenie kariet ako matchované
first.card.isMatched = true;
second.card.isMatched = true;
first.element.classList.add('matched');
second.element.classList.add('matched');
// Aktualizuj skóre
players[currentPlayer].score++;
updatePlayersDisplay();
matchedPairs++;
// Zahraj úspešný zvuk
if (sounds.correct) {
sounds.correct.play().catch(e => console.log('Audio chyba:', e));
}
// Spusti rečové cvičenie
startSpeechExercise(first.card.word);
}
/**
* Spracovanie neúspešného páru
*/
function handleFailedMatch(first, second) {
console.log('Neúspešný pár!');
// Otočenie kariet späť
setTimeout(() => {
flipCardBack(first.index, first.element);
flipCardBack(second.index, second.element);
}, 500);
// Zahraj neúspešný zvuk
if (sounds.wrong) {
sounds.wrong.play().catch(e => console.log('Audio chyba:', e));
}
}
/**
* Otočenie karty späť
*/
function flipCardBack(cardIndex, cardElement) {
const card = gameCards[cardIndex];
// Nastav stav karty
card.isFlipped = false;
// Vizuálne otočenie späť
cardElement.classList.remove('flipped');
// Skry obrázok a obnov text
const img = cardElement.querySelector('img');
const span = cardElement.querySelector('span');
if (img) img.style.display = 'none';
if (span) span.textContent = 'PEXESO';
console.log(`Karta otočená späť: ${card.word}`);
}
// ===============================================
// REČOVÉ CVIČENIE
// ===============================================
/**
* Spustenie rečového cvičenia
*/
function startSpeechExercise(word) {
console.log(`Spúšťam rečové cvičenie pre slovo: ${word}`);
currentWord = word;
speechAttempts = 0;
// Zobraz modal
showSpeechModal(word);
}
/**
* Zobrazenie modalu pre rečové cvičenie
*/
function showSpeechModal(word) {
const modal = document.getElementById('cvicenie');
const wordDisplay = document.getElementById('word-display');
const wordImage = document.getElementById('cvicenie-image');
if (modal) {
// Nastav slovo a obrázok
if (wordDisplay) wordDisplay.textContent = word.toUpperCase();
if (wordImage) {
wordImage.src = `images/slova/${word}.png`;
wordImage.alt = word;
}
modal.style.display = 'block';
modal.classList.add('modal-open');
console.log(`Modal zobrazený pre slovo: ${word}`);
}
}
/**
* Inicializácia rečového rozpoznávania
*/
function initializeSpeechRecognition() {
if (!('webkitSpeechRecognition' in window) && !('SpeechRecognition' in window)) {
console.warn('Rečové rozpoznávanie nie je podporované v tomto prehliadači');
return;
}
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
speechRecognition = new SpeechRecognition();
speechRecognition.lang = 'sk-SK';
speechRecognition.continuous = false;
speechRecognition.interimResults = false;
speechRecognition.maxAlternatives = 3;
speechRecognition.onstart = function() {
console.log('Rečové rozpoznávanie spustené');
isListening = true;
updateSpeechButton();
};
speechRecognition.onresult = function(event) {
console.log('Výsledok rečového rozpoznávania:', event);
const result = event.results[0][0].transcript.toLowerCase().trim();
const confidence = event.results[0][0].confidence;
console.log(`Rozpoznané: "${result}" (spoľahlivosť: ${confidence})`);
processSpeechResult(result, confidence);
};
speechRecognition.onerror = function(event) {
console.error('Chyba rečového rozpoznávania:', event.error);
isListening = false;
updateSpeechButton();
showSpeechError(event.error);
};
speechRecognition.onend = function() {
console.log('Rečové rozpoznávanie ukončené');
isListening = false;
updateSpeechButton();
};
// Event listener pre tlačidlo mikrofónu
const micButton = document.getElementById('rozpoznanie');
if (micButton) {
micButton.addEventListener('click', toggleSpeechRecognition);
}
}
/**
* Zapnutie/vypnutie rečového rozpoznávania
*/
function toggleSpeechRecognition() {
if (!speechRecognition) {
console.warn('Rečové rozpoznávanie nie je dostupné');
return;
}
if (isListening) {
speechRecognition.stop();
} else {
speechAttempts++;
speechRecognition.start();
}
}
/**
* Aktualizácia tlačidla mikrofónu
*/
function updateSpeechButton() {
const button = document.getElementById('rozpoznanie');
const buttonContainer = button?.parentElement;
const buttonText = button?.querySelector('a');
if (!button || !buttonContainer || !buttonText) return;
if (isListening) {
buttonContainer.classList.add('recording');
buttonText.textContent = 'POČÚVAM...';
} else {
buttonContainer.classList.remove('recording');
buttonText.textContent = 'HOVORIŤ';
}
}
/**
* Spracovanie výsledku rečového rozpoznávania
*/
function processSpeechResult(recognized, confidence) {
const targetWord = currentWord.toLowerCase();
const isCorrect = recognized.includes(targetWord) ||
targetWord.includes(recognized) ||
calculateSimilarity(recognized, targetWord) > 0.7;
console.log(`Porovnanie: "${recognized}" vs "${targetWord}" = ${isCorrect ? 'SPRÁVNE' : 'NESPRÁVNE'}`);
if (isCorrect || confidence > 0.8) {
handleSpeechSuccess();
} else {
handleSpeechFailure();
}
}
/**
* Spracovanie úspešného rečového cvičenia
*/
function handleSpeechSuccess() {
console.log('Rečové cvičenie úspešné!');
showSpeechResult(true, 'Výborne! Správne si vyslovil slovo.');
setTimeout(() => {
closeSpeechModal();
checkGameEnd();
}, 2000);
}
/**
* Spracovanie neúspešného rečového cvičenia
*/
function handleSpeechFailure() {
console.log('Rečové cvičenie neúspešné');
if (speechAttempts >= maxSpeechAttempts) {
showSpeechResult(false, 'Skús to ešte raz neskôr.');
setTimeout(() => {
closeSpeechModal();
checkGameEnd();
}, 2000);
} else {
const remainingAttempts = maxSpeechAttempts - speechAttempts;
showSpeechResult(false, `Skús to znova. Zostáva ti ${remainingAttempts} pokusov.`);
}
}
/**
* Zobrazenie výsledku rečového cvičenia
*/
function showSpeechResult(success, message) {
const resultDiv = document.getElementById('vysledok');
if (!resultDiv) return;
const imageSrc = success ? 'images/spravne.png' : 'images/nespravne.png';
resultDiv.innerHTML = `
<center>
<img src="${imageSrc}" alt="${success ? 'Správne' : 'Nesprávne'}">
<div class="attempt-message" style="color: white; font-size: 20px; margin-top: 10px;">
${message}
</div>
</center>
`;
resultDiv.classList.add('show');
// Skry výsledok po chvíli
setTimeout(() => {
resultDiv.classList.remove('show');
}, 1500);
}
/**
* Zatvorenie modalu rečového cvičenia
*/
function closeSpeechModal() {
const modal = document.getElementById('cvicenie');
if (modal) {
modal.style.display = 'none';
modal.classList.remove('modal-open');
}
}
/**
* Zobrazenie chyby rečového rozpoznávania
*/
function showSpeechError(error) {
let message = 'Chyba rečového rozpoznávania';
switch (error) {
case 'not-allowed':
message = 'Prístup k mikrofónu je zakázaný';
break;
case 'no-speech':
message = 'Nebola rozpoznaná žiadna reč';
break;
case 'audio-capture':
message = 'Problém s mikrofónom';
break;
case 'network':
message = 'Problém so sieťou';
break;
}
showSpeechResult(false, message);
}
// ===============================================
// ČASOMIERA A UI AKTUALIZÁCIE
// ===============================================
/**
* Spustenie časomiery
*/
function startGameTimer() {
gameStartTime = Date.now();
gameTimer = setInterval(() => {
currentTime = Math.floor((Date.now() - gameStartTime) / 1000);
updateTimeDisplay();
// Kontrola časového limitu
const timeLimit = currentLevelConfig?.timeLimit;
if (timeLimit && currentTime >= timeLimit) {
handleTimeUp();
}
}, 1000);
}
/**
* Zastavenie časomiery
*/
function stopGameTimer() {
if (gameTimer) {
clearInterval(gameTimer);
gameTimer = null;
}
}
/**
* Aktualizácia zobrazenia času
*/
function updateTimeDisplay() {
const timeElement = document.getElementById('game-time');
if (timeElement) {
const minutes = Math.floor(currentTime / 60);
const seconds = currentTime % 60;
timeElement.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`;
}
}
/**
* Aktualizácia zobrazenia pokusov
*/
function updateAttemptsDisplay() {
const attemptsElement = document.getElementById('game-attempts');
if (attemptsElement) {
attemptsElement.textContent = gameAttempts.toString();
}
}
/**
* Aktualizácia zobrazenia hráčov
*/
function updatePlayersDisplay() {
// Pre teraz len jeden hráč - neskôr rozšíriť pre multiplayer
const playerElements = document.querySelectorAll('.players-panel');
playerElements.forEach((element, index) => {
if (index < players.length) {
const player = players[index];
const nameElement = element.querySelector('.name h1');
const scoreElement = element.querySelector('.score span');
if (nameElement) nameElement.textContent = player.name;
if (scoreElement) scoreElement.textContent = player.score;
element.style.display = 'flex';
} else {
element.style.display = 'none';
}
});
}
// ===============================================
// KONIEC HRY A HODNOTENIE
// ===============================================
/**
* Kontrola konca hry
*/
function checkGameEnd() {
console.log(`Nájdené páry: ${matchedPairs}/${totalPairs}`);
if (matchedPairs >= totalPairs) {
endGame();
}
}
/**
* Ukončenie hry
*/
function endGame() {
console.log('Hra ukončená!');
// Zastav časomieru
stopGameTimer();
// Zahraj víťazný zvuk
if (sounds.victory) {
sounds.victory.play().catch(e => console.log('Audio chyba:', e));
}
// Vypočítaj hodnotenie
const stars = calculateStars();
// Ulož pokrok ak nie je custom level
if (!isCustomLevel && currentLevelConfig) {
saveGameProgress(stars, currentTime);
}
// Zobraz konečný modal
showEndGameModal(stars);
}
/**
* Výpočet hviezd na základe výkonu
*/
function calculateStars() {
const timeLimit = currentLevelConfig?.timeLimit;
const targetAttempts = totalPairs * 1.5; // Ideálny počet pokusov
let stars = 1; // Minimálne 1 hviezda za dokončenie
// Hodnotenie na základe pokusov
if (gameAttempts <= targetAttempts) {
stars = 3; // Perfektný výkon
} else if (gameAttempts <= targetAttempts * 1.3) {
stars = 2; // Dobrý výkon
}
// Ak je časový limit, zohľadni čas
if (timeLimit) {
const timePercentage = currentTime / timeLimit;
if (timePercentage > 0.9) {
stars = Math.max(1, stars - 1); // Zníženie za pomalý čas
}
}
console.log(`Hodnotenie: ${stars} hviezd (pokusy: ${gameAttempts}/${targetAttempts}, čas: ${currentTime}s)`);
return Math.max(1, Math.min(3, stars));
}
/**
* Uloženie pokroku hry
*/
function saveGameProgress(stars, time) {
if (!window.progressManager || !currentLevelConfig) return;
try {
window.progressManager.saveLevelProgress(
currentLevelConfig.worldId,
currentLevelConfig.id,
{
stars: stars,
time: time,
attempts: gameAttempts,
completed: true,
timestamp: Date.now()
}
);
console.log('Pokrok uložený');
} catch (error) {
console.error('Chyba pri ukladaní pokroku:', error);
}
}
/**
* Zobrazenie konečného modalu
*/
function showEndGameModal(stars) {
const modal = document.getElementById('endgame');
if (!modal) return;
// Aktualizuj štatistiky
updateEndGameStats(stars);
// Zobraz modal
modal.style.display = 'block';
console.log('Konečný modal zobrazený');
}
/**
* Aktualizácia štatistík v konečnom modali
*/
function updateEndGameStats(stars) {
// Čas
const timeElements = document.querySelectorAll('#endgame .stats span');
if (timeElements.length > 0) {
const minutes = Math.floor(currentTime / 60);
const seconds = currentTime % 60;
timeElements[0].textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`;
}
// Správne/nesprávne pokusy
if (timeElements.length > 1) {
timeElements[1].textContent = matchedPairs;
}
if (timeElements.length > 3) {
timeElements[3].textContent = gameAttempts - matchedPairs;
}
// Hviezdy
updateStarsDisplay(stars);
}
/**
* Aktualizácia zobrazenia hviezd
*/
function updateStarsDisplay(stars) {
const starsContainer = document.getElementById('modal-stars');
if (!starsContainer) return;
starsContainer.innerHTML = '';
for (let i = 1; i <= 3; i++) {
const star = document.createElement('img');
star.src = i <= stars ? 'images/star.png' : 'images/star_empty.png';
star.alt = i <= stars ? 'Hviezda' : 'Prázdna hviezda';
starsContainer.appendChild(star);
}
console.log(`Zobrazených ${stars} hviezd`);
}
/**
* Spracovanie vypršania času
*/
function handleTimeUp() {
console.log('Čas vypršal!');
stopGameTimer();
// Zobraz správu o vypršaní času
alert('Čas vypršal! Hra je ukončená.');
// Ukončenie hry s minimálnym hodnotením
const stars = 1;
if (!isCustomLevel && currentLevelConfig) {
saveGameProgress(stars, currentTime);
}
showEndGameModal(stars);
}
// ===============================================
// NAVIGAČNÉ FUNKCIE
// ===============================================
/**
* Reštart aktuálneho levelu
*/
function restartCurrentLevel() {
console.log('Reštartujem aktuálny level...');
// Zatvor modály
closeAllModals();
// Reštartuj hru
startGame();
}
/**
* Prechod na ďalší level
*/
function goToNextLevel() {
console.log('Pokúšam sa prejsť na ďalší level...');
// Pokús sa použiť gameRouter
if (window.gameRouter && typeof window.gameRouter.continueToNextLevel === 'function') {
window.gameRouter.continueToNextLevel();
} else {
// Fallback - návrat do menu
console.log('GameRouter nie je dostupný, vraciam sa do menu');
returnToMenu();
}
}
/**
* Návrat do menu svetov
*/
function returnToMenu() {
console.log('Návrat do menu svetov...');
// Pokús sa použiť gameRouter
if (window.gameRouter && typeof window.gameRouter.returnToLevelSelector === 'function') {
const worldId = currentLevelConfig?.worldId;
if (worldId) {
window.gameRouter.returnToLevelSelector(worldId);
} else {
window.location.href = 'worldsmenu.html';
}
} else {
// Fallback - priama navigácia
window.location.href = 'worldsmenu.html';
}
}
/**
* Zatvorenie všetkých modálov
*/
function closeAllModals() {
const modals = ['cvicenie', 'zvuky', 'endgame', 'dialogove-okno'];
modals.forEach(modalId => {
const modal = document.getElementById(modalId);
if (modal) {
modal.style.display = 'none';
modal.classList.remove('modal-open');
}
});
// Skry blur background
const blurBg = document.getElementById('blur-background');
if (blurBg) {
blurBg.style.display = 'none';
}
console.log('Všetky modály zatvorené');
}
// ===============================================
// POMOCNÉ FUNKCIE
// ===============================================
/**
* Kontrola dostupnosti Web Speech API
*/
function isSpeechRecognitionSupported() {
return 'webkitSpeechRecognition' in window || 'SpeechRecognition' in window;
}
/**
* Získanie náhodného elementu z poľa
*/
function getRandomElement(array) {
return array[Math.floor(Math.random() * array.length)];
}
/**
* Formátovanie času do MM:SS formátu
*/
function formatTime(seconds) {
const minutes = Math.floor(seconds / 60);
const secs = seconds % 60;
return `${minutes}:${secs.toString().padStart(2, '0')}`;
}
/**
* Debug funkcie pre testovanie
*/
window.pexesoDebug = {
// Simulácia dokončenia hry
finishGame: () => {
matchedPairs = totalPairs;
endGame();
},
// Zobrazenie všetkých kariet
revealAllCards: () => {
gameCards.forEach((card, index) => {
if (!card.isMatched) {
const cardElement = document.querySelector(`[data-card-index="${index}"]`);
flipCard(index, cardElement);
}
});
},
// Reset hry
resetGame: () => {
stopGameTimer();
startGame();
},
// Získanie informácií o hre
getGameInfo: () => {
return {
levelConfig: currentLevelConfig,
gameCards: gameCards,
matchedPairs: matchedPairs,
totalPairs: totalPairs,
gameAttempts: gameAttempts,
currentTime: currentTime,
players: players
};
}
};
// ===============================================
// EVENT LISTENERY A INICIALIZÁCIA
// ===============================================
/**
* Event listener pre načítanie stránky
*/
document.addEventListener('DOMContentLoaded', function() {
console.log('DOM načítaný, inicializujem pexeso...');
// Malé oneskorenie pre načítanie všetkých skriptov
setTimeout(() => {
initializePexesoGame();
}, 100);
});
/**
* Event listener pre zatvorenie stránky
*/
window.addEventListener('beforeunload', function() {
stopGameTimer();
});
/**
* Globálne funkcie pre HTML
*/
window.restartCurrentLevel = restartCurrentLevel;
window.goToNextLevel = goToNextLevel;
window.returnToMenu = returnToMenu;
console.log('Pexeso.js načítaný a pripravený');
// ===============================================
// EXPORT PRE POUŽITIE V INÝCH SÚBOROCH
// ===============================================
// Export hlavných funkcií ak je potrebný
if (typeof module !== 'undefined' && module.exports) {
module.exports = {
initializePexesoGame,
startGame,
restartCurrentLevel,
goToNextLevel,
returnToMenu
};
}