|
|
| 38. satır: |
38. satır: |
|
| |
|
| ==Nota== | | ==Nota== |
| ==Oyun==
| |
|
| |
| <meta charset="UTF-8">
| |
| <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
| |
| <title>Şubadap - Kabuk Kırma Partisi</title>
| |
| <link href="https://fonts.googleapis.com/css2?family=Quicksand:wght@500;700&display=swap" rel="stylesheet">
| |
| <style>
| |
| * { box-sizing: border-box; }
| |
| body {
| |
| background-color: #ff8d02; color: white;
| |
| font-family: 'Quicksand', sans-serif; text-align: center;
| |
| margin: 0;
| |
| /* Overflow: hidden kaldırıldı, height auto yapıldı */
| |
| overflow-x: hidden;
| |
| min-height: 850px;
| |
| touch-action: manipulation;
| |
| }
| |
| #ui {
| |
| height: 80px; display: flex; flex-direction: column; justify-content: center;
| |
| background: rgba(0,0,0,0.9); border-bottom: 2px solid #333;
| |
| }
| |
| #score-row { font-size: 24px; }
| |
| #combo-row { font-size: 16px; color: #ffb600; font-weight: bold; height: 20px; }
| |
| #score { color: #e14882; font-weight: 700; }
| |
|
| |
| #game {
| |
| width: 100%; max-width: 420px;
| |
| /* Yükseklik 600px olarak sabitlendi, böylece alt butonlar görünür kalır */
| |
| height: 600px;
| |
| background: #221917; margin: 0 auto; position: relative;
| |
| display: flex; overflow: hidden; border-bottom: 2px solid #444;
| |
| }
| |
|
| |
| #lyrics-container {
| |
| position: absolute; width: 100%; height: 100%; top: 0; left: 0;
| |
| display: flex; justify-content: center; align-items: center;
| |
| pointer-events: none; z-index: 1; opacity: 0.2;
| |
| font-size: 22px; text-align: center; color: #fff; font-weight: bold;
| |
| }
| |
|
| |
| .lane { flex: 1; height: 100%; border-right: 1px solid #333; position: relative; z-index: 2; }
| |
| .lane.glow { background: rgba(255, 255, 255, 0.15); box-shadow: inset 0 -20px 30px rgba(255,255,255,0.1); }
| |
| .note { position: absolute; width: 100%; left: 0; height: 18px; z-index: 10; border-radius: 4px; transform: translateY(-50%); }
| |
|
| |
| #hit-zone { position: absolute; bottom: 0; width: 100%; height: 12px; background: rgba(255,255,255,0.2); border-top: 2px solid white; box-shadow: 0 -5px 20px white; z-index: 5; }
| |
|
| |
| #controls { width: 100%; max-width: 420px; height: 90px; margin: 0 auto; display: flex; background: #000; }
| |
| .m-btn { flex: 1; display: flex; justify-content: center; align-items: center; cursor: pointer; position: relative; transition: 0.1s; }
| |
| .m-btn.pressed { background: rgba(255, 255, 255, 0.3); transform: scale(0.95); }
| |
| .btn-circle { width: 60px; height: 60px; border-radius: 50%; border: 4px solid; display: flex; justify-content: center; align-items: center; font-size: 24px; font-weight: 700; color: white; }
| |
| #btn0 .btn-circle { border-color: #e14882; } #btn1 .btn-circle { border-color: #ffb600; }
| |
| #btn2 .btn-circle { border-color: #0cc0df; } #btn3 .btn-circle { border-color: #eb5c25; }
| |
|
| |
| .screen { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: #221917; z-index: 100; display: flex; flex-direction: column; justify-content: center; align-items: center; padding: 20px; }
| |
| input { padding: 12px; border-radius: 8px; border: none; font-family: 'Quicksand'; font-size: 18px; margin-bottom: 15px; text-align: center; width: 220px; color: #333; }
| |
| .how-to { font-size: 15px; color: #ccc; margin-bottom: 25px; line-height: 1.6; max-width: 300px; }
| |
| button { padding: 15px 30px; font-size: 18px; background: #e14882; border: none; font-weight: 700; border-radius: 12px; cursor: pointer; color: #fff; font-family: 'Quicksand'; margin: 5px; }
| |
| button.share-btn { background: #0cc0df; }
| |
|
| |
| .feedback { position: absolute; bottom: 60px; width: 100%; text-align: center; font-size: 30px; font-weight: 700; animation: scorePop 0.5s forwards; z-index: 20; pointer-events: none; }
| |
| @keyframes scorePop { 0% { opacity: 0; transform: scale(0.5); } 30% { opacity: 1; transform: scale(1.2); } 100% { opacity: 0; transform: translateY(-70px); } }
| |
|
| |
| /* "Adını Yaz..." yazısını BEYAZ yapmak için en güçlü kural */
| |
| #username::placeholder {
| |
| color: #ffffff !important;
| |
| opacity: 1 !important;
| |
| }
| |
|
| |
| /* Chrome, Safari ve Opera için */
| |
| #username::-webkit-input-placeholder {
| |
| color: #ffffff !important;
| |
| opacity: 1 !important;
| |
| }
| |
|
| |
| /* Firefox için */
| |
| #username::-moz-placeholder {
| |
| color: #ffffff !important;
| |
| opacity: 1 !important;
| |
| }
| |
|
| |
| /* Internet Explorer ve Edge için */
| |
| #username:-ms-input-placeholder {
| |
| color: #ffffff !important;
| |
| opacity: 1 !important;
| |
| }
| |
|
| |
| /* Kullanıcı adını yazarken kutunun içindeki harflerin rengi */
| |
| #username {
| |
| color: #ffffff !important;
| |
| background: rgba(255, 255, 255, 0.1) !important; /* Kutunun içini hafif şeffaf yapar, daha şık durur */
| |
| border: 1px solid #ffffff !important; /* Kutunun etrafına ince beyaz bir hat çeker */
| |
| }
| |
|
| |
| </style>
| |
|
| |
|
| |
|
| |
| <div id="ui">
| |
| <div id="score-row">Puan: <span id="score">0</span></div>
| |
| <div id="combo-row"></div>
| |
| </div>
| |
|
| |
| <div id="progress-container" style="width: 100%; height: 6px; background: #333; position: relative;">
| |
| <div id="progress-bar" style="width: 0%; height: 100%; background: #0cc0df; transition: width 0.1s linear;"></div>
| |
| </div>
| |
|
| |
| <div id="game">
| |
| <div id="start-screen" class="screen">
| |
| <div style="font-size: 40px; margin-bottom: 20px;">🎸</div>
| |
| <input type="text" id="username" placeholder="Adını Yaz..." maxlength="12">
| |
| <div class="how-to">
| |
| Çubuklar en alt çizgiye değdiğinde<br> <b>A S D F</b>'ye bas.<br>
| |
| 🔥 5 Seri = 2 Kat Puan! <br> ⚠️ 3 Iskala = -10 Puan!
| |
| </div>
| |
| <button onclick="checkUser()">OYUNA BAŞLA 🎸</button>
| |
| </div>
| |
|
| |
| <div id="end-screen" class="screen" style="display: none;">
| |
| <h1 style="color: #fbff00;">TEBRİKLER <span id="display-username"></span>!</h1>
| |
| <div style="font-size: 60px; color: #fff; margin: 10px 0;" id="total-score">0</div>
| |
| <div style="display: flex; gap: 10px;">
| |
| <button onclick="resetGame()">TEKRAR 🔄</button>
| |
| <button class="share-btn" onclick="shareScore()">PAYLAŞ 🔗</button>
| |
| </div>
| |
| </div>
| |
|
| |
| <div id="lyrics-container"></div>
| |
| <div id="hit-zone"></div>
| |
| <div class="lane" id="lane0"></div><div class="lane" id="lane1"></div>
| |
| <div class="lane" id="lane2"></div><div class="lane" id="lane3"></div>
| |
| </div>
| |
|
| |
| <div id="controls">
| |
| <div class="m-btn" id="btn0" onmousedown="handleInput(0)" ontouchstart="handleInput(0)"><div class="btn-circle">A</div></div>
| |
| <div class="m-btn" id="btn1" onmousedown="handleInput(1)" ontouchstart="handleInput(1)"><div class="btn-circle">S</div></div>
| |
| <div class="m-btn" id="btn2" onmousedown="handleInput(2)" ontouchstart="handleInput(2)"><div class="btn-circle">D</div></div>
| |
| <div class="m-btn" id="btn3" onmousedown="handleInput(3)" ontouchstart="handleInput(3)"><div class="btn-circle">F</div></div>
| |
| </div>
| |
|
| |
| <audio id="audio" src="https://files.catbox.moe/1dtgqd.mp3"></audio>
| |
|
| |
| <script>
| |
| const audio = document.getElementById("audio");
| |
| const lanes = [document.getElementById("lane0"), document.getElementById("lane1"), document.getElementById("lane2"), document.getElementById("lane3")];
| |
| const scoreEl = document.getElementById("score");
| |
| const comboEl = document.getElementById("combo-row");
| |
|
| |
| let score = 0; let comboCount = 0; let missCount = 0;
| |
| let active = []; let userName = "";
| |
| let gameRunning = false;
| |
|
| |
| const OFFSET = 0.05;
| |
| const FALL_DURATION = 2.0;
| |
| const laneColors = ["#e14882", "#ffb600", "#0cc0df", "#eb5c25"];
| |
|
| |
| const lyrics = [
| |
| { t: 6, text: "Tak tak tak" }, { t: 10, text: "Tak tak tak" }, { t: 13, text: "Tak tak tak" }, { t: 18, text: "Tak tak tak" },
| |
| { t: 22, text: "Kabuk kırma partisi burada" }, { t: 27, text: "Hoş geldiniz..." }, { t: 30, text: "Kabuk kırma partisi burada" }, { t: 37, text: "Hoş geldiniz..." }, { t: 38, text: "Kabukları var herkesin" },
| |
| { t: 42, text: "Birini kır diğeri gelsin" }, { t: 46, text: "Zor ama eğlenceli" }, { t: 49, text: "Kabuk kırma partisi" }, { t: 53, text: "Başlıyor..." }, { t: 57, text: "Kelebekler kabuğunu kırar" }, { t: 61, text: "Tak tak tak" }, { t: 64, text: "Civcivler kabuğunu kırar" }, { t: 67, text: "Tak tak tak" }, { t: 71, text: "Tohumlar kabuğunu kırar" }, { t: 74, text: "Tak tak tak" }, { t: 79, text: "Çocuklar kabuğunu kırar" }, { t: 82, text: "Tak tak tak" },
| |
| ];
| |
|
| |
| let notes = [
| |
| { time: 7.82, lane: 0 }, { time: 7.98, lane: 1 }, { time: 8.20, lane: 2 }, { time: 11.47, lane: 1 }, { time: 11.62, lane: 2 }, { time: 11.86, lane: 3 },
| |
| { time: 15.16, lane: 3 }, { time: 15.35, lane: 2 }, { time: 15.57, lane: 1 }, { time: 17.02, lane: 0 }, { time: 17.20, lane: 1 }, { time: 17.44, lane: 2 },
| |
| { time: 18.87, lane: 1 }, { time: 19.03, lane: 2 }, { time: 19.26, lane: 3 }, { time: 22.62, lane: 0 }, { time: 23.53, lane: 1 }, { time: 24.44, lane: 3 },
| |
| { time: 26.29, lane: 2 }, { time: 28.05, lane: 0 }, { time: 29.95, lane: 0 }, { time: 30.89, lane: 1 }, { time: 31.79, lane: 2 }, { time: 33.64, lane: 3 }, { time: 37.37, lane: 1 },
| |
| { time: 39.25, lane: 0 }, { time: 39.58, lane: 1 }, { time: 40.22, lane: 0 }, { time: 42.90, lane: 3 }, { time: 43.34, lane: 2 }, { time: 43.65, lane: 1 }, { time: 44.05, lane: 0 },
| |
| { time: 46.63, lane: 0 }, { time: 47.09, lane: 1 }, { time: 47.51, lane: 2 }, { time: 50.27, lane: 1 }, { time: 50.67, lane: 2 }, { time: 51.16, lane: 3 },
| |
| { time: 53.95, lane: 2 }, { time: 57.63, lane: 1 }, { time: 59.49, lane: 2 }, { time: 60.46, lane: 3 }, { time: 61.38, lane: 0 }, { time: 61.55, lane: 1 },
| |
| { time: 61.77, lane: 2 }, { time: 65.07, lane: 3 }, { time: 66.87, lane: 2 }, { time: 67.80, lane: 1 }, { time: 68.72, lane: 1 }, { time: 68.89, lane: 2 },
| |
| { time: 69.11, lane: 3 }, { time: 72.43, lane: 0 }, { time: 74.29, lane: 1 }, { time: 75.26, lane: 3 }, { time: 76.12, lane: 2 }, { time: 76.32, lane: 1 },
| |
| { time: 76.51, lane: 0 }, { time: 79.78, lane: 0 }, { time: 81.62, lane: 1 }, { time: 82.55, lane: 3 }, { time: 83.43, lane: 1 }, { time: 83.63, lane: 2 },
| |
| { time: 83.90, lane: 3 }, { time: 87.20, lane: 1 }, { time: 87.36, lane: 2 }, { time: 87.62, lane: 3 }, { time: 90.88, lane: 0 },
| |
| { time: 91.03, lane: 1 }, { time: 91.25, lane: 2 }, { time: 94.56, lane: 1 }, { time: 94.72, lane: 2 }, { time: 94.97, lane: 3 }, { time: 96.47, lane: 0 },
| |
| { time: 96.62, lane: 1 }, { time: 96.82, lane: 2 }, { time: 98.24, lane: 1 }, { time: 98.41, lane: 2 }, { time: 98.61, lane: 3 }, { time: 101.98, lane: 0 },
| |
| { time: 102.93, lane: 1 }, { time: 103.79, lane: 3 }, { time: 105.64, lane: 0 }, { time: 107.50, lane: 1 }, { time: 109.36, lane: 2 }, { time: 110.28, lane: 0 },
| |
| { time: 111.20, lane: 1 }, { time: 113.04, lane: 3 }, { time: 116.74, lane: 2 }, { time: 118.76, lane: 0 },
| |
| { time: 119.14, lane: 1 },
| |
| { time: 119.63, lane: 2 }, { time: 122.26, lane: 2 },
| |
| { time: 122.69, lane: 1 }, { time: 122.98, lane: 0 }, { time: 123.40, lane: 3 }, { time: 125.98, lane: 1 }, { time: 126.43, lane: 2 }, { time: 126.84, lane: 3 },
| |
| { time: 129.66, lane: 0 }, { time: 130.09, lane: 1 }, { time: 130.52, lane: 2 }, { time: 133.28, lane: 1 }, { time: 137.01, lane: 3 }, { time: 138.86, lane: 2 },
| |
| { time: 139.74, lane: 0 }, { time: 140.68, lane: 1 }, { time: 140.87, lane: 2 }, { time: 141.12, lane: 3 }, { time: 144.38, lane: 0 }, { time: 146.24, lane: 3 },
| |
| { time: 147.17, lane: 1 }, { time: 148.09, lane: 2 }, { time: 148.28, lane: 1 }, { time: 148.49, lane: 0 }, { time: 151.84, lane: 1 }, { time: 153.66, lane: 2 },
| |
| { time: 154.58, lane: 3 }, { time: 155.51, lane: 0 }, { time: 155.68, lane: 1 }, { time: 155.92, lane: 2 }, { time: 159.22, lane: 3 }, { time: 161.03, lane: 2 },
| |
| { time: 161.95, lane: 0 }, { time: 162.87, lane: 1 }, { time: 163.06, lane: 2 }, { time: 163.29, lane: 3 }, { time: 166.57, lane: 1 }, { time: 166.75, lane: 2 },
| |
| { time: 166.99, lane: 3 }, { time: 167.47, lane: 0 }, { time: 170.28, lane: 1 }, { time: 170.45, lane: 2 }, { time: 170.69, lane: 3 }, { time: 171.14, lane: 0 },
| |
| { time: 173.96, lane: 3 }, { time: 174.13, lane: 2 }, { time: 174.36, lane: 1 }, { time: 174.84, lane: 0 }, { time: 175.76, lane: 0 }, { time: 175.97, lane: 1 },
| |
| { time: 176.24, lane: 2 }, { time: 176.70, lane: 3 }, { time: 177.65, lane: 1 }, { time: 177.83, lane: 0 }, { time: 178.13, lane: 2 }, { time: 178.57, lane: 3 },
| |
| { time: 179.50, lane: 2 }, { time: 180.02, lane: 1 }, { time: 180.47, lane: 0 }
| |
| ];
| |
|
| |
| function checkUser() {
| |
| userName = document.getElementById("username").value.trim();
| |
| if (userName.length < 2) { alert("Lütfen adını yaz!"); return; }
| |
| startGame();
| |
| }
| |
|
| |
| function startGame() {
| |
| gameRunning = true;
| |
| document.getElementById("start-screen").style.display = "none";
| |
| document.getElementById("end-screen").style.display = "none";
| |
| audio.currentTime = 0;
| |
| audio.play();
| |
| requestAnimationFrame(gameLoop);
| |
| }
| |
|
| |
| function gameLoop() {
| |
| if (!gameRunning) return;
| |
| const t = audio.currentTime;
| |
| const height = document.getElementById("game").offsetHeight;
| |
|
| |
| if (t >= 181.65 || audio.ended) {
| |
| saveAndShowScore();
| |
| return;
| |
| }
| |
|
| |
| lyrics.forEach(l => {
| |
| if (!l.shown && t >= l.t) {
| |
| document.getElementById("lyrics-container").innerText = l.text;
| |
| l.shown = true;
| |
| setTimeout(() => { if(document.getElementById("lyrics-container").innerText === l.text) document.getElementById("lyrics-container").innerText = ""; }, 3000);
| |
| }
| |
| });
| |
|
| |
| notes.forEach(n => {
| |
| if (!n.spawned && t > n.time + OFFSET - FALL_DURATION) {
| |
| const el = document.createElement("div");
| |
| el.className = "note"; el.style.background = laneColors[n.lane];
| |
| lanes[n.lane].appendChild(el);
| |
| active.push({ ...n, el }); n.spawned = true;
| |
| }
| |
| });
| |
|
| |
| active.forEach((n, i) => {
| |
| let y = height - (n.time + OFFSET - t) * (height / FALL_DURATION);
| |
| n.el.style.top = y + "px";
| |
| if (y > height + 50) {
| |
| processMiss(n.lane);
| |
| n.el.remove(); active.splice(i, 1);
| |
| }
| |
| });
| |
| requestAnimationFrame(gameLoop);
| |
| }
| |
|
| |
| function handleInput(laneId) {
| |
| const btn = document.getElementById('btn' + laneId);
| |
| btn.classList.add('pressed');
| |
| setTimeout(() => btn.classList.remove('pressed'), 100);
| |
|
| |
| lanes[laneId].classList.add("glow");
| |
| setTimeout(() => lanes[laneId].classList.remove("glow"), 100);
| |
|
| |
| const t = audio.currentTime;
| |
| active.forEach((n, i) => {
| |
| const diff = Math.abs((n.time + OFFSET) - t);
| |
| if (n.lane === laneId && diff < 0.25) {
| |
| processHit(laneId, diff);
| |
| n.el.remove(); active.splice(i, 1);
| |
| }
| |
| });
| |
| }
| |
|
| |
| function processHit(laneId, diff) {
| |
| let pts = diff < 0.1 ? 50 : 25;
| |
| comboCount++; missCount = 0;
| |
| if (comboCount >= 5) { pts *= 2; comboEl.innerText = "KOMBO! 2X PUAN 🔥"; }
| |
| score += pts; scoreEl.innerText = score;
| |
| showFeedback(laneId, `+${pts}`, "#fbff00");
| |
| }
| |
|
| |
| function processMiss(laneId) {
| |
| comboCount = 0; missCount++; comboEl.innerText = "";
| |
| if (missCount >= 3) {
| |
| score = Math.max(0, score - 10); scoreEl.innerText = score;
| |
| showFeedback(laneId, "-10", "#ff4444");
| |
| }
| |
| }
| |
|
| |
| function showFeedback(lane, text, color) {
| |
| const f = document.createElement("div"); f.className = "feedback";
| |
| f.innerText = text; f.style.color = color; lanes[lane].appendChild(f);
| |
| setTimeout(() => f.remove(), 500);
| |
| }
| |
|
| |
| function saveAndShowScore() {
| |
| gameRunning = false;
| |
| audio.pause();
| |
| document.getElementById("end-screen").style.display = "flex";
| |
| document.getElementById("total-score").innerText = score;
| |
| document.getElementById("display-username").innerText = userName.toUpperCase();
| |
| }
| |
|
| |
| function resetGame() {
| |
| gameRunning = false;
| |
| score = 0; comboCount = 0; missCount = 0;
| |
| scoreEl.innerText = "0";
| |
| comboEl.innerText = "";
| |
| active.forEach(n => n.el.remove());
| |
| active = [];
| |
| notes.forEach(n => n.spawned = false);
| |
| lyrics.forEach(l => l.shown = false);
| |
| document.getElementById("lyrics-container").innerText = "";
| |
| document.getElementById("end-screen").style.display = "none";
| |
| document.getElementById("start-screen").style.display = "flex";
| |
| }
| |
|
| |
| function shareScore() {
| |
| const text = `Şubadap Kabuk Kırma Partisi'nde ${score} puan yaptım! Haydi sen de oyna! 🎸\n${window.location.href}`;
| |
| if (navigator.share) {
| |
| navigator.share({ title: 'Şubadap Skor', text: text, url: window.location.href });
| |
| } else {
| |
| navigator.clipboard.writeText(text).then(() => alert("Skorun kopyalandı!"));
| |
| }
| |
| }
| |
|
| |
| document.addEventListener("keydown", e => {
| |
| const map = { "a": 0, "s": 1, "d": 2, "f": 3 };
| |
| const lid = map[e.key.toLowerCase()];
| |
| if (lid !== undefined) handleInput(lid);
| |
| });
| |
| </script>
| |
|
| |
| ==Playback== | | ==Playback== |
| [[Kategori: Şarkı]] | | [[Kategori: Şarkı]] |