{score}`, width/2, 90);
textSize(65);
fill(20, 40, 20);
let displayOp = operator === ‚*‘ ? ‚x‘ : (operator === ‚/‘ ? ‚:‘ : operator);
if (isSignTask) {
let resultValue = calculate(num1, num2, operator);
text(`
{num2} =
{num1}
{num2} = ?`, width/2, height/2 – 20);
}
let btnW = 100, btnH = 75, gap = 15;
let totalW = options.length * btnW + (options.length – 1) * gap;
let startX = (width – totalW) / 2;
for (let i = 0; i < options.length; i++) {
let label = options[i];
if (isSignTask) {
if (label === '*') label = 'x';
if (label === '/') label = ':';
}
drawButtonUI(label, startX + i * (btnW + gap) + btnW/2, 450, btnW, btnH, color(255), 0, isSignTask ? 36 : 26);
}
}
function mousePressed() {
// Prehliadače často blokujú zvuk, kým používateľ neklikne na stránku
if (getAudioContext().state !== 'running') {
getAudioContext().resume();
}
if (state === "START") {
let opsKeys = ['+', '-', '*', '/'];
for (let i = 0; i < opsKeys.length; i++) {
let x = width / 2 - 75 + i * 50;
let y = 385;
if (dist(mouseX, mouseY, x, y) < 20) {
enabledOps[opsKeys[i]] = !enabledOps[opsKeys[i]];
return;
}
}
let names = [...new Set(leaderboard.map(i => i.name))].slice(0, 5);
for (let i = 0; i < names.length; i++) {
if (isOver(width/2, 130 + i * 40, 160, 30)) { tryStart(names[i]); return; }
}
if (isOver(width/2, 460, 200, 40)) {
let n = prompt("Meno:");
if (n) tryStart(n.trim());
}
if (isOver(width/2, 515, 200, 40)) state = "LEADERBOARD";
}
else if (state === "LEADERBOARD") {
if (isOver(width/2 - 110, height - 40, 150, 40)) state = "START";
if (isOver(width/2 + 110, height - 40, 150, 40)) {
if(confirm("Vymazať?")) { localStorage.removeItem('mathLeaderboard'); loadData(); }
}
}
else if (state === "PLAY") {
let btnW = 100, btnH = 75, gap = 15;
let totalW = options.length * btnW + (options.length - 1) * gap;
let startX = (width - totalW) / 2;
for (let i = 0; i < options.length; i++) {
let x = startX + i * (btnW + gap) + btnW/2;
if (isOver(x, 450, btnW, btnH)) { handleAnswer(options[i]); break; }
}
}
else if (state === "GAMEOVER") state = "START";
}
function handleAnswer(val) {
totalAttempts++;
if (val == correctAnswer) {
score += 2; correctAnswers++;
timer = min(timer + 2, maxTimer);
playClickSound(true); // Zvuk pre správnu odpoveď
generateProblem();
} else {
score = max(0, score - 1);
timer -= 1.5;
playClickSound(false); // Zvuk pre chybu
generateProblem();
}
}
// Zvyšné pomocné funkcie (loadData, generateProblem, calculate, tryStart, endGame, drawLeaderboard, drawGameOver, drawButtonUI, isOver) zostávajú rovnaké ako v predošlej verzii.
function loadData() {
let saved = localStorage.getItem('mathLeaderboard');
leaderboard = saved ? JSON.parse(saved) : [];
}
function generateProblem() {
taskCount++;
let currentMax = 10 + floor((taskCount - 1) / 40) * 10;
let allowed = Object.keys(enabledOps).filter(k => enabledOps[k]);
operator = random(allowed);
isSignTask = (taskCount > 40 && random() > 0.5);
if (operator === '+') {
num1 = floor(random(1, currentMax)); num2 = floor(random(1, currentMax));
correctAnswer = num1 + num2;
} else if (operator === '-') {
num1 = floor(random(1, currentMax)); num2 = floor(random(1, num1 + 1));
correctAnswer = num1 - num2;
} else if (operator === '*') {
num1 = floor(random(2, 10)); num2 = floor(random(2, 10));
correctAnswer = num1 * num2;
} else {
num2 = floor(random(2, 10)); correctAnswer = floor(random(1, 10));
num1 = num2 * correctAnswer;
}
if (isSignTask) {
correctAnswer = operator;
options = allowed;
} else {
let numOpt = (taskCount <= 10) ? 2 : (taskCount <= 25) ? 3 : 4;
options = [correctAnswer];
while (options.length < numOpt) {
let w = correctAnswer + floor(random(-5, 6));
if (w >= 0 && w !== correctAnswer && !options.includes(w)) options.push(w);
}
options.sort((a, b) => a - b);
}
}
function calculate(a, b, op) {
if (op === '+') return a + b;
if (op === '-') return a - b;
if (op === '*') return a * b;
if (op === '/') return a / b;
}
function tryStart(name) {
let anyEnabled = Object.values(enabledOps).some(v => v);
if (!anyEnabled) { alert("Musíš vybrať aspoň jednu operáciu!"); return; }
currentPlayer = name;
score = 0; correctAnswers = 0; totalAttempts = 0; taskCount = 0;
timer = 10; state = "PLAY"; lastMillis = millis();
generateProblem();
}
function endGame() {
state = "GAMEOVER";
let acc = totalAttempts > 0 ? round((correctAnswers / totalAttempts) * 100) : 0;
leaderboard.push({ name: currentPlayer, score: score, acc: acc });
leaderboard.sort((a, b) => b.score - a.score);
localStorage.setItem('mathLeaderboard', JSON.stringify(leaderboard));
}
function drawLeaderboard() {
fill(20, 60, 20); textSize(32);
text("REBRÍČEK", width / 2, 60);
textSize(18);
for (let i = 0; i < min(leaderboard.length, 10); i++) {
text(`
{leaderboard[i].name} –
{leaderboard[i].acc}%)`, width/2, 130 + i * 35);
}
drawButtonUI("SPÄŤ", width/2 – 110, height – 40, 150, 40, color(255), 0, 16);
drawButtonUI("VYMAZAŤ", width/2 + 110, height – 40, 150, 40, color(200, 50, 50), 255, 16);
}
function drawGameOver() {
fill(150, 0, 0); textSize(45);
text("KONIEC HRY", width / 2, height / 2 – 40);
fill(20, 50, 20); textSize(26);
text(`
{score} bodov`, width / 2, height / 2 + 15);
textSize(18);
text("Klikni pre menu", width / 2, height / 2 + 70);
}
function drawButtonUI(txt, x, y, w, h, bg, txC = 0, fSize = 18) {
push();
rectMode(CENTER);
fill(isOver(x, y, w, h) ? lerpColor(color(bg), color(0), 0.1) : bg);
stroke(60, 120, 60);
strokeWeight(2);
rect(x, y, w, h, 10);
noStroke();
fill(txC);
textSize(fSize);
text(txt, x, y + fSize/4);
pop();
}
function isOver(x, y, w, h) {
return mouseX > x – w/2 && mouseX < x + w/2 && mouseY > y - h/2 && mouseY < y + h/2;
}