<div id="game-container">
  <div id="score-board">Score: <span id="score">0</span></div>
  <div id="start-screen">
    <h1>Shark Attack Survival</h1>
    <p>Use Left/Right Arrows to move the boat.</p>
    <p>Avoid the sharks!</p>
    <button id="start-button">Start Game</button>
  </div>
  <div id="game-area">
    <!-- Player Boat -->
    <div id="boat">
      <div id="person">🧑‍ P</div> <!-- Simple representation -->
    </div>
    <!-- Game elements will be added here by JS -->
  </div>
  <div id="game-over-screen" style="display: none;">
    <h1>Game Over!</h1>
    <p>Your Score: <span id="final-score">0</span></p>
    <button id="restart-button">Play Again</button>
  </div>
</div>
body {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  margin: 0;
  background-color: #f0f0f0;
  font-family: Arial, sans-serif;
  overflow: hidden; /* Hide scrollbars if game area is slightly too big */
}

#game-container {
  position: relative;
  width: 600px;
  height: 80vh; /* Use viewport height */
  max-height: 700px; /* Max height */
  border: 3px solid #333;
  background-color: #add8e6; /* Light blue sea */
  overflow: hidden; /* Keep elements inside */
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}

#game-area {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: linear-gradient(
    to bottom,
    #87CEEB 0%, /* Sky Blue */
    #1E90FF 60%, /* Dodger Blue */
    #00008B 100% /* Dark Blue */
  );
  background-size: 100% 200%; /* Taller background for scrolling */
  animation: scroll-water 15s linear infinite;
}

@keyframes scroll-water {
  0% { background-position: 0 0; }
  100% { background-position: 0 100%; }
}

#boat {
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  width: 80px;
  height: 40px;
  background-color: #8B4513; /* Brown */
  border-radius: 10px 10px 30px 30px / 10px 10px 20px 20px;
  border: 2px solid #5a2d0c;
  z-index: 10;
  display: flex;
  justify-content: center;
  align-items: center;
}

#person {
    font-size: 20px;
    /* You could use a background image for a better person/boat look */
}

.shark {
  position: absolute;
  width: 60px;
  height: 30px;
  /* background-color: grey; */ /* Placeholder */
  font-size: 30px; /* Use Emoji */
  line-height: 30px; /* Center emoji */
  text-align: center;
  z-index: 5;
  /* background-image: url('shark-image.png'); /* Optional: Use an image */
  /* background-size: contain; */
  /* background-repeat: no-repeat; */
  transform-origin: center center;
}

.fish {
    position: absolute;
    font-size: 20px;
    z-index: 1;
    opacity: 0.8;
}

.buoy {
    position: absolute;
    width: 25px;
    height: 40px;
    background-color: red;
    border-radius: 50% 50% 10px 10px;
    border: 2px solid darkred;
    z-index: 2;
    box-shadow: 0 2px 4px rgba(0,0,0,0.3);
}
.buoy::before { /* Top part of buoy */
    content: '';
    position: absolute;
    top: -8px;
    left: 50%;
    transform: translateX(-50%);
    width: 8px;
    height: 10px;
    background-color: darkred;
}


#score-board {
  position: absolute;
  top: 10px;
  left: 10px;
  font-size: 1.5em;
  color: white;
  z-index: 20;
  text-shadow: 1px 1px 2px black;
}

/* Screens */
#start-screen, #game-over-screen {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.7);
  color: white;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  z-index: 30;
}

#start-screen h1, #game-over-screen h1 {
  margin-bottom: 20px;
}

#start-screen p, #game-over-screen p {
  margin-bottom: 30px;
  font-size: 1.2em;
}

#start-button, #restart-button {
  padding: 15px 30px;
  font-size: 1.2em;
  cursor: pointer;
  border: none;
  border-radius: 5px;
  background-color: #4CAF50;
  color: white;
  transition: background-color 0.3s ease;
}

#start-button:hover, #restart-button:hover {
  background-color: #45a049;
}
const gameArea = document.getElementById('game-area');
const boat = document.getElementById('boat');
const scoreDisplay = document.getElementById('score');
const finalScoreDisplay = document.getElementById('final-score');
const startScreen = document.getElementById('start-screen');
const gameOverScreen = document.getElementById('game-over-screen');
const startButton = document.getElementById('start-button');
const restartButton = document.getElementById('restart-button');

// Game Settings
const boatSpeed = 15;
const sharkBaseSpeed = 2;
const fishSpeed = 1;
const buoySpeed = 1.5;
const sharkSpawnRate = 0.015; // Probability per frame
const fishSpawnRate = 0.02;
const buoySpawnRate = 0.005;
const difficultyIncreaseInterval = 10000; // Increase difficulty every 10 seconds (ms)
const difficultyMultiplier = 1.1; // How much faster things get

// Game State
let score = 0;
let gameInterval;
let isGameOver = false;
let keysPressed = {};
let currentSharkSpeed = sharkBaseSpeed;
let currentSharkSpawnRate = sharkSpawnRate;
let gameTime = 0;
let lastDifficultyIncrease = 0;

// --- Event Listeners ---
document.addEventListener('keydown', (e) => {
  keysPressed[e.key] = true;
});

document.addEventListener('keyup', (e) => {
  keysPressed[e.key] = false;
});

startButton.addEventListener('click', startGame);
restartButton.addEventListener('click', startGame);

// --- Game Functions ---

function startGame() {
  // Reset State
  score = 0;
  gameTime = 0;
  lastDifficultyIncrease = 0;
  currentSharkSpeed = sharkBaseSpeed;
  currentSharkSpawnRate = sharkSpawnRate;
  isGameOver = false;
  keysPressed = {};
  scoreDisplay.textContent = score;
  gameOverScreen.style.display = 'none';
  startScreen.style.display = 'none';
  gameArea.style.animationPlayState = 'running'; // Resume background scroll

  // Clear previous game elements
  document.querySelectorAll('.shark, .fish, .buoy').forEach(el => el.remove());

  // Reset boat position
  boat.style.left = '50%';

  // Start game loop
  clearInterval(gameInterval); // Clear any existing interval
  gameInterval = setInterval(gameLoop, 1000 / 60); // ~60 FPS
}

function gameOver() {
  isGameOver = true;
  clearInterval(gameInterval);
  finalScoreDisplay.textContent = score;
  gameOverScreen.style.display = 'flex';
  gameArea.style.animationPlayState = 'paused'; // Pause background scroll
}

function moveBoat() {
  const gameRect = gameArea.getBoundingClientRect();
  const boatRect = boat.getBoundingClientRect();
  let currentLeft = parseFloat(boat.style.left || '50%'); // Get percentage

   // Convert percentage to pixels for boundary check
  let currentLeftPx = (currentLeft / 100) * gameRect.width;

  if (keysPressed['ArrowLeft'] || keysPressed['a']) {
    let nextLeftPx = currentLeftPx - boatSpeed;
    // Boundary check (left) - account for boat width relative to its center anchor
    if (nextLeftPx - boatRect.width / 2 > 0) {
       boat.style.left = `${((nextLeftPx) / gameRect.width) * 100}%`;
    } else {
       boat.style.left = `${(boatRect.width / 2 / gameRect.width) * 100}%`; // Snap to edge
    }
  }
  if (keysPressed['ArrowRight'] || keysPressed['d']) {
     let nextLeftPx = currentLeftPx + boatSpeed;
     // Boundary check (right) - account for boat width relative to its center anchor
    if (nextLeftPx + boatRect.width / 2 < gameRect.width) {
       boat.style.left = `${((nextLeftPx) / gameRect.width) * 100}%`;
    } else {
        boat.style.left = `${((gameRect.width - boatRect.width / 2) / gameRect.width) * 100}%`; // Snap to edge
    }
  }
}

function createShark() {
  const shark = document.createElement('div');
  shark.classList.add('shark');
  shark.textContent = '🦈'; // Shark Emoji
  shark.style.left = `${Math.random() * (gameArea.offsetWidth - 60)}px`; // Random horizontal start (minus shark width)
  shark.style.top = '-40px'; // Start above screen

  // Add slight horizontal drift/targeting
  shark.dataset.drift = (Math.random() - 0.5) * 1; // -0.5 to +0.5 horizontal speed adjustment
  // Maybe make some sharks target the player slightly more directly (optional enhancement)
  // if (Math.random() < 0.3) { // 30% chance to target
  //   const boatRect = boat.getBoundingClientRect();
  //   const sharkStartX = parseFloat(shark.style.left);
  //   const targetX = boatRect.left + boatRect.width / 2 - gameArea.getBoundingClientRect().left;
  //   shark.dataset.drift = (targetX - sharkStartX) / (gameArea.offsetHeight / currentSharkSpeed) * 0.05; // Simple prediction
  // }

  gameArea.appendChild(shark);
}

function moveSharks() {
  const sharks = document.querySelectorAll('.shark');
  const gameRect = gameArea.getBoundingClientRect();

  sharks.forEach(shark => {
    let top = parseFloat(shark.style.top);
    let left = parseFloat(shark.style.left);
    const drift = parseFloat(shark.dataset.drift || 0);

    top += currentSharkSpeed;
    left += drift;

    // Basic boundary check for horizontal drift
    if (left < 0 || left > gameRect.width - shark.offsetWidth) {
        shark.dataset.drift = -drift; // Reverse drift at edges
        left += -drift * 2; // Move back into bounds slightly
    }

    shark.style.top = `${top}px`;
    shark.style.left = `${left}px`;

    // Flip shark based on drift direction
    if (drift < 0 && shark.style.transform !== 'scaleX(-1)') {
         shark.style.transform = 'scaleX(-1)';
    } else if (drift > 0 && shark.style.transform === 'scaleX(-1)') {
         shark.style.transform = 'scaleX(1)';
    }


    // Remove shark if it goes off screen bottom
    if (top > gameArea.offsetHeight) {
      shark.remove();
    }
  });
}

function createFish() {
    const fish = document.createElement('div');
    fish.classList.add('fish');
    const fishTypes = ['🐠', '🐟', '🐡'];
    fish.textContent = fishTypes[Math.floor(Math.random() * fishTypes.length)];
    fish.style.left = `${Math.random() * (gameArea.offsetWidth - 30)}px`;
    fish.style.top = '-30px';
    fish.dataset.speed = fishSpeed + (Math.random() - 0.5); // Slight speed variation
    fish.dataset.drift = (Math.random() - 0.5) * 0.5; // Horizontal drift

     // Randomly flip fish
    if (Math.random() < 0.5) {
        fish.style.transform = 'scaleX(-1)';
    }

    gameArea.appendChild(fish);
}

function moveFish() {
    const fishes = document.querySelectorAll('.fish');
    fishes.forEach(fish => {
        let top = parseFloat(fish.style.top);
        let left = parseFloat(fish.style.left);
        const speed = parseFloat(fish.dataset.speed);
        const drift = parseFloat(fish.dataset.drift);

        top += speed;
        left += drift;

        // Remove fish if it goes off screen
        if (top > gameArea.offsetHeight || left < -30 || left > gameArea.offsetWidth) {
            fish.remove();
        } else {
            fish.style.top = `${top}px`;
            fish.style.left = `${left}px`;
        }
    });
}

function createBuoy() {
    const buoy = document.createElement('div');
    buoy.classList.add('buoy');
    buoy.style.left = `${Math.random() * (gameArea.offsetWidth - 25)}px`;
    buoy.style.top = '-50px';
    gameArea.appendChild(buoy);
}

function moveBuoys() {
    const buoys = document.querySelectorAll('.buoy');
    buoys.forEach(buoy => {
        let top = parseFloat(buoy.style.top);
        top += buoySpeed; // Buoys just drift down slowly

        if (top > gameArea.offsetHeight) {
            buoy.remove();
        } else {
            buoy.style.top = `${top}px`;
        }
    });
}


function checkCollision() {
  const boatRect = boat.getBoundingClientRect();
  const sharks = document.querySelectorAll('.shark');
  // Optional: Check collision with buoys if they are obstacles
  // const buoys = document.querySelectorAll('.buoy');

  sharks.forEach(shark => {
    const sharkRect = shark.getBoundingClientRect();
    // Simple Axis-Aligned Bounding Box (AABB) collision detection
    if (
      boatRect.left < sharkRect.right &&
      boatRect.right > sharkRect.left &&
      boatRect.top < sharkRect.bottom &&
      boatRect.bottom > sharkRect.top
    ) {
      gameOver();
    }
  });

  // Example: Collision with Buoys (uncomment if buoys should end the game)
  /*
  buoys.forEach(buoy => {
    const buoyRect = buoy.getBoundingClientRect();
    if (
      boatRect.left < buoyRect.right &&
      boatRect.right > buoyRect.left &&
      boatRect.top < buoyRect.bottom &&
      boatRect.bottom > buoyRect.top
    ) {
      gameOver();
    }
  });
  */
}

function updateScore() {
  score++;
  scoreDisplay.textContent = score;
}

function increaseDifficulty() {
    gameTime += 1000 / 60; // Add frame time

    if(gameTime - lastDifficultyIncrease > difficultyIncreaseInterval) {
        console.log("Increasing difficulty!");
        currentSharkSpeed *= difficultyMultiplier;
        currentSharkSpawnRate = Math.min(0.1, currentSharkSpawnRate * difficultyMultiplier); // Increase spawn rate but cap it
        // Optionally increase buoy speed/spawn rate too
        lastDifficultyIncrease = gameTime;
    }
}

// --- Main Game Loop ---
function gameLoop() {
  if (isGameOver) return;

  // 1. Handle Input & Move Player
  moveBoat();

  // 2. Spawn Enemies & Assets
  if (Math.random() < currentSharkSpawnRate) {
    createShark();
  }
  if (Math.random() < fishSpawnRate) {
    createFish();
  }
   if (Math.random() < buoySpawnRate) {
    createBuoy();
  }

  // 3. Move Enemies & Assets
  moveSharks();
  moveFish();
  moveBuoys();

  // 4. Check Collisions
  checkCollision();

  // 5. Update Score
  updateScore();

  // 6. Increase Difficulty over time
  increaseDifficulty();

}

// Initially hide game area stuff until start
// (Handled by CSS display:none on start/game over screens)
// Optional: Pause animation initially
gameArea.style.animationPlayState = 'paused';

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.