modified: templates/quiz_buzzer_multiplayer.html
This commit is contained in:
@@ -243,6 +243,9 @@
|
||||
let decayRate = parseInt(localStorage.getItem('buzzer_decay_rate')) || 50;
|
||||
let gameStarted = false;
|
||||
let currentBuzzer = null;
|
||||
let buzzedPlayers = []; // Liste der Spieler die schon gebuzzert haben
|
||||
let canBuzz = false; // Kann man buzzern?
|
||||
let pendingPoints = 0; // Punkte die noch nicht gezählt wurden
|
||||
|
||||
// Lade Team-Namen und Anzahl
|
||||
const teamCount = parseInt(localStorage.getItem('team_count')) || 4;
|
||||
@@ -256,6 +259,14 @@
|
||||
{ id: 4, name: teamNames[3] || 'Spieler 4', score: {{ player_scores[3] if player_scores else 0 }} }
|
||||
];
|
||||
|
||||
// Leertaste zum Buzzern
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.code === 'Space' && canBuzz && !currentBuzzer) {
|
||||
e.preventDefault();
|
||||
triggerBuzz();
|
||||
}
|
||||
});
|
||||
|
||||
window.onSpotifyWebPlaybackSDKReady = () => {
|
||||
const token = '{{ access_token }}';
|
||||
const player = new Spotify.Player({
|
||||
@@ -330,6 +341,7 @@
|
||||
gameStarted = true;
|
||||
document.getElementById('startButton').classList.add('disabled');
|
||||
document.getElementById('startButton').style.cursor = 'wait';
|
||||
document.getElementById('buzzerHint').style.display = 'block';
|
||||
|
||||
const device_id = window.deviceId;
|
||||
const startPosition = getOption('startPosition', 'start');
|
||||
@@ -344,21 +356,19 @@
|
||||
.then(() => {
|
||||
console.log('Play command sent');
|
||||
document.getElementById('startButton').style.display = 'none';
|
||||
// Aktiviere Buzzer
|
||||
for (let i = 1; i <= 4; i++) {
|
||||
document.getElementById(`buzzer${i}`).classList.remove('disabled');
|
||||
}
|
||||
canBuzz = true;
|
||||
})
|
||||
.catch(error => console.error('Error starting playback:', error));
|
||||
}
|
||||
|
||||
function startBuzzerTimer() {
|
||||
startTime = Date.now();
|
||||
canBuzz = true;
|
||||
updateTimer();
|
||||
}
|
||||
|
||||
function updateTimer() {
|
||||
if (currentBuzzer) return;
|
||||
if (!canBuzz && currentBuzzer) return;
|
||||
|
||||
const elapsed = (Date.now() - startTime) / 1000;
|
||||
const timerDisplay = document.getElementById('buzzerTimer');
|
||||
@@ -394,11 +404,11 @@
|
||||
return points;
|
||||
}
|
||||
|
||||
function buzz(playerId) {
|
||||
function triggerBuzz() {
|
||||
if (currentBuzzer !== null) return;
|
||||
if (!gameStarted || !startTime) return;
|
||||
if (!canBuzz) return;
|
||||
|
||||
currentBuzzer = playerId;
|
||||
canBuzz = false; // Verhindere weitere Buzzes
|
||||
buzzTime = Date.now();
|
||||
const elapsed = (buzzTime - startTime) / 1000;
|
||||
|
||||
@@ -408,17 +418,33 @@
|
||||
window.spotifyPlayer.pause();
|
||||
}
|
||||
|
||||
// Markiere Spieler
|
||||
document.getElementById(`player${playerId}`).classList.add('buzzed');
|
||||
document.getElementById('currentPlayer').textContent = `${players[playerId - 1].name} hat gebuzzert!`;
|
||||
|
||||
// Deaktiviere alle Buzzer
|
||||
for (let i = 1; i <= 4; i++) {
|
||||
document.getElementById(`buzzer${i}`).classList.add('disabled');
|
||||
// Zeige Spielerauswahl
|
||||
document.getElementById('playerSelection').style.display = 'block';
|
||||
document.getElementById('currentPlayer').textContent = 'Wer hat gebuzzert?';
|
||||
pendingPoints = calculatePoints(elapsed);
|
||||
}
|
||||
|
||||
function selectPlayer(playerId) {
|
||||
if (buzzedPlayers.includes(playerId)) {
|
||||
alert('Dieser Spieler hat bereits gebuzzert!');
|
||||
return;
|
||||
}
|
||||
|
||||
currentBuzzer = playerId;
|
||||
buzzedPlayers.push(playerId);
|
||||
|
||||
// Markiere Spieler
|
||||
document.getElementById(`player${playerId}`).classList.add('buzzed');
|
||||
document.getElementById('currentPlayer').textContent = `${players[playerId - 1].name} antwortet...`;
|
||||
|
||||
// Verstecke Spielerauswahl, zeige Antwortfeld
|
||||
document.getElementById('playerSelection').style.display = 'none';
|
||||
document.getElementById('answerSection').classList.add('active');
|
||||
window.earnedPoints = calculatePoints(elapsed);
|
||||
window.earnedPoints = pendingPoints;
|
||||
}
|
||||
|
||||
function buzz(playerId) {
|
||||
selectPlayer(playerId);
|
||||
}
|
||||
|
||||
function setCorrectAnswer() {
|
||||
@@ -486,6 +512,10 @@
|
||||
const guess = document.getElementById('answerInput').value;
|
||||
if (!guess) return;
|
||||
|
||||
// Disable input während Prüfung
|
||||
document.getElementById('answerInput').disabled = true;
|
||||
document.querySelector('button[onclick="checkAnswer()"]').disabled = true;
|
||||
|
||||
fetch('/check_answer_buzzer', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
@@ -495,7 +525,8 @@
|
||||
game_mode: currentGameMode,
|
||||
playlist_id: '{{ playlist_id }}',
|
||||
earned_points: window.earnedPoints,
|
||||
player_id: currentBuzzer
|
||||
player_id: currentBuzzer,
|
||||
apply_points: false // Punkte NICHT sofort anwenden
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
@@ -503,45 +534,95 @@
|
||||
const resultContainer = document.getElementById('resultContainer');
|
||||
|
||||
if (data.correct) {
|
||||
players[currentBuzzer - 1].score += window.earnedPoints;
|
||||
updateScoreboard();
|
||||
// Speichere Punkte, aber wende sie noch NICHT an
|
||||
pendingPoints = window.earnedPoints;
|
||||
|
||||
resultContainer.innerHTML = `
|
||||
<div style="background:linear-gradient(135deg, rgba(76, 175, 80, 0.2) 0%, rgba(56, 142, 60, 0.2) 100%); padding:20px; border-radius:12px; border:2px solid #4CAF50;">
|
||||
<h3 style="color:#4CAF50; margin-bottom:10px;">✅ ${i18n.correct || 'Correct'}</h3>
|
||||
<h3 style="color:#4CAF50; margin-bottom:10px;">✅ ${i18n.correct || 'Richtig'}</h3>
|
||||
<p style="font-size:1.5em; margin:10px 0;"><strong style="color:#1DB954;">+${window.earnedPoints}</strong> Punkte für ${players[currentBuzzer - 1].name}!</p>
|
||||
<div style="margin-top:20px; padding:20px; background:rgba(15,20,25,0.8); border-radius:12px;">
|
||||
<h4 style="color:#1DB954; margin-bottom:15px;">Song Info:</h4>
|
||||
<p style="margin:8px 0;"><strong style="color:#1DB954;">Titel:</strong> <span style="color:#e0e0e0;">{{ track.name | clean }}</span></p>
|
||||
<p style="margin:8px 0;"><strong style="color:#1DB954;">Künstler:</strong> <span style="color:#e0e0e0;">{{ track.artists[0].name | clean }}</span></p>
|
||||
<p style="margin:8px 0;"><strong style="color:#1DB954;">Album:</strong> <span style="color:#e0e0e0;">{{ track.album.name | clean }}</span></p>
|
||||
<a href="{{ track.external_urls.spotify }}" target="_blank" style="display:inline-block; margin-top:10px; padding:8px 16px; background:linear-gradient(135deg, #1DB954 0%, #1ed760 100%); color:#fff; text-decoration:none; border-radius:20px; font-weight:600;">Auf Spotify öffnen</a>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
document.getElementById('nextQuestionBtn').style.display = 'inline-block';
|
||||
document.getElementById('nextQuestionBtn').onclick = function() {
|
||||
// Wende Punkte beim Klick auf "Nächster Song" an
|
||||
players[currentBuzzer - 1].score += pendingPoints;
|
||||
updateScoreboard();
|
||||
window.location.href = '/quiz/{{ playlist_id }}?mode={{ game_mode }}&buzzer=1&local_multiplayer=1';
|
||||
};
|
||||
} else {
|
||||
// Minuspunkte: 25% der möglichen Punkte
|
||||
const minusPoints = Math.floor(window.earnedPoints * 0.25);
|
||||
pendingPoints = -minusPoints;
|
||||
|
||||
resultContainer.innerHTML = `
|
||||
<div style="background:linear-gradient(135deg, rgba(244, 67, 54, 0.2) 0%, rgba(211, 47, 47, 0.2) 100%); padding:20px; border-radius:12px; border:2px solid #f44336;">
|
||||
<h3 style="color:#f44336; margin-bottom:10px;">❌ ${i18n.incorrect || 'Incorrect'}</h3>
|
||||
<p style="font-size:1.1em; margin:10px 0;">${i18n.your_answer || 'Your answer'}: <strong style="color:#f44336;">${guess}</strong></p>
|
||||
<p style="font-size:1.1em; margin:10px 0;">${i18n.correct_answer || 'Correct answer'}: <strong style="color:#4CAF50;">${data.correct_answer}</strong></p>
|
||||
<h3 style="color:#f44336; margin-bottom:10px;">❌ Falsch</h3>
|
||||
<p style="font-size:1.1em; margin:10px 0;">Deine Antwort: <strong style="color:#f44336;">${guess}</strong></p>
|
||||
<p style="font-size:1.1em; margin:10px 0;"><strong style="color:#f44336;">-${minusPoints}</strong> Punkte für ${players[currentBuzzer - 1].name}</p>
|
||||
<div style="margin-top:20px;">
|
||||
<button class="btn" onclick="continueGame()" style="background:linear-gradient(135deg, #FFA500 0%, #FF8C00 100%);">🔄 Weiterbuzzern</button>
|
||||
<button class="btn" onclick="showSolution()" style="background:linear-gradient(135deg, #1DB954 0%, #1ed760 100%);">📝 Lösung anzeigen</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
if (data.comparison) {
|
||||
resultContainer.innerHTML += `
|
||||
<div style="margin-top:20px; padding:20px; background:rgba(15,20,25,0.8); border-radius:12px;">
|
||||
<h4 style="color:#1DB954; margin-bottom:15px;">${i18n.song_info || 'Song Info'}:</h4>
|
||||
<p style="margin:8px 0;"><strong style="color:#1DB954;">${i18n.title || 'Title'}:</strong> <span style="color:#e0e0e0;">{{ track.name | clean }}</span></p>
|
||||
<p style="margin:8px 0;"><strong style="color:#1DB954;">${i18n.artist || 'Artist'}:</strong> <span style="color:#e0e0e0;">{{ track.artists[0].name | clean }}</span></p>
|
||||
<p style="margin:8px 0;"><strong style="color:#1DB954;">${i18n.album || 'Album'}:</strong> <span style="color:#e0e0e0;">{{ track.album.name | clean }}</span></p>
|
||||
<p style="margin:8px 0;"><strong style="color:#1DB954;">${i18n.year || 'Year'}:</strong> <span style="color:#e0e0e0;">{{ track.album.release_date[:4] }}</span></p>
|
||||
<a href="{{ track.external_urls.spotify }}" target="_blank" style="display:inline-block; margin-top:10px; padding:8px 16px; background:linear-gradient(135deg, #1DB954 0%, #1ed760 100%); color:#fff; text-decoration:none; border-radius:20px; font-weight:600; transition:all 0.3s ease;">${i18n.open_on_spotify || 'Open on Spotify'}</a>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
document.getElementById('nextQuestionBtn').style.display = 'inline-block';
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error checking answer:', error);
|
||||
});
|
||||
}
|
||||
|
||||
function continueGame() {
|
||||
// Wende Minuspunkte an
|
||||
players[currentBuzzer - 1].score += pendingPoints;
|
||||
updateScoreboard();
|
||||
|
||||
// Reset für nächsten Buzzer
|
||||
document.getElementById('answerSection').classList.remove('active');
|
||||
document.getElementById('answerInput').value = '';
|
||||
document.getElementById('answerInput').disabled = false;
|
||||
document.querySelector('button[onclick="checkAnswer()"]').disabled = false;
|
||||
document.getElementById('resultContainer').innerHTML = '';
|
||||
document.getElementById(`player${currentBuzzer}`).classList.remove('buzzed');
|
||||
|
||||
currentBuzzer = null;
|
||||
canBuzz = true;
|
||||
|
||||
// Musik weiterspielen
|
||||
if (window.spotifyPlayer) {
|
||||
window.spotifyPlayer.resume();
|
||||
}
|
||||
|
||||
// Timer weiterlaufen lassen
|
||||
buzzTimer = requestAnimationFrame(updateTimer);
|
||||
}
|
||||
|
||||
function showSolution() {
|
||||
// Wende Minuspunkte an
|
||||
players[currentBuzzer - 1].score += pendingPoints;
|
||||
updateScoreboard();
|
||||
|
||||
const resultContainer = document.getElementById('resultContainer');
|
||||
resultContainer.innerHTML = `
|
||||
<div style="margin-top:20px; padding:20px; background:rgba(15,20,25,0.8); border-radius:12px; border:2px solid #1DB954;">
|
||||
<h4 style="color:#1DB954; margin-bottom:15px;">Lösung:</h4>
|
||||
<p style="margin:8px 0;"><strong style="color:#1DB954;">Titel:</strong> <span style="color:#e0e0e0;">{{ track.name | clean }}</span></p>
|
||||
<p style="margin:8px 0;"><strong style="color:#1DB954;">Künstler:</strong> <span style="color:#e0e0e0;">{{ track.artists[0].name | clean }}</span></p>
|
||||
<p style="margin:8px 0;"><strong style="color:#1DB954;">Album:</strong> <span style="color:#e0e0e0;">{{ track.album.name | clean }}</span></p>
|
||||
<a href="{{ track.external_urls.spotify }}" target="_blank" style="display:inline-block; margin-top:10px; padding:8px 16px; background:linear-gradient(135deg, #1DB954 0%, #1ed760 100%); color:#fff; text-decoration:none; border-radius:20px; font-weight:600;">Auf Spotify öffnen</a>
|
||||
</div>
|
||||
`;
|
||||
document.getElementById('nextQuestionBtn').style.display = 'inline-block';
|
||||
}
|
||||
|
||||
function switchGameMode(mode) {
|
||||
window.location.href = `/reset_quiz/{{ playlist_id }}?next_mode=${mode}&buzzer=1&local_multiplayer=1`;
|
||||
}
|
||||
@@ -592,23 +673,35 @@
|
||||
|
||||
<div class="current-player" id="currentPlayer">Drücke START um zu beginnen</div>
|
||||
|
||||
<!-- Buzzer Buttons -->
|
||||
<div class="buzzer-grid">
|
||||
<button class="player-buzzer start" id="startButton" onclick="startGame()">
|
||||
<!-- Buzzer Hint -->
|
||||
<div id="buzzerHint" style="text-align:center; font-size:1.5em; color:#1DB954; margin:20px 0; display:none;">
|
||||
⌨️ Drücke LEERTASTE zum Buzzern!
|
||||
</div>
|
||||
|
||||
<!-- Player Selection (versteckt bis gebuzzert) -->
|
||||
<div id="playerSelection" style="display:none; text-align:center; margin:30px 0;">
|
||||
<h3 style="margin-bottom:20px; color:#1DB954;">Wer hat gebuzzert?</h3>
|
||||
<div class="buzzer-grid">
|
||||
<button class="player-buzzer" id="selectPlayer1" onclick="selectPlayer(1)">
|
||||
Spieler 1
|
||||
</button>
|
||||
<button class="player-buzzer" id="selectPlayer2" onclick="selectPlayer(2)">
|
||||
Spieler 2
|
||||
</button>
|
||||
<button class="player-buzzer" id="selectPlayer3" onclick="selectPlayer(3)">
|
||||
Spieler 3
|
||||
</button>
|
||||
<button class="player-buzzer" id="selectPlayer4" onclick="selectPlayer(4)">
|
||||
Spieler 4
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- START Button -->
|
||||
<div style="text-align:center; margin:30px 0;">
|
||||
<button class="player-buzzer start" id="startButton" onclick="startGame()" style="width:300px; height:200px; font-size:2em;">
|
||||
▶️<br>START
|
||||
</button>
|
||||
<button class="player-buzzer disabled" id="buzzer1" onclick="buzz(1)">
|
||||
🔴<br>Spieler 1
|
||||
</button>
|
||||
<button class="player-buzzer disabled" id="buzzer2" onclick="buzz(2)">
|
||||
🔴<br>Spieler 2
|
||||
</button>
|
||||
<button class="player-buzzer disabled" id="buzzer3" onclick="buzz(3)">
|
||||
🔴<br>Spieler 3
|
||||
</button>
|
||||
<button class="player-buzzer disabled" id="buzzer4" onclick="buzz(4)">
|
||||
🔴<br>Spieler 4
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Answer Section -->
|
||||
|
||||
Reference in New Issue
Block a user