Skip to main content

Logo

Tam Gelişmiş Balon Patlatmaca Oyunu Açık kaynak kod

Konu

#1
Tam Gelişmiş Balon Patlatmaca Oyunu ( Javascript + html + Tialwindcss ) Açık kaynak kod

herkese merhaba !
Boş zamanlarınızı eğlenceli bir şekilde değerlendirebileceğiniz bağımlılık yapıcı bir HTML5 balon patlatma oyunu! Bu oyunu tarayıcınız üzerinden herhangi bir eklentiye ihtiyaç duymadan oynayabilirsiniz.


Oyunun Özellikleri
Farklı zorluk seviyeleri: Kolay, Orta ve Zor seçenekleri
Ayarlanabilir arka plan rengi
Ses açma/kapama seçeneği
Parçacık efektlerini açma/kapama seçeneği
Ayarlanabilir balon boyutu
Seviye ilerleme çubuğu
Oyun duraklatma özelliği
Mobil uyumlu tasarım
Tamamen ücretsiz!
Eğlenceli ses efektleri: Oyun deneyiminizi daha da keyifli hale getirir.
Basit ve anlaşılır arayüz: Her yaştan oyuncu için uygun.
Oyunun Amacı

Ekranda yukarı doğru hareket eden renkli balonları üzerlerine tıklayarak patlatın ve belirli bir süre içinde hedef puana ulaşarak bir sonraki seviyeye geçin. Her seviyede patlatmanız gereken balon sayısı artar ve oyun zorlaşır.
Nasıl Oynanır
HTML Dosyasını İndirin: Oyunu oynamak için aşağıdaki HTML dosyasını bilgisayarınıza indirin.
Tarayıcıda Açın: Dosyayı Chrome, Firefox, Edge gibi herhangi bir web tarayıcısında açın.
Oyuncu Adınızı Girin: Başlangıç ekranında oyuncu adınızı girerek oyuna başlayın.
Balonları Patlatın: Fare ile balonlara tıklayarak patlatın.
Ayarları Kişiselleştirin:
Zorluk seviyesini, arka plan rengini, ses efektlerini ve balon boyutunu ayarlar menüsünden değiştirebilirsiniz.
Oyun Duraklatma:
Oyunu duraklatmak için boşluk tuşuna basabilir veya ekranın sağ üst köşesindeki duraklatma simgesine tıklayabilirsiniz.
Şimdi oyunu indirip eğlenceye başlayabilirsiniz!


[Resim: 374zcev.png]

Kod :
<!DOCTYPE html>
<html lang="tr">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Balon Patlatma Oyunu</title>
  <script src="https://cdn.tailwindcss.com"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
  <style>
    body {
      overflow: hidden;
    }
    #myCanvas {
      background: lightblue;
    }
    .settings-icon {
      position: absolute;
      top: 10px;
      right: 10px;
      cursor: pointer;
      z-index: 30;
      transition: transform 0.3s ease;
    }
    .settings-icon:hover {
      transform: rotate(90deg);
    }
    .settings-panel {
      position: absolute;
      top: 50px;
      right: 10px;
      background-color: white;
      border: 1px solid #ccc;
      padding: 10px;
      border-radius: 5px;
      z-index: 30;
      width: 200px;
      transform: translateX(100%);
      opacity: 0;
      transition: transform 0.5s ease, opacity 0.5s ease;
    }
    .settings-panel.open {
      transform: translateX(0);
      opacity: 1;
    }
    .settings-panel label {
      display: flex;
      align-items: center;
      margin-bottom: 5px;
    }
    .settings-panel input[type="range"] {
      margin-left: 10px;
    }
    .level-info {
      position: absolute;
      top: 10px;
      left: 50%;
      transform: translateX(-50%);
      font-size: 1.2rem;
      font-weight: bold;
      color: #4a5568;
      z-index: 10;
    }
    .level-transition {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: rgba(0, 0, 0, 0.7);
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      z-index: 20;
      color: white;
      font-size: 2rem;
      font-weight: bold;
      opacity: 0;
      animation: fadeInOut 3s ease forwards;
    }
    @keyframes fadeInOut {
      0% { opacity: 0; }
      25% { opacity: 1; }
      75% { opacity: 1; }
      100% { opacity: 0; }
    }
    .level-transition p {
      margin: 5px 0;
    }
    .progress-bar-container {
      position: absolute;
      top: 45px;
      left: 50%;
      transform: translateX(-50%);
      width: 300px;
      height: 20px;
      background-color: #e0e0e0;
      border-radius: 10px;
      overflow: hidden;
      z-index: 10;
      box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
    }
    .progress-bar {
      height: 100%;
      width: 0%;
      background: linear-gradient(to right, #4caf50, #8bc34a);
      transition: width 0.3s ease, background 0.5s ease;
    }
    .progress-bar.completed {
      background: linear-gradient(to right, #ff9800, #ffc107);
    }
    .progress-bar-particle {
      position: absolute;
      border-radius: 50%;
      opacity: 0.7;
      animation: particleAnimation 1s ease-out;
    }
    @keyframes particleAnimation {
      0% {
        transform: translateY(0) scale(1);
        opacity: 0.7;
      }
      100% {
        transform: translateY(-20px) scale(0);
        opacity: 0;
      }
    }
    .progress-text {
      position: absolute;
      top: 45px;
      left: 50%;
      transform: translateX(-50%);
      margin-top: 25px;
      font-size: 0.9rem;
      color: #4a5568;
      z-index: 10;
    }
    .pause-overlay {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: rgba(0, 0, 0, 0.5);
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      z-index: 40;
    }
    .pause-message {
      color: white;
      font-size: 2rem;
      font-weight: bold;
      margin-bottom: 20px;
    }
    .continue-button {
      background-color: #4caf50;
      color: white;
      font-weight: bold;
      padding: 10px 20px;
      border-radius: 5px;
      cursor: pointer;
      box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
    }
    .settings-panel label {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 8px;
      color: #333;
    }
    .settings-panel label span {
      margin-right: 10px;
    }
    .settings-panel select,
    .settings-panel input[type="color"],
    .settings-panel input[type="range"],
    .settings-panel input[type="checkbox"] {
      border: 1px solid #ccc;
      border-radius: 4px;
      padding: 4px;
    }
    .settings-panel input[type="checkbox"] {
      width: auto;
      margin: 0;
    }
  </style>
</head>
<body class="bg-gray-100 flex justify-center items-center h-screen">
  <div class="relative">
    <canvas id="myCanvas" class="rounded-lg shadow-lg"></canvas>
    <div id="playerName" class="absolute top-2 left-2 text-xl font-bold text-gray-700"></div>
    <div id="score" class="absolute top-2 left-2 text-xl font-bold text-gray-700" style="left: 150px">Skor: 0</div>
    <div id="timer" class="absolute top-2 right-2 text-xl font-bold text-gray-700" style="right: 60px">Süre: 60</div>
    <div id="levelInfo" class="level-info">Seviye: 1</div>
    <div class="progress-bar-container">
      <div id="progressBar" class="progress-bar"></div>
    </div>
    <div id="progressText" class="progress-text"></div>
    <div id="gameOver" class="hidden absolute inset-0 bg-black bg-opacity-50 flex flex-col justify-center items-center">
      <h1 id="gameOverText" class="text-4xl font-bold text-white mb-4">Oyun Bitti!</h1>
      <p id="finalScore" class="text-2xl text-white mb-4"></p>
      <button id="restartButton" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Yeniden Başla</button>
    </div>
    <div id="settingsIcon" class="settings-icon"><i class="fas fa-cog fa-2x text-gray-700"></i></div>
    <div id="settingsPanel" class="settings-panel">
      <label for="difficulty">
        <span>Zorluk:</span>
        <select id="difficulty">
          <option value="easy">Kolay</option>
          <option value="medium">Orta</option>
          <option value="hard">Zor</option>
        </select>
      </label>
      <label for="bgColor">
        <span>Arkaplan Rengi:</span>
        <input type="color" id="bgColor" value="#add8e6">
      </label>
      <label for="sound">
        <span>Ses:</span>
        <input type="checkbox" id="sound" checked>
      </label>
      <label for="particleEffects">
        <span>Parçacık Efektleri:</span>
        <input type="checkbox" id="particleEffects" checked>
      </label>
      <label for="balloonSize">
        <span>Balon Boyutu:</span>
        <input type="range" id="balloonSize" min="10" max="50" value="30">
      </label>
    </div>
    <div id="levelTransition" class="hidden level-transition"></div>
    <div id="pauseOverlay" class="hidden pause-overlay">
      <div class="pause-message">Oyun Duraklatıldı</div>
      <button id="continueButton" class="continue-button">Devam Et</button>
    </div>
  </div>

  <audio id="popSound" src="https://www.fesliyanstudios.com/play-mp3/3848"></audio>
  <audio id="nextLevelSound" src="https://www.fesliyanstudios.com/play-mp3/3955"></audio>

  <script>
    const canvas = document.getElementById("myCanvas");
    const ctx = canvas.getContext("2d");
    const scoreElement = document.getElementById("score");
    const timerElement = document.getElementById("timer");
    const gameOverElement = document.getElementById("gameOver");
    const gameOverTextElement = document.getElementById("gameOverText");
    const finalScoreElement = document.getElementById("finalScore");
    const restartButton = document.getElementById("restartButton");
    const settingsIcon = document.getElementById("settingsIcon");
    const settingsPanel = document.getElementById("settingsPanel");
    const difficultySelect = document.getElementById("difficulty");
    const bgColorInput = document.getElementById("bgColor");
    const soundCheckbox = document.getElementById("sound");
    const popSound = document.getElementById("popSound");
    const nextLevelSound = document.getElementById("nextLevelSound");
    const playerNameElement = document.getElementById("playerName");
    const levelInfoElement = document.getElementById("levelInfo");
    const particleEffectsCheckbox = document.getElementById("particleEffects");
    const balloonSizeInput = document.getElementById("balloonSize");
    const levelTransitionElement = document.getElementById("levelTransition");
    const progressBar = document.getElementById("progressBar");
    const progressText = document.getElementById("progressText");
    const pauseOverlay = document.getElementById("pauseOverlay");
    const continueButton = document.getElementById("continueButton");

    canvas.width = 800;
    canvas.height = 600;

    let score = 0;
    let timeLeft = 60;
    let isGameOver = false;
    let animationId;
    let difficulty = "medium";
    let playerName = "";
    let soundEnabled = true;
    let level = 1;
    let requiredScore = 35;
    let levelBalloonCount = 0;
    let extraBalloons = 0; // Fazladan patlatılan balon sayısı
    let particleEffectsEnabled = true;
    let balloonSize = 30;
    let isLevelTransitioning = false;
    let countdownInterval;
    let isPaused = false;
    let spawnInterval;

    const balloonColors = [
      "#FF5733", // Kırmızı
      "#FFC300", // Turuncu
      "#FFFF66", // Sarı
      "#90EE90", // Açık Yeşil
      "#3399FF", // Açık Mavi
      "#9933FF", // Mor
      "#FF66CC", // Pembe
    ];

    class Balloon {
      constructor(x, y, radius, color, speed) {
        this.x = x;
        this.y = y;
        this.radius = radius;
        this.color = color;
        this.speed = speed;
        this.gradient = ctx.createRadialGradient(
          this.x,
          this.y,
          0,
          this.x,
          this.y,
          this.radius
        );
        this.gradient.addColorStop(0, "rgba(255,255,255,0.5)");
        this.gradient.addColorStop(0.3, this.color);
        this.gradient.addColorStop(0.8, this.color);
        this.gradient.addColorStop(1, "rgba(0,0,0,0.5)");
        this.shadowBlur = 10;
        this.shadowColor = "rgba(0, 0, 0, 0.5)";
      }

      draw() {
        ctx.save();
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
        ctx.fillStyle = this.gradient;
        ctx.shadowBlur = this.shadowBlur;
        ctx.shadowColor = this.shadowColor;
        ctx.fill();
        ctx.closePath();

        // Balonun ipi
        ctx.beginPath();
        ctx.moveTo(this.x, this.y + this.radius);
        ctx.lineTo(this.x + 5, this.y + this.radius + 10);
        ctx.lineTo(this.x - 5, this.y + this.radius + 10);
        ctx.fillStyle = this.color;
        ctx.fill();
        ctx.closePath();
        ctx.restore();
      }

      update() {
        this.draw();
        this.y -= this.speed;
      }
    }

    class Particle {
      constructor(x, y, color) {
        this.x = x;
        this.y = y;
        this.color = color;
        this.radius = Math.random() * 2 + 1;
        this.speedX = (Math.random() - 0.5) * 4;
        this.speedY = (Math.random() - 0.5) * 4;
        this.life = 1;
        this.opacity = 1;
      }

      draw() {
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
        ctx.fillStyle = this.color;
        ctx.globalAlpha = this.opacity;
        ctx.fill();
        ctx.closePath();
        ctx.globalAlpha = 1;
      }

      update() {
        this.draw();
        this.x += this.speedX;
        this.y += this.speedY;
        this.life -= 0.01;
        this.opacity = this.life;
      }
    }

    let balloons = [];
    let particles = [];

    function spawnBalloons() {
      clearInterval(spawnInterval);
      spawnInterval = setInterval(() => {
        if (!isGameOver && !isLevelTransitioning && !isPaused) {
          const x =
            Math.random() * (canvas.width - balloonSize * 2) + balloonSize;
          const y = canvas.height + balloonSize;
          const color =
            balloonColors[Math.floor(Math.random() * balloonColors.length)];
          let speed;

          switch (difficulty) {
            case "easy":
              speed = Math.random() * 1 + 0.5;
              break;
            case "medium":
              speed = Math.random() * 2 + 1;
              break;
            case "hard":
              speed = Math.random() * 3 + 1.5;
              break;
          }

          balloons.push(new Balloon(x, y, balloonSize, color, speed));
        }
      }, getInterval());
    }

    function getInterval() {
      switch (difficulty) {
        case "easy":
          return 1500;
        case "medium":
          return 1000;
        case "hard":
          return 500;
      }
    }

    function updateScore() {
      scoreElement.textContent = `Skor: ${score}`;
    }

    function updateTimer() {
      timerElement.textContent = `Süre: ${timeLeft}`;
    }

    function updateLevel() {
      levelInfoElement.textContent = `Seviye: ${level}`;
    }

    function createProgressBarParticle(x, y) {
      const particle = document.createElement("div");
      particle.classList.add("progress-bar-particle");
      particle.style.left = `${x}px`;
      particle.style.top = `${y}px`;
      particle.style.backgroundColor =
        balloonColors[Math.floor(Math.random() * balloonColors.length)];
      particle.style.width = `${Math.random() * 5 + 5}px`;
      particle.style.height = particle.style.width;
      progressBar.appendChild(particle);

      setTimeout(() => {
        progressBar.removeChild(particle);
      }, 1000);
    }

    function updateProgressBar() {
        const totalBalloonsPopped = levelBalloonCount + extraBalloons;
        const progress = totalBalloonsPopped / requiredScore;

        // İlerleme çubuğunun genişliğini ayarla
        progressBar.style.width = `${Math.min(progress * 100, 100)}%`;
      
        // Gerekli balon sayısına ulaşılıp ulaşılmadığını kontrol et
        if (progress >= 1) {
          progressBar.classList.add("completed");
        } else {
          progressBar.classList.remove("completed");
        }
      
        // İlerleme metnini güncelle, ancak maksimum değeri aşma
        const displayBalloonsPopped = Math.min(totalBalloonsPopped, requiredScore);
        progressText.textContent = `${displayBalloonsPopped}/${requiredScore}`;

        // Parçacık efekti oluştur (sadece gerekli balon sayısına ulaşılana kadar)
        if (totalBalloonsPopped <= requiredScore) {
            createProgressBarParticle(
                progress * progressBar.parentElement.offsetWidth,
                progressBar.parentElement.offsetHeight / 2
            );
        }
    }

    function showLevelTransition() {
      isLevelTransitioning = true;
      levelTransitionElement.innerHTML = `
        <p>${level}. Seviye Tamamlandı</p>
        <p>${level + 1}. Seviye Başlıyor</p>
      `;
      levelTransitionElement.classList.remove("hidden");

      setTimeout(() => {
        levelTransitionElement.classList.add("hidden");
        level++;
        if (level === 2) {
          requiredScore = 75;
        } else if (level === 3) {
          requiredScore = 100;
        } else {
          requiredScore += Math.floor(requiredScore * 0.25);
        }
        levelBalloonCount = 0; // Mevcut seviye için patlatılan balon sayısını sıfırla
        timeLeft = 60;
        isLevelTransitioning = false;
        updateLevel();
        updateTimer();
        updateProgressBar();
        balloons = [];
        particles = [];
        countdown();
        spawnBalloons();
      }, 3000);
    }

    function checkLevelUp() {
      const totalBalloonsPopped = levelBalloonCount + extraBalloons;
      if (totalBalloonsPopped >= requiredScore) {
          if (soundEnabled) {
              nextLevelSound.currentTime = 0;
              nextLevelSound.play();
            }
            clearInterval(countdownInterval);
    
            // Fazladan patlatılan balon sayısını hesapla
            extraBalloons = totalBalloonsPopped - requiredScore;
            //console.log("extraBalloons:", extraBalloons);

          
            showLevelTransition();
        } else {
            handleGameOver(false);
        }
    }

    function handleGameOver(win) {
      isGameOver = true;
      clearInterval(countdownInterval);
      clearInterval(spawnInterval);
      if (win) {
        gameOverTextElement.textContent = "Tebrikler! Kazandınız!";
      } else {
        gameOverTextElement.textContent = "Oyun Bitti!";
      }
      finalScoreElement.textContent = `${playerName}, Skorunuz: ${score}`;
      gameOverElement.classList.remove("hidden");
      cancelAnimationFrame(animationId);
    }

    function countdown() {
      clearInterval(countdownInterval);
      countdownInterval = setInterval(() => {
        if (timeLeft > 0 && !isGameOver && !isLevelTransitioning && !isPaused) {
          timeLeft--;
          updateTimer();
          if (timeLeft == 0) {
            clearInterval(countdownInterval);
            checkLevelUp();
          }
        }
      }, 1000);
    }

    function animate() {
      animationId = requestAnimationFrame(animate);
      ctx.fillStyle = bgColorInput.value;
      ctx.fillRect(0, 0, canvas.width, canvas.height);

      for (let i = balloons.length - 1; i >= 0; i--) {
        const balloon = balloons[i];
        balloon.update();

        if (balloon.y + balloon.radius < 0) {
          balloons.splice(i, 1);
        }
      }

      if (particleEffectsEnabled) {
        for (let i = particles.length - 1; i >= 0; i--) {
          const particle = particles[i];
          particle.update();

          if (particle.life <= 0) {
            particles.splice(i, 1);
          }
        }
      }
    }

    function togglePause() {
      isPaused = !isPaused;
      if (isPaused) {
        clearInterval(countdownInterval);
        pauseOverlay.classList.remove("hidden");
        cancelAnimationFrame(animationId);
      } else {
        countdown();
        pauseOverlay.classList.add("hidden");
        animate();
        spawnBalloons();
      }
    }

    canvas.addEventListener("click", (event) => {
      if (!isGameOver && !isLevelTransitioning && !isPaused) {
        const rect = canvas.getBoundingClientRect();
        const x = event.clientX - rect.left;
        const y = event.clientY - rect.top;

        for (let i = balloons.length - 1; i >= 0; i--) {
          const balloon = balloons[i];
          const distance = Math.sqrt(
            (x - balloon.x) ** 2 + (y - balloon.y) ** 2
          );
          if (distance < balloon.radius + 5) {
            if (soundEnabled) {
              popSound.currentTime = 0;
              popSound.play();
            }

            if (particleEffectsEnabled) {
              for (let j = 0; j < balloon.radius * 2; j++) {
                particles.push(
                  new Particle(balloon.x, balloon.y, balloon.color)
                );
              }
            }

            balloons.splice(i, 1);
            score++;
            levelBalloonCount++;
            updateScore();
            updateProgressBar();
            break;
          }
        }
      }
    });

    restartButton.addEventListener("click", () => {
      isGameOver = false;
      gameOverElement.classList.add("hidden");
      score = 0;
      timeLeft = 60;
      level = 1;
      requiredScore = 35;
      levelBalloonCount = 0;
      extraBalloons = 0; // Yeniden başlatıldığında fazladan balon sayısını sıfırla
      balloons = [];
      particles = [];
      updateScore();
      updateTimer();
      updateLevel();
      updateProgressBar();
      animate();
      countdown();
      spawnBalloons();
    });

    settingsIcon.addEventListener("click", () => {
      settingsPanel.classList.toggle("open");
    });

    difficultySelect.addEventListener("change", () => {
      difficulty = difficultySelect.value;
    });

    bgColorInput.addEventListener("input", () => {
      canvas.style.backgroundColor = bgColorInput.value;
    });

    soundCheckbox.addEventListener("change", () => {
      soundEnabled = soundCheckbox.checked;
    });

    particleEffectsCheckbox.addEventListener("change", () => {
      particleEffectsEnabled = particleEffectsCheckbox.checked;
    });

    balloonSizeInput.addEventListener("input", () => {
      balloonSize = parseInt(balloonSizeInput.value);
    });

    continueButton.addEventListener("click", () => {
      togglePause();
    });

    document.addEventListener("visibilitychange", () => {
      if (document.hidden && !isGameOver && !isLevelTransitioning) {
        togglePause();
      }
    });

    document.addEventListener("keydown", (event) => {
      if (event.code === "Space" && !isGameOver && !isLevelTransitioning) {
        togglePause();
      }
    });

    function startGame() {
      playerName = prompt("Lütfen oyuncu adınızı girin:", "Oyuncu");
      if (playerName === null || playerName.trim() === "") {
        playerName = "Oyuncu";
      }
      playerNameElement.textContent = `${playerName}`;
      playerNameElement.style.display = "block";
      updateScore();
      updateTimer();
      updateLevel();
      updateProgressBar();
      countdown();
      spawnBalloons();
      animate();
    }

    startGame();
  </script>
</body>
</html>

Cevapla

Bir hesap oluşturun veya yorum yapmak için giriş yapın

Yorum yapmak için üye olmanız gerekiyor

ya da