Meta Description" name="description" />

Share this result

Previews are deleted daily. Get a permanent share link sent to your inbox:
Script
<!DOCTYPE html> <html lang="tr"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Şehir Bilgi Yarışması - 3D</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { overflow: hidden; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: #000; } #game-container { position: relative; width: 100vw; height: 100vh; } /* === INTRO SCREEN === */ #intro-screen { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%); display: flex; flex-direction: column; justify-content: center; align-items: center; z-index: 1000; transition: opacity 1s ease; } #intro-screen h1 { font-size: 4rem; color: #e94560; text-shadow: 0 0 20px rgba(233,69,96,0.5); margin-bottom: 20px; animation: pulse 2s infinite; } @keyframes pulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.05); } } #intro-screen .subtitle { font-size: 1.5rem; color: #a0a0a0; margin-bottom: 40px; } #intro-screen .instructions { background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1); border-radius: 15px; padding: 30px; max-width: 600px; color: #ddd; line-height: 1.8; font-size: 1.1rem; margin-bottom: 40px; } #intro-screen .instructions h3 { color: #e94560; margin-bottom: 15px; font-size: 1.3rem; } #intro-screen .instructions ul { list-style: none; padding: 0; } #intro-screen .instructions li { padding: 8px 0; padding-left: 30px; position: relative; } #intro-screen .instructions li::before { content: "🎮"; position: absolute; left: 0; } #start-btn { padding: 18px 60px; font-size: 1.5rem; font-weight: bold; background: linear-gradient(45deg, #e94560, #ff6b6b); color: white; border: none; border-radius: 50px; cursor: pointer; box-shadow: 0 10px 30px rgba(233,69,96,0.4); transition: all 0.3s ease; } #start-btn:hover { transform: translateY(-3px); box-shadow: 0 15px 40px rgba(233,69,96,0.6); } /* === CANVAS === */ canvas { display: block; width: 100%; height: 100%; } /* === HUD === */ #hud { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 10; } /* Mini Map */ #minimap { position: absolute; bottom: 20px; left: 20px; width: 180px; height: 180px; background: rgba(0,0,0,0.7); border: 2px solid rgba(255,255,255,0.3); border-radius: 50%; overflow: hidden; pointer-events: auto; } #minimap-canvas { width: 100%; height: 100%; } /* Speedometer */ #speedometer { position: absolute; bottom: 20px; right: 20px; background: rgba(0,0,0,0.7); border: 2px solid rgba(255,255,255,0.3); border-radius: 15px; padding: 15px 25px; color: white; text-align: center; } #speed-value { font-size: 2.5rem; font-weight: bold; color: #4ecdc4; } #speed-label { font-size: 0.9rem; color: #888; } /* Timer */ #timer { position: absolute; top: 20px; left: 50%; transform: translateX(-50%); background: rgba(0,0,0,0.7); border: 2px solid rgba(255,255,255,0.3); border-radius: 15px; padding: 15px 40px; color: white; text-align: center; } #timer-value { font-size: 2.5rem; font-weight: bold; } #timer-value.warning { color: #ff6b6b; animation: blink 0.5s infinite; } @keyframes blink { 0%,100% { opacity: 1; } 50% { opacity: 0.3; } } #timer-label { font-size: 0.9rem; color: #888; } /* Navigation Arrow */ #nav-arrow { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 60px; height: 60px; pointer-events: none; z-index: 20; filter: drop-shadow(0 0 10px rgba(78,205,196,0.8)); } /* Distance to target */ #distance-to-target { position: absolute; top: 100px; left: 50%; transform: translateX(-50%); background: rgba(0,0,0,0.6); color: #4ecdc4; padding: 8px 20px; border-radius: 20px; font-size: 1rem; font-weight: bold; } /* Question Modal */ #question-modal { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.85); display: none; flex-direction: column; justify-content: center; align-items: center; z-index: 500; pointer-events: auto; } #question-modal.active { display: flex; } #question-box { background: linear-gradient(135deg, #1a1a2e, #16213e); border: 2px solid #e94560; border-radius: 20px; padding: 40px; max-width: 600px; width: 90%; text-align: center; box-shadow: 0 20px 60px rgba(0,0,0,0.5); } #question-text { font-size: 1.5rem; color: white; margin-bottom: 30px; line-height: 1.5; } .answer-btn { display: block; width: 100%; padding: 15px; margin: 10px 0; background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.2); border-radius: 10px; color: white; font-size: 1.1rem; cursor: pointer; transition: all 0.3s ease; text-align: left; padding-left: 20px; } .answer-btn:hover { background: rgba(233,69,96,0.2); border-color: #e94560; transform: translateX(5px); } .answer-btn.correct { background: rgba(46,204,113,0.3); border-color: #2ecc71; } .answer-btn.wrong { background: rgba(231,76,60,0.3); border-color: #e74c3c; } /* Feedback */ #feedback { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 3rem; font-weight: bold; padding: 20px 40px; border-radius: 15px; display: none; z-index: 600; animation: popIn 0.5s ease; } @keyframes popIn { 0% { transform: translate(-50%, -50%) scale(0); } 80% { transform: translate(-50%, -50%) scale(1.1); } 100% { transform: translate(-50%, -50%) scale(1); } } #feedback.correct { background: rgba(46,204,113,0.9); color: white; } #feedback.wrong { background: rgba(231,76,60,0.9); color: white; } /* Game Over */ #game-over { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.9); display: none; flex-direction: column; justify-content: center; align-items: center; z-index: 1000; pointer-events: auto; } #game-over.active { display: flex; } #game-over h2 { font-size: 3rem; color: #e94560; margin-bottom: 20px; } #game-over .stats { color: #ddd; font-size: 1.3rem; margin-bottom: 30px; line-height: 2; } #restart-btn { padding: 15px 50px; font-size: 1.3rem; background: #e94560; color: white; border: none; border-radius: 30px; cursor: pointer; transition: all 0.3s; } #restart-btn:hover { background: #ff6b6b; transform: scale(1.05); } /* Progress */ #progress { position: absolute; top: 20px; right: 20px; background: rgba(0,0,0,0.7); border: 2px solid rgba(255,255,255,0.3); border-radius: 15px; padding: 15px 20px; color: white; } #progress-text { font-size: 1.2rem; } /* Controls hint */ #controls-hint { position: absolute; bottom: 220px; left: 20px; background: rgba(0,0,0,0.6); color: #aaa; padding: 10px 15px; border-radius: 10px; font-size: 0.85rem; line-height: 1.6; } </style> </head> <body> <div id="game-container"> <!-- Intro Screen --> <div id="intro-screen"> <h1>🏙️ ŞEHİR BİLGİ YARIŞMASI</h1> <p class="subtitle">3D Açık Dünya Bilgi Yarışması</p> <div class="instructions"> <h3>🎮 Nasıl Oynanır?</h3> <ul> <li><strong>WASD</strong> veya <strong>Ok Tuşları</strong> ile aracı süz</li> <li>Haritadaki <strong>5 kırmızı noktaya</strong> git ve soruları cevapla</li> <li>Doğru cevap: <strong>+15 saniye</strong> kazan</li> <li>Yanlış cevap: <strong>-10 saniye</strong> kaybet</li> <li>Tüm soruları cevapla veya süre bitmeden bitir!</li> <li>Navigasyon oku sana hedefi gösterir</li> </ul> </div> <button id="start-btn" onclick="startGame()">🚗 OYUNA BAŞLA</button> </div> <!-- Canvas --> <canvas id="gameCanvas"></canvas> <!-- HUD --> <div id="hud" style="display:none;"> <div id="minimap"> <canvas id="minimap-canvas" width="180" height="180"></canvas> </div> <div id="controls-hint"> <strong>Kontroller:</strong><br> W / ↑ : İleri<br> S / ↓ : Geri<br> A / ← : Sola<br> D / → : Sağa<br> SPACE : Fren </div> <div id="speedometer"> <div id="speed-value">0</div> <div id="speed-label">km/h</div> </div> <div id="timer"> <div id="timer-value">120</div> <div id="timer-label">SANİYE</div> </div> <div id="distance-to-target">Hedefe Mesafe: -- m</div> <div id="progress"> <div id="progress-text">Soru: 0/5</div> </div> <svg id="nav-arrow" viewBox="0 0 100 100"> <polygon points="50,10 20,90 50,70 80,90" fill="#4ecdc4" stroke="white" stroke-width="2"/> </svg> </div> <!-- Question Modal --> <div id="question-modal"> <div id="question-box"> <div id="question-text">Soru burada görünecek...</div> <div id="answers-container"></div> </div> </div> <!-- Feedback --> <div id="feedback"></div> <!-- Game Over --> <div id="game-over"> <h2 id="game-over-title">Oyun Bitti!</h2> <div class="stats" id="game-over-stats"></div> <button id="restart-btn" onclick="restartGame()">🔄 Yeniden Başla</button> </div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <script> // ==================== GAME STATE ==================== let gameState = { started: false, paused: false, timeRemaining: 120, score: 0, questionsAnswered: 0, totalQuestions: 5, currentTarget: 0, targetsCompleted: [], gameOver: false }; // ==================== QUESTIONS ==================== const questions = [ { question: "Türkiye'nin başkenti hangi şehirdir?", answers: ["İstanbul", "Ankara", "İzmir", "Bursa"], correct: 1 }, { question: "Dünya üzerindeki en yüksek dağ hangisidir?", answers: ["K2", "Kilimanjaro", "Everest", "Aconcagua"], correct: 2 }, { question: "Hangi gezegen Güneş Sistemi'nde en büyüktür?", answers: ["Satürn", "Mars", "Jüpiter", "Neptün"], correct: 2 }, { question: "İnsan vücudunda kaç kemik vardır (yetişkin)?", answers: ["206", "208", "210", "212"], correct: 0 }, { question: "Hangi yıl Ay'a ilk kez ayak basıldı?", answers: ["1967", "1969", "1971", "1973"], correct: 1 } ]; // ==================== THREE.JS SETUP ==================== let scene, camera, renderer; let car, carBody, carWheels = []; let buildings = [], roads = [], trees = [], streetLights = []; let targets = []; let minimapCanvas, minimapCtx; // Car physics let carSpeed = 0; let carAngle = 0; const maxSpeed = 0.8; const acceleration = 0.02; const friction = 0.95; const turnSpeed = 0.04; // Input const keys = { w: false, a: false, s: false, d: false, space: false }; // City size const citySize = 400; const blockSize = 80; const roadWidth = 20; function init() { const canvas = document.getElementById('gameCanvas'); // Scene scene = new THREE.Scene(); scene.background = new THREE.Color(0x87CEEB); scene.fog = new THREE.Fog(0x87CEEB, 50, 300); // Camera camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(0, 30, 50); // Renderer renderer = new THREE.WebGLRenderer({ canvas: canvas, antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; // Lights const ambientLight = new THREE.AmbientLight(0xffffff, 0.4); scene.add(ambientLight); const sunLight = new THREE.DirectionalLight(0xffffff, 0.8); sunLight.position.set(100, 200, 100); sunLight.castShadow = true; sunLight.shadow.mapSize.width = 2048; sunLight.shadow.mapSize.height = 2048; sunLight.shadow.camera.near = 0.5; sunLight.shadow.camera.far = 500; sunLight.shadow.camera.left = -200; sunLight.shadow.camera.right = 200; sunLight.shadow.camera.top = 200; sunLight.shadow.camera.bottom = -200; scene.add(sunLight); // Ground const groundGeo = new THREE.PlaneGeometry(citySize * 2, citySize * 2); const groundMat = new THREE.MeshLambertMaterial({ color: 0x2d5a27 }); const ground = new THREE.Mesh(groundGeo, groundMat); ground.rotation.x = -Math.PI / 2; ground.receiveShadow = true; scene.add(ground); // Generate City generateCity(); // Create Car createCar(); // Create Targets createTargets(); // Minimap setup minimapCanvas = document.getElementById('minimap-canvas'); minimapCtx = minimapCanvas.getContext('2d'); // Event listeners window.addEventListener('keydown', onKeyDown); window.addEventListener('keyup', onKeyUp); window.addEventListener('resize', onWindowResize); // Start loop animate(); } function generateCity() { // Grid of roads const gridCount = Math.floor(citySize / blockSize); // Road material const roadMat = new THREE.MeshLambertMaterial({ color: 0x333333 }); const lineMat = new THREE.MeshBasicMaterial({ color: 0xFFD700 }); // Horizontal roads for (let i = -gridCount; i <= gridCount; i++) { const z = i * blockSize; const roadGeo = new THREE.PlaneGeometry(citySize * 2, roadWidth); const road = new THREE.Mesh(roadGeo, roadMat); road.rotation.x = -Math.PI / 2; road.position.set(0, 0.1, z); road.receiveShadow = true; scene.add(road); roads.push(road); // Center line const lineGeo = new THREE.PlaneGeometry(citySize * 2, 0.5); const line = new THREE.Mesh(lineGeo, lineMat); line.rotation.x = -Math.PI / 2; line.position.set(0, 0.2, z); scene.add(line); // Dashed lines for (let x = -citySize; x < citySize; x += 15) { const dashGeo = new THREE.PlaneGeometry(8, 0.8); const dash = new THREE.Mesh(dashGeo, lineMat); dash.rotation.x = -Math.PI / 2; dash.position.set(x, 0.21, z); scene.add(dash); } } // Vertical roads for (let i = -gridCount; i <= gridCount; i++) { const x = i * blockSize; const roadGeo = new THREE.PlaneGeometry(roadWidth, citySize * 2); const road = new THREE.Mesh(roadGeo, roadMat); road.rotation.x = -Math.PI / 2; road.position.set(x, 0.1, 0); road.receiveShadow = true; scene.add(road); roads.push(road); // Center line const lineGeo = new THREE.PlaneGeometry(0.5, citySize * 2); const line = new THREE.Mesh(lineGeo, lineMat); line.rotation.x = -Math.PI / 2; line.position.set(x, 0.2, 0); scene.add(line); // Dashed lines for (let z = -citySize; z < citySize; z += 15) { const dashGeo = new THREE.PlaneGeometry(0.8, 8); const dash = new THREE.Mesh(dashGeo, lineMat); dash.rotation.x = -Math.PI / 2; dash.position.set(x, 0.21, z); scene.add(dash); } } // Crosswalks at intersections for (let i = -gridCount; i <= gridCount; i++) { for (let j = -gridCount; j <= gridCount; j++) { const x = i * blockSize; const z = j * blockSize; // Crosswalk lines const cwMat = new THREE.MeshBasicMaterial({ color: 0xffffff }); for (let k = 0; k < 5; k++) { const cwGeo = new THREE.PlaneGeometry(2, roadWidth - 2); const cw = new THREE.Mesh(cwGeo, cwMat); cw.rotation.x = -Math.PI / 2; cw.position.set(x - 6 + k * 3, 0.22, z); scene.add(cw); } for (let k = 0; k < 5; k++) { const cwGeo = new THREE.PlaneGeometry(roadWidth - 2, 2); const cw = new THREE.Mesh(cwGeo, cwMat); cw.rotation.x = -Math.PI / 2; cw.position.set(x, 0.22, z - 6 + k * 3); scene.add(cw); } } } // Buildings const buildingColors = [0x1a1a2e, 0x16213e, 0x0f3460, 0x2c3e50, 0x34495e]; for (let i = -gridCount; i <= gridCount; i++) { for (let j = -gridCount; j <= gridCount; j++) { const x = i * blockSize; const z = j * blockSize; // Skip intersections if (Math.abs(x) < roadWidth && Math.abs(z) < roadWidth) continue; // Random building in each block if (Math.random() > 0.3) { const bx = x + (Math.random() - 0.5) * (blockSize - roadWidth - 10); const bz = z + (Math.random() - 0.5) * (blockSize - roadWidth - 10); const height = 20 + Math.random() * 60; const width = 15 + Math.random() * 20; const depth = 15 + Math.random() * 20; const geo = new THREE.BoxGeometry(width, height, depth); const color = buildingColors[Math.floor(Math.random() * buildingColors.length)]; const mat = new THREE.MeshLambertMaterial({ color: color }); const building = new THREE.Mesh(geo, mat); building.position.set(bx, height / 2, bz); building.castShadow = true; building.receiveShadow = true; scene.add(building); buildings.push(building); // Windows const windowMat = new THREE.MeshBasicMaterial({ color: 0x88ccff, transparent: true, opacity: 0.6 }); for (let wy = 5; wy < height - 5; wy += 8) { for (let wx = -width/2 + 3; wx < width/2 - 3; wx += 6) { const winGeo = new THREE.PlaneGeometry(3, 4); const win = new THREE.Mesh(winGeo, windowMat); win.position.set(bx + wx, wy, bz + depth/2 + 0.1); scene.add(win); const win2 = win.clone(); win2.position.set(bx + wx, wy, bz - depth/2 - 0.1); win2.rotation.y = Math.PI; scene.add(win2); } } } } } // Trees for (let i = 0; i < 80; i++) { const tx = (Math.random() - 0.5) * citySize * 1.5; const tz = (Math.random() - 0.5) * citySize * 1.5; // Don't place on roads const onRoad = Math.abs(tx % blockSize) < roadWidth/2 + 5 || Math.abs(tz % blockSize) < roadWidth/2 + 5; if (!onRoad) { createTree(tx, tz); } } // Street lights for (let i = -gridCount; i <= gridCount; i++) { for (let j = -gridCount; j <= gridCount; j++) { if (Math.random() > 0.5) { const lx = i * blockSize + roadWidth/2 + 3; const lz = j * blockSize; createStreetLight(lx, lz); } } } } function createTree(x, z) { const trunkGeo = new THREE.CylinderGeometry(0.5, 0.8, 4, 6); const trunkMat = new THREE.MeshLambertMaterial({ color: 0x8B4513 }); const trunk = new THREE.Mesh(trunkGeo, trunkMat); trunk.position.set(x, 2, z); trunk.castShadow = true; scene.add(trunk); const leavesGeo = new THREE.ConeGeometry(3, 8, 8); const leavesMat = new THREE.MeshLambertMaterial({ color: 0x228B22 }); const leaves = new THREE.Mesh(leavesGeo, leavesMat); leaves.position.set(x, 7, z); leaves.castShadow = true; scene.add(leaves); trees.push({ trunk, leaves }); } function createStreetLight(x, z) { const poleGeo = new THREE.CylinderGeometry(0.2, 0.3, 12, 8); const poleMat = new THREE.MeshLambertMaterial({ color: 0x555555 }); const pole = new THREE.Mesh(poleGeo, poleMat); pole.position.set(x, 6, z); scene.add(pole); const lampGeo = new THREE.SphereGeometry(1, 8, 8); const lampMat = new THREE.MeshBasicMaterial({ color: 0xffffcc }); const lamp = new THREE.Mesh(lampGeo, lampMat); lamp.position.set(x, 12, z); scene.add(lamp); const light = new THREE.PointLight(0xffffcc, 0.5, 30); light.position.set(x, 11, z); scene.add(light); streetLights.push({ pole, lamp, light }); } function createCar() { car = new THREE.Group(); // Car body const bodyGeo = new THREE.BoxGeometry(4, 1.5, 8); const bodyMat = new THREE.MeshLambertMaterial({ color: 0xe74c3c }); carBody = new THREE.Mesh(bodyGeo, bodyMat); carBody.position.y = 1.2; carBody.castShadow = true; car.add(carBody); // Car top const topGeo = new THREE.BoxGeometry(3, 1, 4); const topMat = new THREE.MeshLambertMaterial({ color: 0xc0392b }); const top = new THREE.Mesh(topGeo, topMat); top.position.set(0, 2.5, -0.5); top.castShadow = true; car.add(top); // Windshield const windGeo = new THREE.PlaneGeometry(2.8, 1.5); const windMat = new THREE.MeshBasicMaterial({ color: 0x88ccff, transparent: true, opacity: 0.5 }); const wind = new THREE.Mesh(windGeo, windMat); wind.position.set(0, 2.5, 1.51); car.add(wind); // Wheels const wheelGeo = new THREE.CylinderGeometry(0.6, 0.6, 0.5, 12); const wheelMat = new THREE.MeshLambertMaterial({ color: 0x222222 }); const positions = [ [-2.2, 0.6, 2.5], [2.2, 0.6, 2.5], [-2.2, 0.6, -2.5], [2.2, 0.6, -2.5] ]; positions.forEach(pos => { const wheel = new THREE.Mesh(wheelGeo, wheelMat); wheel.rotation.z = Math.PI / 2; wheel.position.set(...pos); wheel.castShadow = true; car.add(wheel); carWheels.push(wheel); }); // Headlights const lightGeo = new THREE.SphereGeometry(0.3, 8, 8); const lightMat = new THREE.MeshBasicMaterial({ color: 0xffffcc }); const hl1 = new THREE.Mesh(lightGeo, lightMat); hl1.position.set(-1.2, 1.2, 4.1); car.add(hl1); const hl2 = new THREE.Mesh(lightGeo, lightMat); hl2.position.set(1.2, 1.2, 4.1); car.add(hl2); // Headlight beams const beam1 = new THREE.SpotLight(0xffffcc, 0.5, 50, Math.PI/6, 0.5); beam1.position.set(-1.2, 1.2, 4); beam1.target.position.set(-1.2, 0, 10); car.add(beam1); car.add(beam1.target); const beam2 = new THREE.SpotLight(0xffffcc, 0.5, 50, Math.PI/6, 0.5); beam2.position.set(1.2, 1.2, 4); beam2.target.position.set(1.2, 0, 10); car.add(beam2); car.add(beam2.target); // Taillights const tailMat = new THREE.MeshBasicMaterial({ color: 0xff0000 }); const tl1 = new THREE.Mesh(lightGeo, tailMat); tl1.position.set(-1.2, 1.2, -4.1); car.add(tl1); const tl2 = new THREE.Mesh(lightGeo, tailMat); tl2.position.set(1.2, 1.2, -4.1); car.add(tl2); car.position.set(0, 0, 0); scene.add(car); } function createTargets() { const targetPositions = [ { x: 120, z: 120 }, { x: -120, z: 120 }, { x: -120, z: -120 }, { x: 120, z: -120 }, { x: 0, z: 200 } ]; targetPositions.forEach((pos, index) => { // Platform const platformGeo = new THREE.CylinderGeometry(8, 8, 0.5, 16); const platformMat = new THREE.MeshLambertMaterial({ color: 0xe94560 }); const platform = new THREE.Mesh(platformGeo, platformMat); platform.position.set(pos.x, 0.3, pos.z); scene.add(platform); // Glowing pillar const pillarGeo = new THREE.CylinderGeometry(1, 1, 15, 8); const pillarMat = new THREE.MeshBasicMaterial({ color: 0xe94560, transparent: true, opacity: 0.7 }); const pillar = new THREE.Mesh(pillarGeo, pillarMat); pillar.position.set(pos.x, 7.5, pos.z); scene.add(pillar); // Light const light = new THREE.PointLight(0xe94560, 1, 30); light.position.set(pos.x, 10, pos.z); scene.add(light); // Floating ring const ringGeo = new THREE.TorusGeometry(3, 0.3, 8, 16); const ringMat = new THREE.MeshBasicMaterial({ color: 0xffd700 }); const ring = new THREE.Mesh(ringGeo, ringMat); ring.position.set(pos.x, 8, pos.z); ring.rotation.x = Math.PI / 2; scene.add(ring); targets.push({ position: new THREE.Vector3(pos.x, 0, pos.z), platform, pillar, light, ring, index: index, completed: false }); }); } // ==================== INPUT HANDLING ==================== function onKeyDown(e) { const key = e.key.toLowerCase(); if (key === 'w' || key === 'arrowup') keys.w = true; if (key === 'a' || key === 'arrowleft') keys.a = true; if (key === 's' || key === 'arrowdown') keys.s = true; if (key === 'd' || key === 'arrowright') keys.d = true; if (key === ' ') keys.space = true; } function onKeyUp(e) { const key = e.key.toLowerCase(); if (key === 'w' || key === 'arrowup') keys.w = false; if (key === 'a' || key === 'arrowleft') keys.a = false; if (key === 's' || key === 'arrowdown') keys.s = false; if (key === 'd' || key === 'arrowright') keys.d = false; if (key === ' ') keys.space = false; } function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } // ==================== GAME LOGIC ==================== function updateCar() { if (!gameState.started || gameState.paused || gameState.gameOver) return; // Acceleration if (keys.w) carSpeed += acceleration; if (keys.s) carSpeed -= acceleration; // Braking if (keys.space) carSpeed *= 0.9; // Friction carSpeed *= friction; // Max speed if (carSpeed > maxSpeed) carSpeed = maxSpeed; if (carSpeed < -maxSpeed / 2) carSpeed = -maxSpeed / 2; // Stop if very slow if (Math.abs(carSpeed) < 0.001) carSpeed = 0; // Turning if (Math.abs(carSpeed) > 0.01) { if (keys.a) carAngle += turnSpeed * Math.sign(carSpeed); if (keys.d) carAngle -= turnSpeed * Math.sign(carSpeed); } // Update position car.position.x += Math.sin(carAngle) * carSpeed; car.position.z += Math.cos(carAngle) * carSpeed; // Rotation car.rotation.y = carAngle; // Wheel animation carWheels.forEach(wheel => { wheel.rotation.x += carSpeed * 0.5; }); // Boundary check const bound = citySize - 10; if (car.position.x > bound) car.position.x = bound; if (car.position.x < -bound) car.position.x = -bound; if (car.position.z > bound) car.position.z = bound; if (car.position.z < -bound) car.position.z = -bound; } function updateCamera() { if (!car) return; // Chase camera const distance = 25; const height = 15; const offsetX = car.position.x - Math.sin(carAngle) * distance; const offsetZ = car.position.z - Math.cos(carAngle) * distance; camera.position.x += (offsetX - camera.position.x) * 0.1; camera.position.z += (offsetZ - camera.position.z) * 0.1; camera.position.y += (height - camera.position.y) * 0.1; camera.lookAt(car.position.x, 2, car.position.z); } function updateTargets() { if (!gameState.started || gameState.paused || gameState.gameOver) return; const currentTarget = getCurrentTarget(); if (!currentTarget) return; const dist = car.position.distanceTo(currentTarget.position); // Animate ring currentTarget.ring.rotation.z += 0.02; currentTarget.ring.position.y = 8 + Math.sin(Date.now() * 0.002) * 1; // Check proximity if (dist < 10 && !gameState.paused) { showQuestion(currentTarget.index); } // Update distance display document.getElementById('distance-to-target').textContent = `Hedefe Mesafe: ${Math.floor(dist)} m`; } function getCurrentTarget() { for (let target of targets) { if (!target.completed) return target; } return null; } function updateNavigationArrow() { const currentTarget = getCurrentTarget(); const arrow = document.getElementById('nav-arrow'); if (!currentTarget || !gameState.started) { arrow.style.display = 'none'; return; } arrow.style.display = 'block'; // Calculate angle to target const dx = currentTarget.position.x - car.position.x; const dz = currentTarget.position.z - car.position.z; const targetAngle = Math.atan2(dx, dz); // Relative angle let relativeAngle = targetAngle - carAngle; // Normalize while (relativeAngle > Math.PI) relativeAngle -= Math.PI * 2; while (relativeAngle < -Math.PI) relativeAngle += Math.PI * 2; // Convert to degrees and rotate arrow const degrees = relativeAngle * (180 / Math.PI); arrow.style.transform = `translate(-50%, -50%) rotate(${degrees}deg)`; } function updateMinimap() { if (!minimapCtx || !car) return; const ctx = minimapCtx; const w = minimapCanvas.width; const h = minimapCanvas.height; const scale = w / (citySize * 2.5); const cx = w / 2; const cy = h / 2; // Clear ctx.fillStyle = '#1a1a2e'; ctx.fillRect(0, 0, w, h); // Draw roads ctx.strokeStyle = '#333'; ctx.lineWidth = 3; const gridCount = Math.floor(citySize / blockSize); for (let i = -gridCount; i <= gridCount; i++) { const pos = i * blockSize * scale; ctx.beginPath(); ctx.moveTo(cx + pos, 0); ctx.lineTo(cx + pos, h); ctx.stroke(); ctx.beginPath(); ctx.moveTo(0, cy + pos); ctx.lineTo(w, cy + pos); ctx.stroke(); } // Draw targets targets.forEach(target => { const tx = cx + target.position.x * scale; const tz = cy + target.position.z * scale; ctx.fillStyle = target.completed ? '#2ecc71' : '#e94560'; ctx.beginPath(); ctx.arc(tx, tz, 6, 0, Math.PI * 2); ctx.fill(); ctx.strokeStyle = '#fff'; ctx.lineWidth = 1; ctx.stroke(); }); // Draw car const carX = cx + car.position.x * scale; const carZ = cy + car.position.z * scale; ctx.fillStyle = '#4ecdc4'; ctx.beginPath(); ctx.arc(carX, carZ, 5, 0, Math.PI * 2); ctx.fill(); // Car direction ctx.strokeStyle = '#4ecdc4'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(carX, carZ); ctx.lineTo( carX + Math.sin(carAngle) * 12, carZ + Math.cos(carAngle) * 12 ); ctx.stroke(); // Draw circle border ctx.strokeStyle = 'rgba(255,255,255,0.3)'; ctx.lineWidth = 2; ctx.beginPath(); ctx.arc(w/2, h/2, w/2 - 1, 0, Math.PI * 2); ctx.stroke(); } // ==================== QUESTION SYSTEM ==================== function showQuestion(targetIndex) { gameState.paused = true; carSpeed = 0; const modal = document.getElementById('question-modal'); const questionText = document.getElementById('question-text'); const answersContainer = document.getElementById('answers-container'); const q = questions[targetIndex]; questionText.textContent = q.question; answersContainer.innerHTML = ''; q.answers.forEach((answer, i) => { const btn = document.createElement('button'); btn.className = 'answer-btn'; btn.textContent = `${String.fromCharCode(65 + i)}) ${answer}`; btn.onclick = () => answerQuestion(targetIndex, i, btn); answersContainer.appendChild(btn); }); modal.classList.add('active'); } function answerQuestion(targetIndex, answerIndex, btn) { const q = questions[targetIndex]; const isCorrect = answerIndex === q.correct; // Visual feedback on buttons const buttons = document.querySelectorAll('.answer-btn'); buttons.forEach((b, i) => { if (i === q.correct) b.classList.add('correct'); else if (i === answerIndex && !isCorrect) b.classList.add('wrong'); }); // Show feedback showFeedback(isCorrect); // Update game state if (isCorrect) { gameState.timeRemaining += 15; gameState.score += 100; } else { gameState.timeRemaining -= 10; } // Mark target as completed targets[targetIndex].completed = true; gameState.questionsAnswered++; // Update progress document.getElementById('progress-text').textContent = `Soru: ${gameState.questionsAnswered}/${gameState.totalQuestions}`; // Close modal after delay setTimeout(() => { document.getElementById('question-modal').classList.remove('active'); gameState.paused = false; // Check win condition if (gameState.questionsAnswered >= gameState.totalQuestions) { endGame(true); } }, 2000); } function showFeedback(isCorrect) { const feedback = document.getElementById('feedback'); feedback.textContent = isCorrect ? '✅ DOĞRU! +15 sn' : '❌ YANLIŞ! -10 sn'; feedback.className = isCorrect ? 'correct' : 'wrong'; feedback.style.display = 'block'; setTimeout(() => { feedback.style.display = 'none'; }, 1500); } // ==================== TIMER ==================== let lastTime = Date.now(); function updateTimer() { if (!gameState.started || gameState.paused || gameState.gameOver) return; const now = Date.now(); const delta = (now - lastTime) / 1000; lastTime = now; gameState.timeRemaining -= delta; if (gameState.timeRemaining <= 0) { gameState.timeRemaining = 0; endGame(false); } const timerEl = document.getElementById('timer-value'); timerEl.textContent = Math.ceil(gameState.timeRemaining); if (gameState.timeRemaining <= 20) { timerEl.classList.add('warning'); } else { timerEl.classList.remove('warning'); } } // ==================== GAME FLOW ==================== function startGame() { document.getElementById('intro-screen').style.opacity = '0'; setTimeout(() => { document.getElementById('intro-screen').style.display = 'none'; }, 1000); document.getElementById('hud').style.display = 'block'; gameState.started = true; gameState.timeRemaining = 120; gameState.score = 0; gameState.questionsAnswered = 0; gameState.gameOver = false; gameState.paused = false; // Reset targets targets.forEach(t => t.completed = false); // Reset car car.position.set(0, 0, 0); carAngle = 0; carSpeed = 0; lastTime = Date.now(); document.getElementById('progress-text').textContent = 'Soru: 0/5'; } function endGame(won) { gameState.gameOver = true; gameState.started = false; const gameOverScreen = document.getElementById('game-over'); const title = document.getElementById('game-over-title'); const stats = document.getElementById('game-over-stats'); if (won) { title.textContent = '🎉 TEBRİKLER!'; title.style.color = '#2ecc71'; } else { title.textContent = '⏰ SÜRE DOLDU!'; title.style.color = '#e94560'; } stats.innerHTML = ` Cevaplanan Soru: ${gameState.questionsAnswered}/${gameState.totalQuestions}<br> Puan: ${gameState.score}<br> Kalan Süre: ${Math.ceil(gameState.timeRemaining)} sn `; gameOverScreen.classList.add('active'); } function restartGame() { document.getElementById('game-over').classList.remove('active'); startGame(); } // ==================== ANIMATION LOOP ==================== function animate() { requestAnimationFrame(animate); updateCar(); updateCamera(); updateTargets(); updateNavigationArrow(); updateMinimap(); updateTimer(); // Update speedometer const speedKmh = Math.abs(Math.round(carSpeed * 100)); document.getElementById('speed-value').textContent = speedKmh; renderer.render(scene, camera); } // Initialize window.onload = init; </script> </body> </html>
Landing Page
This ad does not have a landing page available
Network Timeline
Performance Summary

2

Requests

2

Domains

162KB

Transfer Size

633KB

Content Size

304.0ms

Dom Content Loaded

296.0ms

First Paint

305.0ms

Load Time
Domain Breakdown
Transfer Size (bytes)
Loading...
Content Size (bytes)
Loading...
Header Size (bytes)
Loading...
Requests
Loading...
Timings (ms)
Loading...
Total Time
Loading...
Content Breakdown
Transfer Size (bytes)
Loading...
Content Size (bytes)
Loading...
Header Size (bytes)
Loading...
Requests
Loading...