• 29-04-2026, 13:30:33
    #10
    Birazda ben geliştirdim elinize sağlık
    <!DOCTYPE html>
    <html lang="tr">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
        <title>Dart Arrow</title>
        <style>
            * {
                box-sizing: border-box;
                user-select: none;
                -webkit-user-select: none;
                -webkit-tap-highlight-color: transparent;
            }
    
            :root {
                --bg: #eef0f3;
                --panel: rgba(255, 255, 255, 0.88);
                --ink: #111318;
                --muted: #69707d;
                --line: rgba(17, 19, 24, 0.12);
                --accent: #0f8f72;
                --danger: #d94444;
                --gold: #d99b19;
                --shadow: 0 20px 55px rgba(24, 29, 38, 0.18);
            }
    
            body.dark {
                --bg: #171a21;
                --panel: rgba(31, 35, 44, 0.92);
                --ink: #f5f6f8;
                --muted: #aeb5c2;
                --line: rgba(245, 246, 248, 0.14);
                --accent: #26c6a2;
                --danger: #ff6b6b;
                --gold: #ffc247;
                --shadow: 0 20px 55px rgba(0, 0, 0, 0.35);
            }
    
            html,
            body {
                margin: 0;
                padding: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
                font-family: Arial, Helvetica, sans-serif;
                background: radial-gradient(circle at 50% 10%, #ffffff 0, var(--bg) 58%);
                color: var(--ink);
                touch-action: none;
            }
    
            body.dark {
                background: radial-gradient(circle at 50% 10%, #2b303b 0, var(--bg) 58%);
            }
    
            #gameContainer {
                position: relative;
                width: 100%;
                max-width: 460px;
                height: 100%;
                max-height: 820px;
                margin: 0 auto;
                overflow: hidden;
                background: var(--bg);
                box-shadow: var(--shadow);
            }
    
            canvas {
                display: block;
                width: 100%;
                height: 100%;
            }
    
            #topBar {
                position: absolute;
                top: 14px;
                left: 14px;
                right: 14px;
                z-index: 4;
                display: flex;
                align-items: flex-start;
                justify-content: space-between;
                gap: 10px;
                pointer-events: none;
            }
    
            .stats {
                display: flex;
                flex-wrap: wrap;
                gap: 8px;
                min-width: 0;
            }
    
            .pill {
                min-width: 62px;
                padding: 7px 10px;
                border: 1px solid var(--line);
                border-radius: 8px;
                background: var(--panel);
                color: var(--ink);
                box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
                backdrop-filter: blur(10px);
                font-size: 11px;
                font-weight: 700;
                line-height: 1.15;
                letter-spacing: 0;
            }
    
            .pill span {
                display: block;
                margin-top: 3px;
                font-size: 18px;
            }
    
            .iconRow {
                display: flex;
                gap: 8px;
                pointer-events: auto;
            }
    
            .iconBtn {
                width: 40px;
                height: 40px;
                display: grid;
                place-items: center;
                border: 1px solid var(--line);
                border-radius: 8px;
                background: var(--panel);
                color: var(--ink);
                box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
                cursor: pointer;
                font-size: 18px;
            }
    
            .overlay {
                position: absolute;
                inset: 0;
                z-index: 8;
                display: none;
                align-items: center;
                justify-content: center;
                padding: 22px;
                background: rgba(238, 240, 243, 0.72);
                backdrop-filter: blur(12px);
            }
    
            body.dark .overlay {
                background: rgba(23, 26, 33, 0.72);
            }
    
            .overlay.show {
                display: flex;
            }
    
            .panel {
                width: min(100%, 390px);
                padding: 22px;
                border: 1px solid var(--line);
                border-radius: 8px;
                background: var(--panel);
                box-shadow: var(--shadow);
            }
    
            .title {
                margin: 0 0 6px;
                font-size: 40px;
                line-height: 1;
                letter-spacing: 0;
            }
    
            .subtitle {
                margin: 0 0 18px;
                color: var(--muted);
                font-size: 14px;
                line-height: 1.35;
            }
    
            .menuGrid {
                display: grid;
                grid-template-columns: 1fr 1fr;
                gap: 10px;
                margin: 12px 0;
            }
    
            .wide {
                grid-column: 1 / -1;
            }
    
            .btn {
                width: 100%;
                min-height: 48px;
                padding: 12px 14px;
                border: 1px solid transparent;
                border-radius: 8px;
                background: var(--ink);
                color: var(--bg);
                cursor: pointer;
                font-size: 15px;
                font-weight: 700;
            }
    
            .btn.secondary {
                border-color: var(--line);
                background: transparent;
                color: var(--ink);
            }
    
            .btn.accent {
                background: var(--accent);
                color: #ffffff;
            }
    
            .btn:active,
            .iconBtn:active {
                transform: scale(0.97);
            }
    
            .setting {
                display: flex;
                align-items: center;
                justify-content: space-between;
                gap: 12px;
                padding: 12px 0;
                border-top: 1px solid var(--line);
                font-size: 14px;
                font-weight: 700;
            }
    
            .setting small {
                display: block;
                margin-top: 3px;
                color: var(--muted);
                font-size: 12px;
                font-weight: 400;
            }
    
            .switch {
                position: relative;
                width: 48px;
                height: 28px;
                flex: 0 0 auto;
            }
    
            .switch input {
                display: none;
            }
    
            .slider {
                position: absolute;
                inset: 0;
                border-radius: 999px;
                background: #adb3bd;
                cursor: pointer;
            }
    
            .slider::after {
                content: "";
                position: absolute;
                width: 22px;
                height: 22px;
                top: 3px;
                left: 3px;
                border-radius: 50%;
                background: #ffffff;
                transition: transform 0.18s;
            }
    
            .switch input:checked + .slider {
                background: var(--accent);
            }
    
            .switch input:checked + .slider::after {
                transform: translateX(20px);
            }
    
            #messageTitle {
                margin: 0 0 8px;
                font-size: 36px;
                line-height: 1.05;
            }
    
            #messageDetail {
                margin: 0 0 18px;
                color: var(--muted);
                line-height: 1.35;
            }
    
            #countdown {
                position: absolute;
                inset: 0;
                z-index: 7;
                display: none;
                align-items: center;
                justify-content: center;
                font-size: 96px;
                font-weight: 900;
                color: var(--ink);
                text-shadow: 0 8px 30px rgba(0, 0, 0, 0.16);
                pointer-events: none;
            }
    
            #countdown.show {
                display: flex;
                animation: pop 0.35s ease;
            }
    
            @keyframes pop {
                from { transform: scale(0.7); opacity: 0; }
                to { transform: scale(1); opacity: 1; }
            }
    
            @media (max-width: 360px) {
                .title { font-size: 34px; }
                .pill { min-width: 56px; padding: 6px 8px; }
                .pill span { font-size: 16px; }
                .iconBtn { width: 36px; height: 36px; }
            }
        </style>
    </head>
    <body>
    <div id="gameContainer">
        <canvas id="gameCanvas"></canvas>
    
        <div id="topBar">
            <div class="stats">
                <div class="pill">SEVİYE<span id="levelDisplay">1</span></div>
                <div class="pill">REKOR<span id="bestDisplay">1</span></div>
                <div class="pill">MOD<span id="modeDisplay">Klasik</span></div>
            </div>
            <div class="iconRow">
                <button class="iconBtn" id="pauseBtn" title="Duraklat">⏸</button>
                <button class="iconBtn" id="restartBtn" title="Yeniden başlat">↻</button>
            </div>
        </div>
    
        <div id="countdown">3</div>
    
        <div class="overlay show" id="menuOverlay">
            <div class="panel">
                <h1 class="title">Dart Arrow</h1>
                <p class="subtitle">Doğru anda ateş et, çarpışmadan tüm iğneleri hedefe yerleştir.</p>
                <div class="menuGrid">
                    <button class="btn accent wide" id="continueBtn">Devam Et</button>
                    <button class="btn" data-mode="classic">Klasik</button>
                    <button class="btn secondary" data-mode="endless">Sonsuz</button>
                    <button class="btn secondary" data-mode="timed">Zamanlı</button>
                    <button class="btn secondary" data-mode="hard">Zor</button>
                </div>
                <div class="setting">
                    <div>Ses<small>Atış, başarı ve çarpışma sesleri</small></div>
                    <label class="switch">
                        <input type="checkbox" id="soundToggle" checked>
                        <span class="slider"></span>
                    </label>
                </div>
                <div class="setting">
                    <div>Titreşim<small>Destekleyen telefonlarda dokunsal geri bildirim</small></div>
                    <label class="switch">
                        <input type="checkbox" id="vibrationToggle" checked>
                        <span class="slider"></span>
                    </label>
                </div>
                <div class="setting">
                    <div>Karanlık Tema<small>Düşük ışıkta daha rahat oyun</small></div>
                    <label class="switch">
                        <input type="checkbox" id="themeToggle">
                        <span class="slider"></span>
                    </label>
                </div>
            </div>
        </div>
    
        <div class="overlay" id="messageOverlay">
            <div class="panel">
                <h2 id="messageTitle">Yandın!</h2>
                <p id="messageDetail">Aynı noktaya denk geldi.</p>
                <div class="menuGrid">
                    <button class="btn accent wide" id="primaryActionBtn">Tekrar Dene</button>
                    <button class="btn secondary" id="menuBtn">Menü</button>
                    <button class="btn secondary" id="nextActionBtn">Sonraki Seviye</button>
                </div>
            </div>
        </div>
    </div>
    
    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const levelDisplay = document.getElementById('levelDisplay');
        const bestDisplay = document.getElementById('bestDisplay');
        const modeDisplay = document.getElementById('modeDisplay');
        const menuOverlay = document.getElementById('menuOverlay');
        const messageOverlay = document.getElementById('messageOverlay');
        const messageTitle = document.getElementById('messageTitle');
        const messageDetail = document.getElementById('messageDetail');
        const primaryActionBtn = document.getElementById('primaryActionBtn');
        const nextActionBtn = document.getElementById('nextActionBtn');
        const menuBtn = document.getElementById('menuBtn');
        const pauseBtn = document.getElementById('pauseBtn');
        const restartBtn = document.getElementById('restartBtn');
        const continueBtn = document.getElementById('continueBtn');
        const countdownEl = document.getElementById('countdown');
        const soundToggle = document.getElementById('soundToggle');
        const vibrationToggle = document.getElementById('vibrationToggle');
        const themeToggle = document.getElementById('themeToggle');
    
        const TAU = Math.PI * 2;
        const maxLevel = 1200;
        const storageKey = 'dartArrowSaveV2';
        const modes = {
            classic: 'Klasik',
            endless: 'Sonsuz',
            timed: 'Zamanlı',
            hard: 'Zor'
        };
    
        let state = loadState();
        let gameState = 'MENU';
        let targetAngle = 0;
        let targetSpeed = 0.02;
        let targetRadius = 50;
        let pinRadius = 12;
        let pinLineLength = 138;
        let bulletSpeed = 25;
        let startingBulletsCount = 0;
        let timer = 0;
        let levelStartedAt = 0;
        let pausedRemainingTime = 0;
        let lastTime = performance.now();
        let pins = [];
        let bullets = [];
        let activeBullet = null;
        let particles = [];
        let flash = null;
        let audioCtx = null;
        let countdownToken = 0;
    
        function loadState() {
            const fallback = {
                level: 1,
                best: 1,
                mode: 'classic',
                sound: true,
                vibration: true,
                dark: false
            };
    
            try {
                return { ...fallback, ...JSON.parse(localStorage.getItem(storageKey) || '{}') };
            } catch (error) {
                return fallback;
            }
        }
    
        function saveState() {
            localStorage.setItem(storageKey, JSON.stringify(state));
        }
    
        function resizeCanvas() {
            const dpr = Math.max(1, Math.min(window.devicePixelRatio || 1, 2));
            const rect = canvas.parentElement.getBoundingClientRect();
            canvas.width = Math.floor(rect.width * dpr);
            canvas.height = Math.floor(rect.height * dpr);
            ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
            canvas.logicalWidth = rect.width;
            canvas.logicalHeight = rect.height;
            pinLineLength = Math.max(105, Math.min(145, rect.height * 0.18));
            targetRadius = Math.max(42, Math.min(54, rect.width * 0.115));
        }
    
        function updateHud() {
            levelDisplay.textContent = state.level;
            bestDisplay.textContent = state.best;
            modeDisplay.textContent = modes[state.mode];
            soundToggle.checked = state.sound;
            vibrationToggle.checked = state.vibration;
            themeToggle.checked = state.dark;
            document.body.classList.toggle('dark', state.dark);
            continueBtn.textContent = state.best > 1 ? 'Devam Et - Seviye ' + state.level : 'Başla';
            saveState();
        }
    
        function getDifficulty() {
            const level = state.mode === 'endless' ? Math.min(state.level, 2000) : state.level;
            const curve = Math.log2(level + 1);
            const hardBoost = state.mode === 'hard' ? 1.35 : 1;
            const timedBoost = state.mode === 'timed' ? 1.12 : 1;
            const speedBase = 0.010 + curve * 0.0042;
            const speedWave = Math.sin(level * 0.73) * 0.006;
            const speed = Math.min(0.09, (speedBase + speedWave) * hardBoost * timedBoost);
            const initialPins = Math.min(state.mode === 'hard' ? 13 : 11, 2 + Math.floor(level / 5) + Math.floor(curve / 2));
            const bulletsCount = Math.min(state.mode === 'hard' ? 30 : 26, 5 + Math.floor(level / 3) + (level % 4 === 0 ? 2 : 0));
            const direction = level % 3 === 0 ? -1 : 1;
            const wobble = level >= 8 || state.mode !== 'classic';
            const stopGo = level >= 14 || state.mode === 'hard';
            const timeLimit = state.mode === 'timed' ? Math.max(7, 16 - Math.floor(level / 12)) : 0;
    
            return {
                speed: speed * direction,
                initialPins,
                bulletsCount,
                wobble,
                stopGo,
                timeLimit
            };
        }
    
        function initLevel(skipCountdown = false) {
            resizeCanvas();
            const difficulty = getDifficulty();
            targetAngle = 0;
            targetSpeed = difficulty.speed;
            startingBulletsCount = difficulty.bulletsCount;
            timer = difficulty.timeLimit;
            pausedRemainingTime = timer;
            levelStartedAt = performance.now();
            pins = [];
            bullets = [];
            activeBullet = null;
            particles = [];
            flash = null;
    
            const jitter = state.mode === 'classic' && state.level < 5 ? 0 : 0.18;
            for (let i = 0; i < difficulty.initialPins; i++) {
                const offset = Math.sin((state.level + i) * 1.77) * jitter;
                pins.push({
                    angle: normalize((TAU / difficulty.initialPins) * i + offset),
                    num: ''
                });
            }
    
            for (let i = startingBulletsCount; i > 0; i--) {
                bullets.push(i);
            }
    
            gameState = skipCountdown ? 'PLAYING' : 'COUNTDOWN';
            menuOverlay.classList.remove('show');
            messageOverlay.classList.remove('show');
            updateHud();
    
            if (skipCountdown) {
                return;
            }
    
            runCountdown();
        }
    
        function runCountdown() {
            const token = ++countdownToken;
            let count = 3;
            countdownEl.textContent = count;
            countdownEl.classList.add('show');
            tone(520, 0.06, 'sine', 0.04);
    
            const tick = () => {
                if (token !== countdownToken || gameState !== 'COUNTDOWN') return;
                count--;
                if (count > 0) {
                    countdownEl.textContent = count;
                    countdownEl.classList.remove('show');
                    void countdownEl.offsetWidth;
                    countdownEl.classList.add('show');
                    tone(520 + count * 50, 0.06, 'sine', 0.04);
                    setTimeout(tick, 650);
                } else {
                    countdownEl.textContent = 'GO';
                    countdownEl.classList.remove('show');
                    void countdownEl.offsetWidth;
                    countdownEl.classList.add('show');
                    tone(760, 0.1, 'triangle', 0.05);
                    setTimeout(() => {
                        if (token === countdownToken) {
                            countdownEl.classList.remove('show');
                            gameState = 'PLAYING';
                            levelStartedAt = performance.now();
                        }
                    }, 450);
                }
            };
    
            setTimeout(tick, 650);
        }
    
        function normalize(angle) {
            return (angle % TAU + TAU) % TAU;
        }
    
        function draw() {
            const width = canvas.logicalWidth || canvas.width;
            const height = canvas.logicalHeight || canvas.height;
            const cx = width / 2;
            const cy = height * 0.36;
            const remaining = bullets.length + (activeBullet ? 1 : 0);
    
            ctx.clearRect(0, 0, width, height);
            drawBackground(width, height);
            drawTarget(cx, cy, remaining);
            drawActiveBullet(cx);
            drawQueue(cx, height);
            drawParticles();
            drawPrompts(cx, height);
    
            if (flash) {
                ctx.fillStyle = flash.color;
                ctx.globalAlpha = Math.max(0, flash.life);
                ctx.fillRect(0, 0, width, height);
                ctx.globalAlpha = 1;
            }
        }
    
        function drawBackground(width, height) {
            const gradient = ctx.createLinearGradient(0, 0, 0, height);
            if (document.body.classList.contains('dark')) {
                gradient.addColorStop(0, '#252a33');
                gradient.addColorStop(1, '#171a21');
            } else {
                gradient.addColorStop(0, '#fbfbfc');
                gradient.addColorStop(1, '#e8ebef');
            }
            ctx.fillStyle = gradient;
            ctx.fillRect(0, 0, width, height);
    
            ctx.strokeStyle = document.body.classList.contains('dark') ? 'rgba(255,255,255,0.035)' : 'rgba(0,0,0,0.035)';
            ctx.lineWidth = 1;
            for (let y = 95; y < height; y += 44) {
                ctx.beginPath();
                ctx.moveTo(0, y);
                ctx.lineTo(width, y);
                ctx.stroke();
            }
        }
    
        function drawTarget(cx, cy, remaining) {
            const ink = getInk();
            ctx.save();
            ctx.translate(cx, cy);
            ctx.rotate(targetAngle);
    
            pins.forEach(pin => {
                const px = Math.cos(pin.angle) * pinLineLength;
                const py = Math.sin(pin.angle) * pinLineLength;
                ctx.beginPath();
                ctx.moveTo(0, 0);
                ctx.lineTo(px, py);
                ctx.strokeStyle = ink;
                ctx.lineWidth = 2;
                ctx.stroke();
    
                ctx.beginPath();
                ctx.arc(px, py, pinRadius, 0, TAU);
                ctx.fillStyle = ink;
                ctx.fill();
    
                if (pin.num !== '') {
                    ctx.save();
                    ctx.translate(px, py);
                    ctx.rotate(-targetAngle);
                    drawSmallNumber(pin.num, 0, 1);
                    ctx.restore();
                }
            });
    
            ctx.beginPath();
            ctx.arc(0, 0, targetRadius + 4, 0, TAU);
            ctx.fillStyle = state.mode === 'hard' ? '#d94444' : state.mode === 'timed' ? '#d99b19' : ink;
            ctx.fill();
    
            ctx.beginPath();
            ctx.arc(0, 0, targetRadius - 7, 0, TAU);
            ctx.fillStyle = ink;
            ctx.fill();
    
            ctx.rotate(-targetAngle);
            ctx.fillStyle = '#ffffff';
            ctx.font = '900 ' + (remaining >= 100 ? 32 : 44) + 'px Arial';
            ctx.textAlign = 'center';
            ctx.textBaseline = 'middle';
            ctx.fillText(remaining, 0, 2);
            ctx.restore();
        }
    
        function drawActiveBullet(cx) {
            if (!activeBullet) return;
            const ink = getInk();
            ctx.beginPath();
            ctx.moveTo(cx, activeBullet.y);
            ctx.lineTo(cx, activeBullet.y + 22);
            ctx.strokeStyle = ink;
            ctx.lineWidth = 2;
            ctx.stroke();
    
            ctx.beginPath();
            ctx.arc(cx, activeBullet.y, pinRadius, 0, TAU);
            ctx.fillStyle = ink;
            ctx.fill();
            drawSmallNumber(activeBullet.num, cx, activeBullet.y + 1);
        }
    
        function drawQueue(cx, height) {
            const ink = getInk();
            const bulletStartY = height * 0.74;
            const spacing = pinRadius * 2.35;
            const showCount = Math.min(7, bullets.length);
    
            for (let i = 0; i < showCount; i++) {
                const by = bulletStartY + (i * spacing);
                ctx.beginPath();
                ctx.arc(cx, by, pinRadius, 0, TAU);
                ctx.fillStyle = ink;
                ctx.fill();
                drawSmallNumber(bullets[bullets.length - 1 - i], cx, by + 1);
            }
    
            if (bullets.length > showCount) {
                ctx.fillStyle = getMuted();
                ctx.font = 'bold 13px Arial';
                ctx.textAlign = 'center';
                ctx.textBaseline = 'middle';
                ctx.fillText('+' + (bullets.length - showCount), cx, bulletStartY + showCount * spacing + 4);
            }
        }
    
        function drawSmallNumber(text, x, y) {
            ctx.fillStyle = '#ffffff';
            ctx.font = 'bold 12px Arial';
            ctx.textAlign = 'center';
            ctx.textBaseline = 'middle';
            ctx.fillText(text, x, y);
        }
    
        function drawPrompts(cx, height) {
            if (gameState === 'PLAYING' && bullets.length === startingBulletsCount && !activeBullet) {
                ctx.fillStyle = getMuted();
                ctx.font = 'bold 20px Arial';
                ctx.textAlign = 'center';
                ctx.fillText('Ateş etmek için dokun', cx, height * 0.62);
            }
    
            if (gameState === 'PAUSED') {
                ctx.fillStyle = 'rgba(0,0,0,0.35)';
                ctx.fillRect(0, 0, canvas.logicalWidth, canvas.logicalHeight);
                ctx.fillStyle = '#ffffff';
                ctx.font = '900 42px Arial';
                ctx.textAlign = 'center';
                ctx.fillText('DURAKLATILDI', canvas.logicalWidth / 2, canvas.logicalHeight / 2);
            }
    
            if (state.mode === 'timed' && gameState === 'PLAYING') {
                const timeLeft = Math.max(0, timer - (performance.now() - levelStartedAt) / 1000);
                ctx.fillStyle = timeLeft <= 3 ? '#d94444' : getInk();
                ctx.font = '900 18px Arial';
                ctx.textAlign = 'right';
                ctx.fillText(timeLeft.toFixed(1), canvas.logicalWidth - 18, 96);
            }
        }
    
        function drawParticles() {
            particles.forEach(p => {
                ctx.globalAlpha = Math.max(0, p.life);
                ctx.beginPath();
                ctx.arc(p.x, p.y, p.size, 0, TAU);
                ctx.fillStyle = p.color;
                ctx.fill();
            });
            ctx.globalAlpha = 1;
        }
    
        function update(now) {
            const dt = Math.min(32, now - lastTime);
            lastTime = now;
    
            updateParticles(dt);
            if (flash) {
                flash.life -= dt / 220;
                if (flash.life <= 0) flash = null;
            }
    
            if (gameState !== 'PLAYING') return;
    
            const difficulty = getDifficulty();
            const elapsed = (now - levelStartedAt) / 1000;
            let speedMultiplier = 1;
            if (difficulty.wobble) speedMultiplier += Math.sin(elapsed * 2.4) * 0.28;
            if (difficulty.stopGo && Math.sin(elapsed * 1.35) > 0.72) speedMultiplier = 0.18;
            targetAngle += targetSpeed * speedMultiplier * (dt / 16.67);
    
            if (state.mode === 'timed' && elapsed >= timer) {
                fail('Süre Bitti!', 'Bu seviyede daha hızlı ateş etmelisin.');
                return;
            }
    
            if (!activeBullet) return;
    
            activeBullet.y -= bulletSpeed * (dt / 16.67);
            const cy = canvas.logicalHeight * 0.36;
    
            if (activeBullet.y <= cy + pinLineLength) {
                let hitAngle = normalize((Math.PI / 2) - targetAngle);
                let collision = false;
    
                for (let i = 0; i < pins.length; i++) {
                    let pinAngle = normalize(pins[i].angle);
                    let diff = Math.abs(hitAngle - pinAngle);
                    if (diff > Math.PI) diff = TAU - diff;
    
                    const distance = 2 * pinLineLength * Math.sin(diff / 2);
                    if (distance < pinRadius * 2 + 2) {
                        collision = true;
                        break;
                    }
                }
    
                if (collision) {
                    fail('Yandın!', 'İğne başka bir iğneye çarptı.');
                } else {
                    pins.push({ angle: hitAngle, num: activeBullet.num });
                    burst(canvas.logicalWidth / 2, cy + pinLineLength, getAccent(), 8);
                    activeBullet = null;
                    tone(420, 0.045, 'triangle', 0.035);
    
                    if (bullets.length === 0) {
                        success();
                    }
                }
            }
        }
    
        function updateParticles(dt) {
            particles = particles.filter(p => {
                p.x += p.vx * dt;
                p.y += p.vy * dt;
                p.vy += 0.0009 * dt;
                p.life -= dt / p.decay;
                return p.life > 0;
            });
        }
    
        function shoot(event) {
            if (event) event.preventDefault();
            if (gameState === 'COUNTDOWN') return;
            if (gameState === 'PAUSED') {
                resumeGame();
                return;
            }
            if (gameState !== 'PLAYING' || activeBullet || bullets.length === 0) return;
    
            const num = bullets.pop();
            activeBullet = {
                y: canvas.logicalHeight * 0.74,
                num
            };
            tone(260, 0.055, 'square', 0.025);
            vibrate(12);
        }
    
        function fail(title, detail) {
            gameState = 'GAMEOVER';
            activeBullet = null;
            flash = { color: 'rgba(217, 68, 68, 0.42)', life: 1 };
            burst(canvas.logicalWidth / 2, canvas.logicalHeight * 0.36, '#d94444', 24);
            tone(120, 0.22, 'sawtooth', 0.05);
            vibrate([50, 30, 80]);
            showMessage(title, detail, false);
        }
    
        function success() {
            gameState = 'SUCCESS';
            flash = { color: 'rgba(15, 143, 114, 0.32)', life: 1 };
            burst(canvas.logicalWidth / 2, canvas.logicalHeight * 0.36, getAccent(), 34);
            tone(620, 0.08, 'triangle', 0.04);
            setTimeout(() => tone(820, 0.11, 'triangle', 0.035), 85);
            vibrate(35);
    
            if (state.mode === 'classic' || state.mode === 'timed' || state.mode === 'hard') {
                state.level = Math.min(maxLevel, state.level + 1);
            } else {
                state.level++;
            }
    
            state.best = Math.max(state.best, state.level);
            updateHud();
            showMessage('Harika!', 'Seviye tamamlandı. Yeni seviye hazır.', true);
        }
    
        function showMessage(title, detail, won) {
            messageTitle.textContent = title;
            messageDetail.textContent = detail;
            primaryActionBtn.textContent = won ? 'Devam Et' : 'Tekrar Dene';
            nextActionBtn.style.display = won ? 'block' : 'none';
            setTimeout(() => messageOverlay.classList.add('show'), 260);
        }
    
        function burst(x, y, color, count) {
            for (let i = 0; i < count; i++) {
                const angle = (TAU / count) * i + Math.random() * 0.3;
                const speed = 0.08 + Math.random() * 0.18;
                particles.push({
                    x,
                    y,
                    vx: Math.cos(angle) * speed,
                    vy: Math.sin(angle) * speed,
                    size: 2 + Math.random() * 4,
                    life: 1,
                    decay: 380 + Math.random() * 260,
                    color
                });
            }
        }
    
        function tone(frequency, duration, type, volume) {
            if (!state.sound) return;
            try {
                audioCtx = audioCtx || new (window.AudioContext || window.webkitAudioContext)();
                const oscillator = audioCtx.createOscillator();
                const gain = audioCtx.createGain();
                oscillator.type = type;
                oscillator.frequency.value = frequency;
                gain.gain.setValueAtTime(volume, audioCtx.currentTime);
                gain.gain.exponentialRampToValueAtTime(0.0001, audioCtx.currentTime + duration);
                oscillator.connect(gain);
                gain.connect(audioCtx.destination);
                oscillator.start();
                oscillator.stop(audioCtx.currentTime + duration);
            } catch (error) {
                state.sound = false;
            }
        }
    
        function vibrate(pattern) {
            if (state.vibration && navigator.vibrate) {
                navigator.vibrate(pattern);
            }
        }
    
        function pauseGame() {
            if (gameState === 'PLAYING') {
                pausedRemainingTime = getRemainingTime();
                gameState = 'PAUSED';
                pauseBtn.textContent = '▶';
            }
        }
    
        function resumeGame() {
            if (gameState === 'PAUSED') {
                gameState = 'PLAYING';
                levelStartedAt = performance.now() - Math.max(0, timer - pausedRemainingTime) * 1000;
                pauseBtn.textContent = '⏸';
            }
        }
    
        function getRemainingTime() {
            if (state.mode !== 'timed') return 0;
            return Math.max(0, timer - (performance.now() - levelStartedAt) / 1000);
        }
    
        function openMenu() {
            gameState = 'MENU';
            countdownToken++;
            countdownEl.classList.remove('show');
            messageOverlay.classList.remove('show');
            menuOverlay.classList.add('show');
            pauseBtn.textContent = '⏸';
        }
    
        function getInk() {
            return document.body.classList.contains('dark') ? '#f5f6f8' : '#111318';
        }
    
        function getMuted() {
            return document.body.classList.contains('dark') ? 'rgba(245,246,248,0.62)' : 'rgba(17,19,24,0.52)';
        }
    
        function getAccent() {
            return document.body.classList.contains('dark') ? '#26c6a2' : '#0f8f72';
        }
    
        function loop(now) {
            update(now);
            draw();
            requestAnimationFrame(loop);
        }
    
        window.addEventListener('resize', resizeCanvas);
        canvas.addEventListener('mousedown', shoot);
        canvas.addEventListener('touchstart', shoot, { passive: false });
    
        document.querySelectorAll('[data-mode]').forEach(button => {
            button.addEventListener('click', () => {
                state.mode = button.dataset.mode;
                state.level = state.mode === 'endless' ? 1 : Math.min(state.level, maxLevel);
                updateHud();
                initLevel();
            });
        });
    
        continueBtn.addEventListener('click', () => initLevel());
        primaryActionBtn.addEventListener('click', () => initLevel());
        nextActionBtn.addEventListener('click', () => initLevel());
        menuBtn.addEventListener('click', openMenu);
        restartBtn.addEventListener('click', () => initLevel());
        pauseBtn.addEventListener('click', () => {
            if (gameState === 'PAUSED') {
                resumeGame();
            } else {
                pauseGame();
            }
        });
    
        soundToggle.addEventListener('change', () => {
            state.sound = soundToggle.checked;
            updateHud();
        });
    
        vibrationToggle.addEventListener('change', () => {
            state.vibration = vibrationToggle.checked;
            updateHud();
        });
    
        themeToggle.addEventListener('change', () => {
            state.dark = themeToggle.checked;
            updateHud();
        });
    
        document.addEventListener('keydown', event => {
            if (event.code === 'Space') shoot(event);
            if (event.code === 'Escape') openMenu();
            if (event.code === 'KeyP') gameState === 'PAUSED' ? resumeGame() : pauseGame();
        });
    
        resizeCanvas();
        updateHud();
        initLevel(true);
        openMenu();
        requestAnimationFrame(loop);
    </script>
    </body>
    </html>
    obisa adlı üyeden alıntı: mesajı görüntüle
    <!DOCTYPE html>
    <html lang="tr">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
        <title>Arrow - Strateji ve Atış Oyunu</title>
        <style>
            * {
                box-sizing: border-box;
                user-select: none;
                -webkit-user-select: none;
            }
            body {
                margin: 0;
                padding: 0;
                background-color: #e6e6e6;
                display: flex;
                justify-content: center;
                align-items: center;
                height: 100vh;
                overflow: hidden;
                font-family: 'Arial', sans-serif;
                touch-action: none;
            }
            #gameContainer {
                position: relative;
                width: 100%;
                max-width: 450px;
                height: 100%;
                max-height: 800px;
                background-color: #f4f4f4;
                box-shadow: 0 0 20px rgba(0,0,0,0.2);
            }
            canvas {
                display: block;
                width: 100%;
                height: 100%;
            }
            #ui {
                position: absolute;
                top: 20px;
                left: 20px;
                font-size: 24px;
                font-weight: bold;
                color: #222;
                pointer-events: none;
            }
            #messageBox {
                position: absolute;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                text-align: center;
                display: none;
                flex-direction: column;
                align-items: center;
            }
            #messageText {
                font-size: 40px;
                font-weight: bold;
                margin-bottom: 20px;
                text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
            }
            .btn {
                padding: 15px 30px;
                font-size: 20px;
                background-color: #222;
                color: #fff;
                border: none;
                border-radius: 30px;
                cursor: pointer;
                box-shadow: 0 4px 6px rgba(0,0,0,0.3);
                transition: transform 0.1s;
            }
            .btn:active {
                transform: scale(0.95);
            }
        </style>
    </head>
    <body>
    
    <div id="gameContainer">
        <div id="ui">Lv <span id="levelDisplay">1</span>/1200</div>
        <canvas id="gameCanvas"></canvas>
        
        <div id="messageBox">
            <div id="messageText">YANDIN!</div>
            <button class="btn" id="actionBtn">Tekrar Dene</button>
        </div>
    </div>
    
    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const levelDisplay = document.getElementById('levelDisplay');
        const messageBox = document.getElementById('messageBox');
        const messageText = document.getElementById('messageText');
        const actionBtn = document.getElementById('actionBtn');
    
        // Canvas boyutlandırma
        function resizeCanvas() {
            canvas.width = canvas.parentElement.clientWidth;
            canvas.height = canvas.parentElement.clientHeight;
        }
        window.addEventListener('resize', resizeCanvas);
        resizeCanvas();
    
        // Oyun Değişkenleri
        let level = 1;
        let maxLevel = 1200;
        let gameState = 'START'; // START, PLAYING, GAMEOVER, SUCCESS
        
        // Merkez Hedef (Büyük Top)
        const targetRadius = 50;
        let targetAngle = 0;
        let targetSpeed = 0.02;
        
        // İğneler / Atışlar (Küçük Toplar)
        const pinRadius = 12;
        const pinLineLength = 140;
        const bulletSpeed = 25;
        
        let pins = [];
        let bullets = [];
        let activeBullet = null;
        let startingBulletsCount = 0;
    
        // Renkler
        const colorBg = '#f4f4f4';
        const colorBlack = '#111';
        const colorFail = '#ff4d4d';
        const colorSuccess = '#4CAF50';
    
        function initLevel() {
            resizeCanvas();
            targetAngle = 0;
            
            // Seviyeye göre zorluk ayarları
            targetSpeed = 0.015 + (level * 0.001);
            let initialPinsCount = Math.min(2 + Math.floor(level / 4), 10); // Başlangıçta olan iğne sayısı
            
            // Seviyeye göre atılacak mermi sayısını belirle
            startingBulletsCount = Math.min(5 + Math.floor(level / 2), 25);
            
            // Bazen ters yöne dönsün
            if (level % 3 === 0) targetSpeed *= -1;
    
            pins = [];
            for (let i = 0; i < initialPinsCount; i++) {
                pins.push({
                    angle: (Math.PI * 2 / initialPinsCount) * i,
                    num: ''
                });
            }
    
            bullets = [];
            for (let i = startingBulletsCount; i > 0; i--) {
                bullets.push(i);
            }
    
            activeBullet = null;
            gameState = 'PLAYING';
            levelDisplay.innerText = level;
            messageBox.style.display = 'none';
        }
    
        function draw() {
            if (gameState === 'GAMEOVER') {
                ctx.fillStyle = colorFail;
            } else if (gameState === 'SUCCESS') {
                ctx.fillStyle = colorSuccess;
            } else {
                ctx.fillStyle = colorBg;
            }
            ctx.fillRect(0, 0, canvas.width, canvas.height);
    
            const cx = canvas.width / 2;
            const cy = canvas.height * 0.35;
    
            ctx.save();
            ctx.translate(cx, cy);
            ctx.rotate(targetAngle);
    
            // Ekli İğneler
            pins.forEach(pin => {
                const px = Math.cos(pin.angle) * pinLineLength;
                const py = Math.sin(pin.angle) * pinLineLength;
    
                ctx.beginPath();
                ctx.moveTo(0, 0);
                ctx.lineTo(px, py);
                ctx.strokeStyle = colorBlack;
                ctx.lineWidth = 2;
                ctx.stroke();
    
                ctx.beginPath();
                ctx.arc(px, py, pinRadius, 0, Math.PI * 2);
                ctx.fillStyle = colorBlack;
                ctx.fill();
    
                if (pin.num !== '') {
                    ctx.save();
                    ctx.translate(px, py);
                    ctx.rotate(-targetAngle);
                    ctx.fillStyle = '#fff';
                    ctx.font = '12px Arial';
                    ctx.textAlign = 'center';
                    ctx.textBaseline = 'middle';
                    ctx.fillText(pin.num, 0, 1);
                    ctx.restore();
                }
            });
    
            // Merkez Büyük Hedef
            ctx.beginPath();
            ctx.arc(0, 0, targetRadius, 0, Math.PI * 2);
            ctx.fillStyle = colorBlack;
            ctx.fill();
            
            // *** GÜNCELLEME: Hedef İçindeki Kalan Atış Sayısı ***
            ctx.rotate(-targetAngle);
            ctx.fillStyle = '#fff';
            
            // Rakamın uzunluğuna göre font boyutunu ayarla (çembere sığması için)
            let fontSize = bullets.length >= 100 ? 35 : 45;
            ctx.font = 'bold ' + fontSize + 'px Arial';
            ctx.textAlign = 'center';
            ctx.textBaseline = 'middle';
            
            // Ekranda kalan mermi sayısını yazdır (havada uçan varsa onu da dahil et)
            let totalRemaining = bullets.length + (activeBullet ? 1 : 0);
            ctx.fillText(totalRemaining, 0, 2);
            ctx.restore();
    
            // Uçan (Aktif) Mermi
            if (activeBullet) {
                ctx.beginPath();
                ctx.moveTo(cx, activeBullet.y);
                ctx.lineTo(cx, activeBullet.y + 20);
                ctx.strokeStyle = colorBlack;
                ctx.lineWidth = 2;
                ctx.stroke();
    
                ctx.beginPath();
                ctx.arc(cx, activeBullet.y, pinRadius, 0, Math.PI * 2);
                ctx.fillStyle = colorBlack;
                ctx.fill();
    
                ctx.fillStyle = '#fff';
                ctx.font = '12px Arial';
                ctx.textAlign = 'center';
                ctx.textBaseline = 'middle';
                ctx.fillText(activeBullet.num, cx, activeBullet.y + 1);
            }
    
            // Bekleyen Mermiler
            const bulletStartY = canvas.height * 0.75;
            const spacing = pinRadius * 2.5;
    
            for (let i = 0; i < bullets.length; i++) {
                if (i > 5) break;
                
                const by = bulletStartY + (i * spacing);
                
                ctx.beginPath();
                ctx.arc(cx, by, pinRadius, 0, Math.PI * 2);
                ctx.fillStyle = colorBlack;
                ctx.fill();
    
                ctx.fillStyle = '#fff';
                ctx.font = '12px Arial';
                ctx.textAlign = 'center';
                ctx.textBaseline = 'middle';
                ctx.fillText(bullets[bullets.length - 1 - i], cx, by + 1);
            }
            
            // "Ateş Etmek İçin Dokun" yazısı
            if (gameState === 'PLAYING' && bullets.length === startingBulletsCount && !activeBullet) {
                ctx.fillStyle = 'rgba(0,0,0,0.3)';
                ctx.font = 'bold 22px Arial';
                ctx.textAlign = 'center';
                ctx.fillText('Ateş Etmek İçin Dokun', cx, canvas.height * 0.62);
            }
        }
    
        function update() {
            if (gameState !== 'PLAYING') return;
    
            targetAngle += targetSpeed;
    
            if (activeBullet) {
                activeBullet.y -= bulletSpeed;
                const cy = canvas.height * 0.35;
                
                if (activeBullet.y <= cy + pinLineLength) {
                    let hitAngle = (Math.PI / 2) - targetAngle;
                    hitAngle = (hitAngle % (Math.PI * 2) + Math.PI * 2) % (Math.PI * 2);
    
                    let collision = false;
                    
                    for (let i = 0; i < pins.length; i++) {
                        let pinAngle = pins[i].angle;
                        pinAngle = (pinAngle % (Math.PI * 2) + Math.PI * 2) % (Math.PI * 2);
    
                        let diff = Math.abs(hitAngle - pinAngle);
                        if (diff > Math.PI) diff = Math.PI * 2 - diff;
    
                        let distance = 2 * pinLineLength * Math.sin(diff / 2);
    
                        if (distance < pinRadius * 2 + 2) {
                            collision = true;
                            break;
                        }
                    }
    
                    if (collision) {
                        gameState = 'GAMEOVER';
                        messageText.innerText = "YANDIN!";
                        messageText.style.color = "#fff";
                        actionBtn.innerText = "Tekrar Dene";
                        setTimeout(() => { messageBox.style.display = 'flex'; }, 300);
                    } else {
                        pins.push({ angle: hitAngle, num: activeBullet.num });
                        activeBullet = null;
                        
                        if (bullets.length === 0) {
                            gameState = 'SUCCESS';
                            messageText.innerText = "HARİKA!";
                            messageText.style.color = "#fff";
                            actionBtn.innerText = "Sonraki Seviye";
                            setTimeout(() => { messageBox.style.display = 'flex'; }, 300);
                        }
                    }
                }
            }
        }
    
        function gameLoop() {
            update();
            draw();
            requestAnimationFrame(gameLoop);
        }
    
        function shoot(e) {
            if (e && e.type === 'touchstart') e.preventDefault();
            
            if (gameState === 'PLAYING' && !activeBullet && bullets.length > 0) {
                const num = bullets.pop();
                activeBullet = {
                    y: canvas.height * 0.75,
                    num: num
                };
            }
        }
    
        canvas.addEventListener('mousedown', shoot);
        canvas.addEventListener('touchstart', shoot, { passive: false });
    
        actionBtn.addEventListener('click', () => {
            if (gameState === 'SUCCESS') {
                level++;
                if(level > maxLevel) level = maxLevel;
            }
            initLevel();
        });
    
        initLevel();
        gameLoop();
    
    </script>
    </body>
    </html>


    Selamlar trend haline gelen o oyunu yapay zeka ile yaptık kodlar yukarıda geliştirmek size kalmış ben daha napam kimse yapmaz kimse vermez iyi forumlar
  • 29-04-2026, 13:31:41
    #11
    Üyeliği durduruldu
    nethanlose adlı üyeden alıntı: mesajı görüntüle
    Birazda ben geliştirdim elinize sağlık
    <!DOCTYPE html>
    <html lang="tr">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
        <title>Dart Arrow</title>
        <style>
            * {
                box-sizing: border-box;
                user-select: none;
                -webkit-user-select: none;
                -webkit-tap-highlight-color: transparent;
            }
    
            :root {
                --bg: #eef0f3;
                --panel: rgba(255, 255, 255, 0.88);
                --ink: #111318;
                --muted: #69707d;
                --line: rgba(17, 19, 24, 0.12);
                --accent: #0f8f72;
                --danger: #d94444;
                --gold: #d99b19;
                --shadow: 0 20px 55px rgba(24, 29, 38, 0.18);
            }
    
            body.dark {
                --bg: #171a21;
                --panel: rgba(31, 35, 44, 0.92);
                --ink: #f5f6f8;
                --muted: #aeb5c2;
                --line: rgba(245, 246, 248, 0.14);
                --accent: #26c6a2;
                --danger: #ff6b6b;
                --gold: #ffc247;
                --shadow: 0 20px 55px rgba(0, 0, 0, 0.35);
            }
    
            html,
            body {
                margin: 0;
                padding: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
                font-family: Arial, Helvetica, sans-serif;
                background: radial-gradient(circle at 50% 10%, #ffffff 0, var(--bg) 58%);
                color: var(--ink);
                touch-action: none;
            }
    
            body.dark {
                background: radial-gradient(circle at 50% 10%, #2b303b 0, var(--bg) 58%);
            }
    
            #gameContainer {
                position: relative;
                width: 100%;
                max-width: 460px;
                height: 100%;
                max-height: 820px;
                margin: 0 auto;
                overflow: hidden;
                background: var(--bg);
                box-shadow: var(--shadow);
            }
    
            canvas {
                display: block;
                width: 100%;
                height: 100%;
            }
    
            #topBar {
                position: absolute;
                top: 14px;
                left: 14px;
                right: 14px;
                z-index: 4;
                display: flex;
                align-items: flex-start;
                justify-content: space-between;
                gap: 10px;
                pointer-events: none;
            }
    
            .stats {
                display: flex;
                flex-wrap: wrap;
                gap: 8px;
                min-width: 0;
            }
    
            .pill {
                min-width: 62px;
                padding: 7px 10px;
                border: 1px solid var(--line);
                border-radius: 8px;
                background: var(--panel);
                color: var(--ink);
                box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
                backdrop-filter: blur(10px);
                font-size: 11px;
                font-weight: 700;
                line-height: 1.15;
                letter-spacing: 0;
            }
    
            .pill span {
                display: block;
                margin-top: 3px;
                font-size: 18px;
            }
    
            .iconRow {
                display: flex;
                gap: 8px;
                pointer-events: auto;
            }
    
            .iconBtn {
                width: 40px;
                height: 40px;
                display: grid;
                place-items: center;
                border: 1px solid var(--line);
                border-radius: 8px;
                background: var(--panel);
                color: var(--ink);
                box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
                cursor: pointer;
                font-size: 18px;
            }
    
            .overlay {
                position: absolute;
                inset: 0;
                z-index: 8;
                display: none;
                align-items: center;
                justify-content: center;
                padding: 22px;
                background: rgba(238, 240, 243, 0.72);
                backdrop-filter: blur(12px);
            }
    
            body.dark .overlay {
                background: rgba(23, 26, 33, 0.72);
            }
    
            .overlay.show {
                display: flex;
            }
    
            .panel {
                width: min(100%, 390px);
                padding: 22px;
                border: 1px solid var(--line);
                border-radius: 8px;
                background: var(--panel);
                box-shadow: var(--shadow);
            }
    
            .title {
                margin: 0 0 6px;
                font-size: 40px;
                line-height: 1;
                letter-spacing: 0;
            }
    
            .subtitle {
                margin: 0 0 18px;
                color: var(--muted);
                font-size: 14px;
                line-height: 1.35;
            }
    
            .menuGrid {
                display: grid;
                grid-template-columns: 1fr 1fr;
                gap: 10px;
                margin: 12px 0;
            }
    
            .wide {
                grid-column: 1 / -1;
            }
    
            .btn {
                width: 100%;
                min-height: 48px;
                padding: 12px 14px;
                border: 1px solid transparent;
                border-radius: 8px;
                background: var(--ink);
                color: var(--bg);
                cursor: pointer;
                font-size: 15px;
                font-weight: 700;
            }
    
            .btn.secondary {
                border-color: var(--line);
                background: transparent;
                color: var(--ink);
            }
    
            .btn.accent {
                background: var(--accent);
                color: #ffffff;
            }
    
            .btn:active,
            .iconBtn:active {
                transform: scale(0.97);
            }
    
            .setting {
                display: flex;
                align-items: center;
                justify-content: space-between;
                gap: 12px;
                padding: 12px 0;
                border-top: 1px solid var(--line);
                font-size: 14px;
                font-weight: 700;
            }
    
            .setting small {
                display: block;
                margin-top: 3px;
                color: var(--muted);
                font-size: 12px;
                font-weight: 400;
            }
    
            .switch {
                position: relative;
                width: 48px;
                height: 28px;
                flex: 0 0 auto;
            }
    
            .switch input {
                display: none;
            }
    
            .slider {
                position: absolute;
                inset: 0;
                border-radius: 999px;
                background: #adb3bd;
                cursor: pointer;
            }
    
            .slider::after {
                content: "";
                position: absolute;
                width: 22px;
                height: 22px;
                top: 3px;
                left: 3px;
                border-radius: 50%;
                background: #ffffff;
                transition: transform 0.18s;
            }
    
            .switch input:checked + .slider {
                background: var(--accent);
            }
    
            .switch input:checked + .slider::after {
                transform: translateX(20px);
            }
    
            #messageTitle {
                margin: 0 0 8px;
                font-size: 36px;
                line-height: 1.05;
            }
    
            #messageDetail {
                margin: 0 0 18px;
                color: var(--muted);
                line-height: 1.35;
            }
    
            #countdown {
                position: absolute;
                inset: 0;
                z-index: 7;
                display: none;
                align-items: center;
                justify-content: center;
                font-size: 96px;
                font-weight: 900;
                color: var(--ink);
                text-shadow: 0 8px 30px rgba(0, 0, 0, 0.16);
                pointer-events: none;
            }
    
            #countdown.show {
                display: flex;
                animation: pop 0.35s ease;
            }
    
            @keyframes pop {
                from { transform: scale(0.7); opacity: 0; }
                to { transform: scale(1); opacity: 1; }
            }
    
            @media (max-width: 360px) {
                .title { font-size: 34px; }
                .pill { min-width: 56px; padding: 6px 8px; }
                .pill span { font-size: 16px; }
                .iconBtn { width: 36px; height: 36px; }
            }
        </style>
    </head>
    <body>
    <div id="gameContainer">
        <canvas id="gameCanvas"></canvas>
    
        <div id="topBar">
            <div class="stats">
                <div class="pill">SEVİYE<span id="levelDisplay">1</span></div>
                <div class="pill">REKOR<span id="bestDisplay">1</span></div>
                <div class="pill">MOD<span id="modeDisplay">Klasik</span></div>
            </div>
            <div class="iconRow">
                <button class="iconBtn" id="pauseBtn" title="Duraklat">⏸</button>
                <button class="iconBtn" id="restartBtn" title="Yeniden başlat">↻</button>
            </div>
        </div>
    
        <div id="countdown">3</div>
    
        <div class="overlay show" id="menuOverlay">
            <div class="panel">
                <h1 class="title">Dart Arrow</h1>
                <p class="subtitle">Doğru anda ateş et, çarpışmadan tüm iğneleri hedefe yerleştir.</p>
                <div class="menuGrid">
                    <button class="btn accent wide" id="continueBtn">Devam Et</button>
                    <button class="btn" data-mode="classic">Klasik</button>
                    <button class="btn secondary" data-mode="endless">Sonsuz</button>
                    <button class="btn secondary" data-mode="timed">Zamanlı</button>
                    <button class="btn secondary" data-mode="hard">Zor</button>
                </div>
                <div class="setting">
                    <div>Ses<small>Atış, başarı ve çarpışma sesleri</small></div>
                    <label class="switch">
                        <input type="checkbox" id="soundToggle" checked>
                        <span class="slider"></span>
                    </label>
                </div>
                <div class="setting">
                    <div>Titreşim<small>Destekleyen telefonlarda dokunsal geri bildirim</small></div>
                    <label class="switch">
                        <input type="checkbox" id="vibrationToggle" checked>
                        <span class="slider"></span>
                    </label>
                </div>
                <div class="setting">
                    <div>Karanlık Tema<small>Düşük ışıkta daha rahat oyun</small></div>
                    <label class="switch">
                        <input type="checkbox" id="themeToggle">
                        <span class="slider"></span>
                    </label>
                </div>
            </div>
        </div>
    
        <div class="overlay" id="messageOverlay">
            <div class="panel">
                <h2 id="messageTitle">Yandın!</h2>
                <p id="messageDetail">Aynı noktaya denk geldi.</p>
                <div class="menuGrid">
                    <button class="btn accent wide" id="primaryActionBtn">Tekrar Dene</button>
                    <button class="btn secondary" id="menuBtn">Menü</button>
                    <button class="btn secondary" id="nextActionBtn">Sonraki Seviye</button>
                </div>
            </div>
        </div>
    </div>
    
    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const levelDisplay = document.getElementById('levelDisplay');
        const bestDisplay = document.getElementById('bestDisplay');
        const modeDisplay = document.getElementById('modeDisplay');
        const menuOverlay = document.getElementById('menuOverlay');
        const messageOverlay = document.getElementById('messageOverlay');
        const messageTitle = document.getElementById('messageTitle');
        const messageDetail = document.getElementById('messageDetail');
        const primaryActionBtn = document.getElementById('primaryActionBtn');
        const nextActionBtn = document.getElementById('nextActionBtn');
        const menuBtn = document.getElementById('menuBtn');
        const pauseBtn = document.getElementById('pauseBtn');
        const restartBtn = document.getElementById('restartBtn');
        const continueBtn = document.getElementById('continueBtn');
        const countdownEl = document.getElementById('countdown');
        const soundToggle = document.getElementById('soundToggle');
        const vibrationToggle = document.getElementById('vibrationToggle');
        const themeToggle = document.getElementById('themeToggle');
    
        const TAU = Math.PI * 2;
        const maxLevel = 1200;
        const storageKey = 'dartArrowSaveV2';
        const modes = {
            classic: 'Klasik',
            endless: 'Sonsuz',
            timed: 'Zamanlı',
            hard: 'Zor'
        };
    
        let state = loadState();
        let gameState = 'MENU';
        let targetAngle = 0;
        let targetSpeed = 0.02;
        let targetRadius = 50;
        let pinRadius = 12;
        let pinLineLength = 138;
        let bulletSpeed = 25;
        let startingBulletsCount = 0;
        let timer = 0;
        let levelStartedAt = 0;
        let pausedRemainingTime = 0;
        let lastTime = performance.now();
        let pins = [];
        let bullets = [];
        let activeBullet = null;
        let particles = [];
        let flash = null;
        let audioCtx = null;
        let countdownToken = 0;
    
        function loadState() {
            const fallback = {
                level: 1,
                best: 1,
                mode: 'classic',
                sound: true,
                vibration: true,
                dark: false
            };
    
            try {
                return { ...fallback, ...JSON.parse(localStorage.getItem(storageKey) || '{}') };
            } catch (error) {
                return fallback;
            }
        }
    
        function saveState() {
            localStorage.setItem(storageKey, JSON.stringify(state));
        }
    
        function resizeCanvas() {
            const dpr = Math.max(1, Math.min(window.devicePixelRatio || 1, 2));
            const rect = canvas.parentElement.getBoundingClientRect();
            canvas.width = Math.floor(rect.width * dpr);
            canvas.height = Math.floor(rect.height * dpr);
            ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
            canvas.logicalWidth = rect.width;
            canvas.logicalHeight = rect.height;
            pinLineLength = Math.max(105, Math.min(145, rect.height * 0.18));
            targetRadius = Math.max(42, Math.min(54, rect.width * 0.115));
        }
    
        function updateHud() {
            levelDisplay.textContent = state.level;
            bestDisplay.textContent = state.best;
            modeDisplay.textContent = modes[state.mode];
            soundToggle.checked = state.sound;
            vibrationToggle.checked = state.vibration;
            themeToggle.checked = state.dark;
            document.body.classList.toggle('dark', state.dark);
            continueBtn.textContent = state.best > 1 ? 'Devam Et - Seviye ' + state.level : 'Başla';
            saveState();
        }
    
        function getDifficulty() {
            const level = state.mode === 'endless' ? Math.min(state.level, 2000) : state.level;
            const curve = Math.log2(level + 1);
            const hardBoost = state.mode === 'hard' ? 1.35 : 1;
            const timedBoost = state.mode === 'timed' ? 1.12 : 1;
            const speedBase = 0.010 + curve * 0.0042;
            const speedWave = Math.sin(level * 0.73) * 0.006;
            const speed = Math.min(0.09, (speedBase + speedWave) * hardBoost * timedBoost);
            const initialPins = Math.min(state.mode === 'hard' ? 13 : 11, 2 + Math.floor(level / 5) + Math.floor(curve / 2));
            const bulletsCount = Math.min(state.mode === 'hard' ? 30 : 26, 5 + Math.floor(level / 3) + (level % 4 === 0 ? 2 : 0));
            const direction = level % 3 === 0 ? -1 : 1;
            const wobble = level >= 8 || state.mode !== 'classic';
            const stopGo = level >= 14 || state.mode === 'hard';
            const timeLimit = state.mode === 'timed' ? Math.max(7, 16 - Math.floor(level / 12)) : 0;
    
            return {
                speed: speed * direction,
                initialPins,
                bulletsCount,
                wobble,
                stopGo,
                timeLimit
            };
        }
    
        function initLevel(skipCountdown = false) {
            resizeCanvas();
            const difficulty = getDifficulty();
            targetAngle = 0;
            targetSpeed = difficulty.speed;
            startingBulletsCount = difficulty.bulletsCount;
            timer = difficulty.timeLimit;
            pausedRemainingTime = timer;
            levelStartedAt = performance.now();
            pins = [];
            bullets = [];
            activeBullet = null;
            particles = [];
            flash = null;
    
            const jitter = state.mode === 'classic' && state.level < 5 ? 0 : 0.18;
            for (let i = 0; i < difficulty.initialPins; i++) {
                const offset = Math.sin((state.level + i) * 1.77) * jitter;
                pins.push({
                    angle: normalize((TAU / difficulty.initialPins) * i + offset),
                    num: ''
                });
            }
    
            for (let i = startingBulletsCount; i > 0; i--) {
                bullets.push(i);
            }
    
            gameState = skipCountdown ? 'PLAYING' : 'COUNTDOWN';
            menuOverlay.classList.remove('show');
            messageOverlay.classList.remove('show');
            updateHud();
    
            if (skipCountdown) {
                return;
            }
    
            runCountdown();
        }
    
        function runCountdown() {
            const token = ++countdownToken;
            let count = 3;
            countdownEl.textContent = count;
            countdownEl.classList.add('show');
            tone(520, 0.06, 'sine', 0.04);
    
            const tick = () => {
                if (token !== countdownToken || gameState !== 'COUNTDOWN') return;
                count--;
                if (count > 0) {
                    countdownEl.textContent = count;
                    countdownEl.classList.remove('show');
                    void countdownEl.offsetWidth;
                    countdownEl.classList.add('show');
                    tone(520 + count * 50, 0.06, 'sine', 0.04);
                    setTimeout(tick, 650);
                } else {
                    countdownEl.textContent = 'GO';
                    countdownEl.classList.remove('show');
                    void countdownEl.offsetWidth;
                    countdownEl.classList.add('show');
                    tone(760, 0.1, 'triangle', 0.05);
                    setTimeout(() => {
                        if (token === countdownToken) {
                            countdownEl.classList.remove('show');
                            gameState = 'PLAYING';
                            levelStartedAt = performance.now();
                        }
                    }, 450);
                }
            };
    
            setTimeout(tick, 650);
        }
    
        function normalize(angle) {
            return (angle % TAU + TAU) % TAU;
        }
    
        function draw() {
            const width = canvas.logicalWidth || canvas.width;
            const height = canvas.logicalHeight || canvas.height;
            const cx = width / 2;
            const cy = height * 0.36;
            const remaining = bullets.length + (activeBullet ? 1 : 0);
    
            ctx.clearRect(0, 0, width, height);
            drawBackground(width, height);
            drawTarget(cx, cy, remaining);
            drawActiveBullet(cx);
            drawQueue(cx, height);
            drawParticles();
            drawPrompts(cx, height);
    
            if (flash) {
                ctx.fillStyle = flash.color;
                ctx.globalAlpha = Math.max(0, flash.life);
                ctx.fillRect(0, 0, width, height);
                ctx.globalAlpha = 1;
            }
        }
    
        function drawBackground(width, height) {
            const gradient = ctx.createLinearGradient(0, 0, 0, height);
            if (document.body.classList.contains('dark')) {
                gradient.addColorStop(0, '#252a33');
                gradient.addColorStop(1, '#171a21');
            } else {
                gradient.addColorStop(0, '#fbfbfc');
                gradient.addColorStop(1, '#e8ebef');
            }
            ctx.fillStyle = gradient;
            ctx.fillRect(0, 0, width, height);
    
            ctx.strokeStyle = document.body.classList.contains('dark') ? 'rgba(255,255,255,0.035)' : 'rgba(0,0,0,0.035)';
            ctx.lineWidth = 1;
            for (let y = 95; y < height; y += 44) {
                ctx.beginPath();
                ctx.moveTo(0, y);
                ctx.lineTo(width, y);
                ctx.stroke();
            }
        }
    
        function drawTarget(cx, cy, remaining) {
            const ink = getInk();
            ctx.save();
            ctx.translate(cx, cy);
            ctx.rotate(targetAngle);
    
            pins.forEach(pin => {
                const px = Math.cos(pin.angle) * pinLineLength;
                const py = Math.sin(pin.angle) * pinLineLength;
                ctx.beginPath();
                ctx.moveTo(0, 0);
                ctx.lineTo(px, py);
                ctx.strokeStyle = ink;
                ctx.lineWidth = 2;
                ctx.stroke();
    
                ctx.beginPath();
                ctx.arc(px, py, pinRadius, 0, TAU);
                ctx.fillStyle = ink;
                ctx.fill();
    
                if (pin.num !== '') {
                    ctx.save();
                    ctx.translate(px, py);
                    ctx.rotate(-targetAngle);
                    drawSmallNumber(pin.num, 0, 1);
                    ctx.restore();
                }
            });
    
            ctx.beginPath();
            ctx.arc(0, 0, targetRadius + 4, 0, TAU);
            ctx.fillStyle = state.mode === 'hard' ? '#d94444' : state.mode === 'timed' ? '#d99b19' : ink;
            ctx.fill();
    
            ctx.beginPath();
            ctx.arc(0, 0, targetRadius - 7, 0, TAU);
            ctx.fillStyle = ink;
            ctx.fill();
    
            ctx.rotate(-targetAngle);
            ctx.fillStyle = '#ffffff';
            ctx.font = '900 ' + (remaining >= 100 ? 32 : 44) + 'px Arial';
            ctx.textAlign = 'center';
            ctx.textBaseline = 'middle';
            ctx.fillText(remaining, 0, 2);
            ctx.restore();
        }
    
        function drawActiveBullet(cx) {
            if (!activeBullet) return;
            const ink = getInk();
            ctx.beginPath();
            ctx.moveTo(cx, activeBullet.y);
            ctx.lineTo(cx, activeBullet.y + 22);
            ctx.strokeStyle = ink;
            ctx.lineWidth = 2;
            ctx.stroke();
    
            ctx.beginPath();
            ctx.arc(cx, activeBullet.y, pinRadius, 0, TAU);
            ctx.fillStyle = ink;
            ctx.fill();
            drawSmallNumber(activeBullet.num, cx, activeBullet.y + 1);
        }
    
        function drawQueue(cx, height) {
            const ink = getInk();
            const bulletStartY = height * 0.74;
            const spacing = pinRadius * 2.35;
            const showCount = Math.min(7, bullets.length);
    
            for (let i = 0; i < showCount; i++) {
                const by = bulletStartY + (i * spacing);
                ctx.beginPath();
                ctx.arc(cx, by, pinRadius, 0, TAU);
                ctx.fillStyle = ink;
                ctx.fill();
                drawSmallNumber(bullets[bullets.length - 1 - i], cx, by + 1);
            }
    
            if (bullets.length > showCount) {
                ctx.fillStyle = getMuted();
                ctx.font = 'bold 13px Arial';
                ctx.textAlign = 'center';
                ctx.textBaseline = 'middle';
                ctx.fillText('+' + (bullets.length - showCount), cx, bulletStartY + showCount * spacing + 4);
            }
        }
    
        function drawSmallNumber(text, x, y) {
            ctx.fillStyle = '#ffffff';
            ctx.font = 'bold 12px Arial';
            ctx.textAlign = 'center';
            ctx.textBaseline = 'middle';
            ctx.fillText(text, x, y);
        }
    
        function drawPrompts(cx, height) {
            if (gameState === 'PLAYING' && bullets.length === startingBulletsCount && !activeBullet) {
                ctx.fillStyle = getMuted();
                ctx.font = 'bold 20px Arial';
                ctx.textAlign = 'center';
                ctx.fillText('Ateş etmek için dokun', cx, height * 0.62);
            }
    
            if (gameState === 'PAUSED') {
                ctx.fillStyle = 'rgba(0,0,0,0.35)';
                ctx.fillRect(0, 0, canvas.logicalWidth, canvas.logicalHeight);
                ctx.fillStyle = '#ffffff';
                ctx.font = '900 42px Arial';
                ctx.textAlign = 'center';
                ctx.fillText('DURAKLATILDI', canvas.logicalWidth / 2, canvas.logicalHeight / 2);
            }
    
            if (state.mode === 'timed' && gameState === 'PLAYING') {
                const timeLeft = Math.max(0, timer - (performance.now() - levelStartedAt) / 1000);
                ctx.fillStyle = timeLeft <= 3 ? '#d94444' : getInk();
                ctx.font = '900 18px Arial';
                ctx.textAlign = 'right';
                ctx.fillText(timeLeft.toFixed(1), canvas.logicalWidth - 18, 96);
            }
        }
    
        function drawParticles() {
            particles.forEach(p => {
                ctx.globalAlpha = Math.max(0, p.life);
                ctx.beginPath();
                ctx.arc(p.x, p.y, p.size, 0, TAU);
                ctx.fillStyle = p.color;
                ctx.fill();
            });
            ctx.globalAlpha = 1;
        }
    
        function update(now) {
            const dt = Math.min(32, now - lastTime);
            lastTime = now;
    
            updateParticles(dt);
            if (flash) {
                flash.life -= dt / 220;
                if (flash.life <= 0) flash = null;
            }
    
            if (gameState !== 'PLAYING') return;
    
            const difficulty = getDifficulty();
            const elapsed = (now - levelStartedAt) / 1000;
            let speedMultiplier = 1;
            if (difficulty.wobble) speedMultiplier += Math.sin(elapsed * 2.4) * 0.28;
            if (difficulty.stopGo && Math.sin(elapsed * 1.35) > 0.72) speedMultiplier = 0.18;
            targetAngle += targetSpeed * speedMultiplier * (dt / 16.67);
    
            if (state.mode === 'timed' && elapsed >= timer) {
                fail('Süre Bitti!', 'Bu seviyede daha hızlı ateş etmelisin.');
                return;
            }
    
            if (!activeBullet) return;
    
            activeBullet.y -= bulletSpeed * (dt / 16.67);
            const cy = canvas.logicalHeight * 0.36;
    
            if (activeBullet.y <= cy + pinLineLength) {
                let hitAngle = normalize((Math.PI / 2) - targetAngle);
                let collision = false;
    
                for (let i = 0; i < pins.length; i++) {
                    let pinAngle = normalize(pins[i].angle);
                    let diff = Math.abs(hitAngle - pinAngle);
                    if (diff > Math.PI) diff = TAU - diff;
    
                    const distance = 2 * pinLineLength * Math.sin(diff / 2);
                    if (distance < pinRadius * 2 + 2) {
                        collision = true;
                        break;
                    }
                }
    
                if (collision) {
                    fail('Yandın!', 'İğne başka bir iğneye çarptı.');
                } else {
                    pins.push({ angle: hitAngle, num: activeBullet.num });
                    burst(canvas.logicalWidth / 2, cy + pinLineLength, getAccent(), 8);
                    activeBullet = null;
                    tone(420, 0.045, 'triangle', 0.035);
    
                    if (bullets.length === 0) {
                        success();
                    }
                }
            }
        }
    
        function updateParticles(dt) {
            particles = particles.filter(p => {
                p.x += p.vx * dt;
                p.y += p.vy * dt;
                p.vy += 0.0009 * dt;
                p.life -= dt / p.decay;
                return p.life > 0;
            });
        }
    
        function shoot(event) {
            if (event) event.preventDefault();
            if (gameState === 'COUNTDOWN') return;
            if (gameState === 'PAUSED') {
                resumeGame();
                return;
            }
            if (gameState !== 'PLAYING' || activeBullet || bullets.length === 0) return;
    
            const num = bullets.pop();
            activeBullet = {
                y: canvas.logicalHeight * 0.74,
                num
            };
            tone(260, 0.055, 'square', 0.025);
            vibrate(12);
        }
    
        function fail(title, detail) {
            gameState = 'GAMEOVER';
            activeBullet = null;
            flash = { color: 'rgba(217, 68, 68, 0.42)', life: 1 };
            burst(canvas.logicalWidth / 2, canvas.logicalHeight * 0.36, '#d94444', 24);
            tone(120, 0.22, 'sawtooth', 0.05);
            vibrate([50, 30, 80]);
            showMessage(title, detail, false);
        }
    
        function success() {
            gameState = 'SUCCESS';
            flash = { color: 'rgba(15, 143, 114, 0.32)', life: 1 };
            burst(canvas.logicalWidth / 2, canvas.logicalHeight * 0.36, getAccent(), 34);
            tone(620, 0.08, 'triangle', 0.04);
            setTimeout(() => tone(820, 0.11, 'triangle', 0.035), 85);
            vibrate(35);
    
            if (state.mode === 'classic' || state.mode === 'timed' || state.mode === 'hard') {
                state.level = Math.min(maxLevel, state.level + 1);
            } else {
                state.level++;
            }
    
            state.best = Math.max(state.best, state.level);
            updateHud();
            showMessage('Harika!', 'Seviye tamamlandı. Yeni seviye hazır.', true);
        }
    
        function showMessage(title, detail, won) {
            messageTitle.textContent = title;
            messageDetail.textContent = detail;
            primaryActionBtn.textContent = won ? 'Devam Et' : 'Tekrar Dene';
            nextActionBtn.style.display = won ? 'block' : 'none';
            setTimeout(() => messageOverlay.classList.add('show'), 260);
        }
    
        function burst(x, y, color, count) {
            for (let i = 0; i < count; i++) {
                const angle = (TAU / count) * i + Math.random() * 0.3;
                const speed = 0.08 + Math.random() * 0.18;
                particles.push({
                    x,
                    y,
                    vx: Math.cos(angle) * speed,
                    vy: Math.sin(angle) * speed,
                    size: 2 + Math.random() * 4,
                    life: 1,
                    decay: 380 + Math.random() * 260,
                    color
                });
            }
        }
    
        function tone(frequency, duration, type, volume) {
            if (!state.sound) return;
            try {
                audioCtx = audioCtx || new (window.AudioContext || window.webkitAudioContext)();
                const oscillator = audioCtx.createOscillator();
                const gain = audioCtx.createGain();
                oscillator.type = type;
                oscillator.frequency.value = frequency;
                gain.gain.setValueAtTime(volume, audioCtx.currentTime);
                gain.gain.exponentialRampToValueAtTime(0.0001, audioCtx.currentTime + duration);
                oscillator.connect(gain);
                gain.connect(audioCtx.destination);
                oscillator.start();
                oscillator.stop(audioCtx.currentTime + duration);
            } catch (error) {
                state.sound = false;
            }
        }
    
        function vibrate(pattern) {
            if (state.vibration && navigator.vibrate) {
                navigator.vibrate(pattern);
            }
        }
    
        function pauseGame() {
            if (gameState === 'PLAYING') {
                pausedRemainingTime = getRemainingTime();
                gameState = 'PAUSED';
                pauseBtn.textContent = '▶';
            }
        }
    
        function resumeGame() {
            if (gameState === 'PAUSED') {
                gameState = 'PLAYING';
                levelStartedAt = performance.now() - Math.max(0, timer - pausedRemainingTime) * 1000;
                pauseBtn.textContent = '⏸';
            }
        }
    
        function getRemainingTime() {
            if (state.mode !== 'timed') return 0;
            return Math.max(0, timer - (performance.now() - levelStartedAt) / 1000);
        }
    
        function openMenu() {
            gameState = 'MENU';
            countdownToken++;
            countdownEl.classList.remove('show');
            messageOverlay.classList.remove('show');
            menuOverlay.classList.add('show');
            pauseBtn.textContent = '⏸';
        }
    
        function getInk() {
            return document.body.classList.contains('dark') ? '#f5f6f8' : '#111318';
        }
    
        function getMuted() {
            return document.body.classList.contains('dark') ? 'rgba(245,246,248,0.62)' : 'rgba(17,19,24,0.52)';
        }
    
        function getAccent() {
            return document.body.classList.contains('dark') ? '#26c6a2' : '#0f8f72';
        }
    
        function loop(now) {
            update(now);
            draw();
            requestAnimationFrame(loop);
        }
    
        window.addEventListener('resize', resizeCanvas);
        canvas.addEventListener('mousedown', shoot);
        canvas.addEventListener('touchstart', shoot, { passive: false });
    
        document.querySelectorAll('[data-mode]').forEach(button => {
            button.addEventListener('click', () => {
                state.mode = button.dataset.mode;
                state.level = state.mode === 'endless' ? 1 : Math.min(state.level, maxLevel);
                updateHud();
                initLevel();
            });
        });
    
        continueBtn.addEventListener('click', () => initLevel());
        primaryActionBtn.addEventListener('click', () => initLevel());
        nextActionBtn.addEventListener('click', () => initLevel());
        menuBtn.addEventListener('click', openMenu);
        restartBtn.addEventListener('click', () => initLevel());
        pauseBtn.addEventListener('click', () => {
            if (gameState === 'PAUSED') {
                resumeGame();
            } else {
                pauseGame();
            }
        });
    
        soundToggle.addEventListener('change', () => {
            state.sound = soundToggle.checked;
            updateHud();
        });
    
        vibrationToggle.addEventListener('change', () => {
            state.vibration = vibrationToggle.checked;
            updateHud();
        });
    
        themeToggle.addEventListener('change', () => {
            state.dark = themeToggle.checked;
            updateHud();
        });
    
        document.addEventListener('keydown', event => {
            if (event.code === 'Space') shoot(event);
            if (event.code === 'Escape') openMenu();
            if (event.code === 'KeyP') gameState === 'PAUSED' ? resumeGame() : pauseGame();
        });
    
        resizeCanvas();
        updateHud();
        initLevel(true);
        openMenu();
        requestAnimationFrame(loop);
    </script>
    </body>
    </html>

    geliştirin tabi onun için verdim zaten