<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chyť cíl!</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
min-height: 100vh;
font-family: "Segoe UI", system-ui, sans-serif;
background: #0a0a1a;
color: #e0e0e0;
overflow: hidden;
}
/* Herní menu */
.menu {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
background: linear-gradient(135deg, #0f0c29, #1a1a3e, #0f2027);
text-align: center;
padding: 2rem;
}
.menu h1 {
font-size: 3rem;
background: linear-gradient(to right, #00d4aa, #7b68ee, #ff6b9d);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin-bottom: 1rem;
}
.menu p { color: #8892a4; font-size: 1.1rem; margin-bottom: 2rem; max-width: 500px; }
.difficulty {
display: flex;
gap: 1rem;
margin-bottom: 2rem;
flex-wrap: wrap;
justify-content: center;
}
.diff-btn {
padding: 0.8rem 2rem;
border: 2px solid rgba(255,255,255,0.15);
border-radius: 12px;
background: rgba(255,255,255,0.05);
color: #e0e0e0;
font-size: 1rem;
cursor: pointer;
transition: all 0.3s;
font-weight: 600;
}
.diff-btn:hover { transform: scale(1.05); }
.diff-btn.easy { border-color: #00d4aa; color: #00d4aa; }
.diff-btn.easy:hover { background: rgba(0,212,170,0.2); }
.diff-btn.medium { border-color: #f59e0b; color: #f59e0b; }
.diff-btn.medium:hover { background: rgba(245,158,11,0.2); }
.diff-btn.hard { border-color: #ff6b9d; color: #ff6b9d; }
.diff-btn.hard:hover { background: rgba(255,107,157,0.2); }
.highscore { color: #7b68ee; font-size: 0.9rem; margin-top: 1rem; }
/* Herní plocha */
.game-area {
display: none;
width: 100vw;
height: 100vh;
position: relative;
background: #0a0a1a;
cursor: crosshair;
}
.hud {
position: absolute;
top: 0; left: 0; right: 0;
padding: 1rem 2rem;
display: flex;
justify-content: space-between;
align-items: center;
background: rgba(0,0,0,0.5);
backdrop-filter: blur(10px);
z-index: 10;
}
.hud-item {
font-size: 1.2rem;
font-weight: 600;
}
.hud-score { color: #00d4aa; }
.hud-time { color: #f59e0b; }
.hud-combo { color: #ff6b9d; }
.target {
position: absolute;
border-radius: 50%;
background: radial-gradient(circle, #ff6b9d, #ff1744);
box-shadow: 0 0 20px rgba(255,107,157,0.5), 0 0 40px rgba(255,107,157,0.2);
cursor: pointer;
transition: transform 0.1s;
z-index: 5;
}
.target::before {
content: "";
position: absolute;
top: 50%; left: 50%;
width: 30%;
height: 30%;
background: white;
border-radius: 50%;
transform: translate(-50%, -50%);
}
.target:active { transform: scale(0.9); }
.hit-effect {
position: absolute;
border-radius: 50%;
border: 2px solid #00d4aa;
animation: ripple 0.6s ease-out forwards;
pointer-events: none;
z-index: 4;
}
.score-popup {
position: absolute;
color: #00d4aa;
font-weight: 800;
font-size: 1.5rem;
animation: scoreFloat 0.8s ease-out forwards;
pointer-events: none;
z-index: 6;
}
.miss-effect {
position: absolute;
color: #ff6b9d;
font-size: 1.2rem;
animation: scoreFloat 0.5s ease-out forwards;
pointer-events: none;
z-index: 6;
}
@keyframes ripple {
from { width: 20px; height: 20px; opacity: 1; transform: translate(-50%, -50%); }
to { width: 100px; height: 100px; opacity: 0; transform: translate(-50%, -50%); }
}
@keyframes scoreFloat {
from { opacity: 1; transform: translateY(0); }
to { opacity: 0; transform: translateY(-50px); }
}
/* Konec hry */
.game-over {
display: none;
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(10,10,26,0.95);
z-index: 20;
align-items: center;
justify-content: center;
flex-direction: column;
text-align: center;
}
.game-over.show { display: flex; }
.final-score {
font-size: 5rem;
font-weight: 800;
background: linear-gradient(to right, #00d4aa, #7b68ee);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
animation: popIn 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.final-label { color: #8892a4; font-size: 1.2rem; margin-bottom: 0.5rem; }
.final-stats { color: #6b7280; margin: 1rem 0 2rem; }
.final-new { color: #f59e0b; font-weight: 600; margin-bottom: 1rem; font-size: 1.1rem; }
.play-again {
padding: 1rem 3rem;
background: linear-gradient(135deg, #00d4aa, #7b68ee);
color: white;
border: none;
border-radius: 12px;
font-size: 1.1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s;
}
.play-again:hover { transform: scale(1.1); }
.back-menu {
margin-top: 1rem;
padding: 0.6rem 1.5rem;
background: none;
border: 1px solid rgba(255,255,255,0.2);
color: #888;
border-radius: 10px;
cursor: pointer;
font-size: 0.9rem;
transition: all 0.3s;
}
.back-menu:hover { border-color: #fff; color: #fff; }
@keyframes popIn { from { transform: scale(0); } to { transform: scale(1); } }
</style>
</head>
<body>
<!-- MENU -->
<div class="menu" id="menu">
<h1>🎯 Chyť cíl!</h1>
<p>Klikej na červené cíle co nejrychleji! Máš 30 sekund. Kolik bodů zvládneš?</p>
<div class="difficulty">
<button class="diff-btn easy" onclick="startGame('easy')">🟢 Snadné</button>
<button class="diff-btn medium" onclick="startGame('medium')">🟡 Střední</button>
<button class="diff-btn hard" onclick="startGame('hard')">🔴 Těžké</button>
</div>
<div class="highscore" id="highscoreDisplay"></div>
</div>
<!-- HERNÍ PLOCHA -->
<div class="game-area" id="gameArea" onclick="handleMiss(event)">
<div class="hud">
<div class="hud-item hud-score" id="hudScore">🎯 0</div>
<div class="hud-item hud-combo" id="hudCombo"></div>
<div class="hud-item hud-time" id="hudTime">⏱ 30s</div>
</div>
</div>
<!-- KONEC HRY -->
<div class="game-over" id="gameOver">
<div class="final-label">Konečné skóre</div>
<div class="final-score" id="finalScore">0</div>
<div class="final-new" id="finalNew" style="display:none">🏆 Nový rekord!</div>
<div class="final-stats" id="finalStats"></div>
<button class="play-again" onclick="restartGame()">🔄 Hrát znovu</button>
<button class="back-menu" onclick="backToMenu()">← Menu</button>
</div>
<script>
let score = 0, timeLeft = 30, combo = 0, maxCombo = 0, hits = 0, misses = 0;
let difficulty = "easy";
let gameInterval, targetTimeout, currentTarget;
const sizes = { easy: 70, medium: 50, hard: 30 };
const speeds = { easy: 1500, medium: 1000, hard: 700 };
function getHighscores() {
try { return JSON.parse(localStorage.getItem("targetgame_hs") || "{}"); }
catch { return {}; }
}
function showHighscores() {
const hs = getHighscores();
const parts = [];
if (hs.easy) parts.push("Snadné: " + hs.easy);
if (hs.medium) parts.push("Střední: " + hs.medium);
if (hs.hard) parts.push("Těžké: " + hs.hard);
document.getElementById("highscoreDisplay").textContent = parts.length ? "🏆 " + parts.join(" | ") : "";
}
showHighscores();
function startGame(diff) {
difficulty = diff;
score = 0; timeLeft = 30; combo = 0; maxCombo = 0; hits = 0; misses = 0;
document.getElementById("menu").style.display = "none";
document.getElementById("gameArea").style.display = "block";
document.getElementById("gameOver").classList.remove("show");
updateHUD();
spawnTarget();
gameInterval = setInterval(() => {
timeLeft--;
updateHUD();
if (timeLeft <= 0) endGame();
}, 1000);
}
function updateHUD() {
document.getElementById("hudScore").textContent = "🎯 " + score;
document.getElementById("hudTime").textContent = "⏱ " + timeLeft + "s";
document.getElementById("hudCombo").textContent = combo > 1 ? "🔥 x" + combo : "";
}
function spawnTarget() {
if (currentTarget) currentTarget.remove();
const size = sizes[difficulty];
const area = document.getElementById("gameArea");
const maxX = area.clientWidth - size - 20;
const maxY = area.clientHeight - size - 70;
const x = Math.random() * maxX + 10;
const y = Math.random() * maxY + 60;
const target = document.createElement("div");
target.className = "target";
target.style.width = size + "px";
target.style.height = size + "px";
target.style.left = x + "px";
target.style.top = y + "px";
target.onclick = function(e) {
e.stopPropagation();
hitTarget(this);
};
area.appendChild(target);
currentTarget = target;
targetTimeout = setTimeout(() => {
if (currentTarget === target) {
combo = 0;
spawnTarget();
}
}, speeds[difficulty] + 500);
}
function hitTarget(target) {
hits++;
combo++;
if (combo > maxCombo) maxCombo = combo;
const points = 10 * combo;
score += points;
const rect = target.getBoundingClientRect();
const cx = rect.left + rect.width / 2;
const cy = rect.top + rect.height / 2;
// Efekt zásahu
const ripple = document.createElement("div");
ripple.className = "hit-effect";
ripple.style.left = cx + "px";
ripple.style.top = cy + "px";
document.getElementById("gameArea").appendChild(ripple);
setTimeout(() => ripple.remove(), 600);
// Bodový popup
const popup = document.createElement("div");
popup.className = "score-popup";
popup.textContent = "+" + points + (combo > 1 ? " (x" + combo + ")" : "");
popup.style.left = cx + "px";
popup.style.top = (cy - 20) + "px";
document.getElementById("gameArea").appendChild(popup);
setTimeout(() => popup.remove(), 800);
clearTimeout(targetTimeout);
target.remove();
currentTarget = null;
updateHUD();
setTimeout(spawnTarget, 100);
}
function handleMiss(e) {
if (e.target.classList.contains("target")) return;
misses++;
combo = 0;
updateHUD();
const miss = document.createElement("div");
miss.className = "miss-effect";
miss.textContent = "Vedle!";
miss.style.left = e.clientX + "px";
miss.style.top = e.clientY + "px";
document.getElementById("gameArea").appendChild(miss);
setTimeout(() => miss.remove(), 500);
}
function endGame() {
clearInterval(gameInterval);
clearTimeout(targetTimeout);
if (currentTarget) currentTarget.remove();
document.getElementById("finalScore").textContent = score;
const accuracy = hits + misses > 0 ? Math.round(hits / (hits + misses) * 100) : 0;
document.getElementById("finalStats").innerHTML =
"Zásahy: " + hits + " | Vedle: " + misses +
" | Přesnost: " + accuracy + "%" +
" | Max combo: x" + maxCombo;
const hs = getHighscores();
const isNew = !hs[difficulty] || score > hs[difficulty];
if (isNew && score > 0) {
hs[difficulty] = score;
localStorage.setItem("targetgame_hs", JSON.stringify(hs));
}
document.getElementById("finalNew").style.display = isNew && score > 0 ? "block" : "none";
document.getElementById("gameOver").classList.add("show");
}
function restartGame() { startGame(difficulty); }
function backToMenu() {
document.getElementById("gameArea").style.display = "none";
document.getElementById("gameOver").classList.remove("show");
document.getElementById("menu").style.display = "flex";
showHighscores();
}
</script>
</body>
</html>