why is the sandbox-overlay tabs NTO clicking or anyt thing else can u find out why 

 <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Advanced Adventure Game</title>
    <style>
        body, html {
            margin: 0;
            padding: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-color: #222;
            color: #fff;
            font-family: Arial, sans-serif;
            overflow: hidden;
        }
 
        #game-container {
            position: relative;
            width: 800px;
            height: 400px;
            background-color: #333;
            overflow: hidden;
            border: 2px solid #444;
        }


        #upgrades-menu {
            display: none;
            background-color: rgba(0, 0, 0, 0.8);
            color: #fff;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            padding: 20px;
            border-radius: 10px;
            text-align: center;
        }

        #upgrade-list {
            margin: 20px 0;
        }

        .upgrade-option {
            margin: 10px 0;
            font-size: 18px;
        }

#start-menu, #game-mode-options, #level-options {
    display: none; /* Initially hidden */
    text-align: center; /* Center text for buttons */
    position: absolute; /* Positioned relative to parent */
    top: 50%; /* Start middle of vertical view */
    left: 50%; /* Start middle of horizontal view */
    transform: translate(-50%, -50%); /* Center it */
    z-index: 10; /* Bring to the front */
}

        .button {
            padding: 10px 20px;
            font-size: 16px;
            cursor: pointer;
            background-color: #555;
            color: #fff;
            border: none;
            border-radius: 5px;
        }

        .navigation-button {
            margin: 5px;
        }

.split-enemy.split {
    border-radius: 0 !important;
}

.boost-drainer-chain {
  position: absolute;
  border-top: 2px dotted cyan;
  pointer-events: none;
  z-index: 1000;
  height: 0; /* Since it's a horizontal line rotated, height is zero */
}


.boost-drainer {
  position: absolute;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 2px solid cyan;
  background-color: green; /* start at green */
  transition: background-color 0.5s;
  z-index: 20;
}

.boost-drainer.green { background-color: green !important; }
.boost-drainer.yellow { background-color: yellow !important; }
.boost-drainer.red { background-color: red !important; }

.boost-laser {
  position: absolute;
  width: 5px;
  height: 120px; /* height of laser, adjust */
  background-color: red;
  top: 0; /* will be positioned at bottom 0 */
  box-shadow: 0 0 10px red;
  z-index: 19;
  pointer-events: none; /* no interference with input */
}

.split-enemy:not(.split) {
    border-radius: 0 !important; /* Make mini splitters squares */
}

.split-enemy:not(.split) {
    border-radius: 0 !important;
}
 
#game-world {
    position: absolute;
    width: 10000px; /* bigger world - adjust as you wish */
    height: 100%;
    transition: transform 0.1s linear;
}
 
        #player {
            position: absolute;
            bottom: 0;
            left: 50px;
            width: 30px;
            height: 30px;
            background-color: #4CAF50;
            animation: idle 1s infinite alternate;
        }
 
        @keyframes idle {
            from { transform: translateY(0); }
            to { transform: translateY(2px); }
        }
 
@keyframes charging-prep {
    0%, 100% { box-shadow: 0 0 5px rgba(255, 0, 0, 0.6); }
    50% { box-shadow: 0 0 15px rgba(255, 0, 0, 1); }
}

 
@keyframes boss-shake {
    0%, 100% { transform: translate(0, 0); }
    25% { transform: translate(-5px, 0); }
    50% { transform: translate(5px, 0); }
    75% { transform: translate(-5px, 0); }
}
 
 
@keyframes charge-trail {
    0% { opacity: 0.8; transform: scale(1); }
    100% { opacity: 0; transform: scale(2); }
}
 
@keyframes boss-shield-glow {
    0%, 100% { box-shadow: 0 0 10px red; }
    50% { box-shadow: 0 0 20px red; }
}
 
        .character, .boss-door, .power-up, .enemy, .virus-drone, .laser-enemy, .obstacle, .bullet, .burst, .boss, #friend, .coin, .flying-enemy, .charging-enemy, .stealth-enemy, .split-enemy, .boost-drainer, .sniper-enemy, .reflective-enemy, .explosive-enemy, .teleporter-enemy, .mourning-enemy, .velocity-enemy, .sticky-enemy, .reflective-enemy {
            position: absolute;
        }
 
        .character, .king, .stealth-enemy, .split-enemy, .sniper-enemy, .reflective-enemy, .explosive-enemy,
        .teleporter-enemy, .mourning-enemy, .velocity-enemy, .sticky-enemy, .reflective-enemy {
            border-radius: 50%;
        }


.virus-drone {
    position: absolute;
    width: 30px;
    height: 30px;
    background-color: green;
    border: 3px solid red;
    border-radius: 5px;
    z-index: 11;
}

.infected {
    background-color: #00cc00 !important; // bright green
    filter: drop-shadow(0 0 5px lime);
    transition: background-color 0.3s;
}

.infected.shielded::after {
    content: '';
    position: absolute;
    top: -5px; left: -5px;
    width: calc(100% + 10px);
    height: calc(100% + 10px);
    border: 2px solid cyan;
    border-radius: 5px;
    pointer-events: none;
    animation: shieldPulse 2s infinite;
}

@keyframes shieldPulse {
    0%, 100% { opacity: 0.3; }
    50% { opacity: 1; }
}

.energy-blast {
    position: absolute;
    width: 200px; /* Diameter of the burst */
    height: 200px; /* Diameter of the burst */
    border-radius: 50%; /* Make it circular */
    border: 2px solid rgba(0, 255, 255, 0.8); /* Color and transparency */
    opacity: 0.5; /* Semi-transparent */
    animation: pulse 0.5s ease-out; /* Animation for the burst */
}

@keyframes pulse {
    0% {
        transform: scale(1);
        opacity: 0.5;
    }
    100% {
        transform: scale(2); /* Expand the burst for the visual effect */
        opacity: 0; /* Fade out */
    }
}
 
.charging-prep {
    animation: charging-prep 1s infinite alternate;
}

.outlined {
    border: 3px solid green; /* Change as necessary */
    box-shadow: 0 0 10px green; /* Add glow effect */
}
 
.boss-shielded {
    animation: boss-shield-glow 0.8s infinite alternate;
    border: 3px solid red;
}
 
.charging-active {
    box-shadow: 0 0 15px red, 0 0 30px red;
    border: 2px solid red;
}
 
.charge-trail {
    position: absolute;
    width: 35px;
    height: 35px;
    background-color: rgba(255, 50, 50, 0.5);
    border-radius: 50%;
    opacity: 1;
    animation: charge-trail 0.4s ease-out;
}
 
.bullet-trail {
    position: absolute;
    width: 8px;
    height: 4px;
    background-color: rgba(255, 215, 0, 0.5);
    opacity: 1;
    transition: opacity 0.3s ease-out;
}

.laser-line {
    pointer-events: none; /* prevent interfering with input */
    z-index: 1000;
    border-radius: 2px;
    transition: background-color 0.2s ease;
}
 

.infected.shielded::after {
    content: '';
    position: absolute;
    top: -5px; left: -5px;
    width: calc(100% + 10px);
    height: calc(100% + 10px);
    border: 2px solid cyan;
    border-radius: 5px;
    pointer-events: none;
    animation: shieldPulse 2s infinite;
}

 
        .coin {
            width: 15px;
            height: 15px;
            background-color: #FFD700;
            border-radius: 50%;
            animation: spin 2s linear infinite;
        }
 
        @keyframes spin {
            from { transform: rotate(0deg); }
            to { transform: rotate(360deg); }
        }
 
        .flying-enemy {
            width: 30px;
            height: 30px;
            background-color: #0099FF;
            border-radius: 50%;
            opacity: 0.9;
        }
 
        .charging-enemy {
            width: 40px;
            height: 40px;
            background-color: #FF5500;
            animation: charge 1s linear infinite alternate;
            border-radius: 50%;
        }
 
        .enemy {
            width: 25px;
            height: 25px;
            background-color: #FF5733;
        }

.laser-warning-line {
    position: absolute;
    width: 6px;
    background-color: yellow;
    opacity: 0.7;
    pointer-events: none;
    z-index: 9;
}

.laser-beam {
    position: absolute;
    width: 8px;
    background-color: red;
    opacity: 0.9;
    pointer-events: none;
    z-index: 10;
}

        .split-enemy {
            width: 35px;
            height: 35px;
            background-color: #FF5733;
        }

        .laser-enemy {
            width: 35px;
            height: 35px;
            background-color: #FF5733;
        }
 
        .obstacle {
            width: 30px;
            height: 30px;
            background-color: #f44336;
        }

.lava {
    position: absolute;
    width: 100%;
    bottom: 0;
    background-color: red;
    z-index: 5;
    height: 0;
    transition: height 0.1s linear;
}
 
        .power-up {
            width: 20px;
            height: 20px;
        }
 
        .bullet {
            width: 10px;
            height: 5px;
            background-color: #FFD700;
        }
 
        .burst {
            width: 20px;
            height: 20px;
            border-radius: 50%;
            background-color: rgba(255, 69, 0, 0.7);
            animation: burst 0.5s ease-out;
        }
 
        @keyframes burst {
            from { transform: scale(0.5); opacity: 1; }
            to { transform: scale(1.5); opacity: 0; }
        }
 
        .boss-door {
            width: 30px;
            height: 60px;
            background-color: #FFFF00;
        }
 
        .burst {
            width: 20px;
            height: 20px;
            border-radius: 50%;
            background-color: rgba(255, 69, 0, 0.7);
            animation: burst 0.5s ease-out;
        }   
 
        .boss {
            width: 60px;
            height: 60px;
            background-color: #FF4500;
        }


.reflective-enemy {
    width: 25px;
    height: 25px;
    background-color: #FF5733;
    border: 3px solid transparent; /* Initial border */
    box-shadow: 0 0 10px green; /* Glow effect */
}

        .mourning-enemy {
            width: 25px;
            height: 25px;
            background-color: #FF3333;
        }

        .sniper-enemy {
            width: 25px;
            height: 25px;
            background-color: #FF3333;
        }


 
        #score, #lives, #level, #timer, #shop-score {
            position: absolute;
            top: 10px;
            font-size: 16px;
        }

  #sandbox-overlay {
    position: fixed;
    top: 5%;
    left: 5%;
    width: 90%;
    height: 90%;
    background-color: #111;
    border: 2px solid #888;
    border-radius: 12px;
    z-index: 10000;
    display: none;
    color: white;
    font-family: Arial, sans-serif;
    overflow: hidden;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
  }
  #sandbox-tabs {
    display: flex;
    background-color: #222;
  }
  #sandbox-tabs button {
    background: none;
    border: none;
    padding: 10px 20px;
    cursor: pointer;
    color: white;
    font-weight: bold;
    border-bottom: 3px solid transparent;
    transition: border-color 0.3s;
  }
  #sandbox-tabs button.active {
    border-bottom: 3px solid #4caf50;
    color: #4caf50;
  }
  #sandbox-content {
    flex: 1;
    display: flex;
    background: #1a1a1a;
  }
  #elements-pane {
    width: 40%;
    border-right: 1px solid #333;
    padding: 10px;
    box-sizing: border-box;
    overflow-y: auto;
  }
  #elements-pane input {
    width: 100%;
    padding: 6px;
    margin-bottom: 10px;
    border: 1px solid #444;
    border-radius: 4px;
    background-color: #222;
    color: white;
  }
  #elements-list {
    max-height: calc(100% - 50px);
    overflow-y: auto;
  }
  #elements-list div {
    padding: 6px;
    cursor: pointer;
    border-radius: 4px;
    user-select: none;
  }
  #elements-list div:hover, #elements-list div.selected {
    background-color: #4caf50;
  }
  #preview-pane {
    width: 60%;
    padding: 10px;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: center;
  }
#element-preview {
    width: 150px;
    height: 150px;
    overflow: auto; /* allow scrolling if needed */
    box-sizing: border-box;
    border: 1px solid #444;
    border-radius: 8px;
    margin-bottom: 10px;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: #222;
    color: white;
}
  #spawn-control {
    margin-bottom: 20px;
    width: 100%;
  }
  #spawn-control label {
    display: block;
    margin: 5px 0;
  }
  #spawn-control input[type=number] {
    width: 80px;
    padding: 5px;
    background-color: #222;
    border: 1px solid #444;
    border-radius: 4px;
    color: white;
    margin-right: 10px;
  }
  #spawn-control button {
    padding: 6px 12px;
    background-color: #4caf50;
    border: none;
    color: white;
    font-weight: bold;
    cursor: pointer;
    border-radius: 4px;
  }
  #spawn-list {
    max-height: 150px;
    overflow-y: auto;
    width: 100%;
    background-color: #222;
    border-radius: 6px;
    border: 1px solid #444;
    padding: 10px;
    color: white;
  }
  #spawn-list-item {
    display: flex;
    justify-content: space-between;
    margin-bottom: 6px;
  }
  #spawn-list-item span {
    flex-grow: 1;
  }
  #sandbox-close {
    position: absolute;
    top: 6px;
    right: 12px;
    background: #f44336;
    border: none;
    color: white;
    font-weight: bold;
    border-radius: 50%;
    width: 30px;
    height: 30px;
    cursor: pointer;
  }
  /* Tabs content styling */
  .tab-content {
    padding: 15px;
    flex: 1;
    max-height: 400px;
    height: %;
    color: white;
    overflow-y: auto;
  }
  label {
    display: block;
    margin: 10px 0 5px 0;
  }
  input[type=range], input[type=number], select, input[type=text] {
    width: 100%;
    padding: 6px;
    border-radius: 4px;
    border: 1px solid #444;
    background-color: #222;
    color: white;
    box-sizing: border-box;
  }
  button.apply-btn {
    margin-top: 15px;
    background-color: #4caf50;
    border: none;
    padding: 8px 12px;
    font-weight: bold;
    cursor: pointer;
    border-radius: 4px;
  }
 
 
 
        #score { left: 10px; }
        #lives { right: 10px; }
        #level { left: 150px; }
        #timer { left: 250px; }
        #shop-score { left: 350px; }
 
        #instructions, #cutscene, #level-intro, #level-intro, #boss-fight, #boss-hallway, #game-over, #interact-message {
            position: absolute;
            width: 100%;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            background-color: rgba(0, 0, 0, 0.8);
            color: #fff;
            flex-direction: column;
            font-size: 18px;
            z-index: 10;
        }
 
        #instructions button, #cutscene button, #level-intro button, #level-intro2 button, #boss-fight button, #game-over button, #boss-hallway button {
            margin-top: 10px;
            padding: 10px 20px;
            font-size: 16px;
            cursor: pointer;
            background-color: #555;
            color: #fff;
        }
 
        #cutscene, #level-intro, #level-intro2, #boss-fight, #boss-hallway, #game-over, #interact-message {
            display: none;
        }

#element-sample > div {
    margin: auto;
    transform-origin: center center;
}
 
        #intro {
            position: absolute;
            width: 100%;
            height: 100%;
            display: flex;
            justify-content: space-around;
            align-items: center;
            background-color: rgba(0, 0, 0, 0.8);
            color: #fff;
            flex-direction: row;
            font-size: 18px;
            z-index: 11;
        }
 
#boss-health-bar {
    display: none; /* Initially hidden */
    position: absolute;
    top: 10px; /* Adjust based on your UI */
    left: 50%; /* Center it horizontally or adjust as needed */
    transform: translateX(-50%); /* Center alignment */
    width: 150px; /* Set fixed maximum width for the health bar */
    height: 20px; /* Height of the bar */
    background-color: #666; /* Background bar color */
    border: 1px solid #333; /* Border style */
    border-radius: 5px; /* Rounded corners */
    overflow: hidden; /* Prevent overflow */
    transition: width 0.5s ease; /* Smooth transition */
}

#boss-health {
    height: 100%;
    background-color: green; /* Initial health segment color */
    border-radius: 5px; /* Rounded corners for inner health */
}
 
        #friend {
            width: 30px;
            height: 30px;
            background-color: #00FF00;
            display: none;
        }
 
        #power-up-message {
            position: absolute;
            top: 50px;
            left: 50%;
            transform: translateX(-50%);
            font-size: 24px;
            z-index: 12;
            display: none;
        }
 
        /* New CSS for cool features */
        @keyframes flash {
            0%, 100% { opacity: 1; }
            50% { opacity: 0.5; }
        }
 
        .flashing {
            animation: flash 0.5s infinite;
        }
 
        .glow {
            box-shadow: 0 0 10px rgba(255,255,255,0.5);
        }
    </style>
</head>
<body>
    <div id="game-container">
        <div id="game-world">
            <div id="player"></div>
        </div>
<div id="upgrades-menu" style="display:none;">
    <h2>Upgrades</h2>
    <button onclick="previousUpgrade()" class="button">Previous</button>
    <div id="upgrade-list"></div>
    <button onclick="nextUpgrade()" class="button">Next</button>
    <button onclick="buyUpgrade()" class="button">Buy Upgrade</button>
    <button onclick="viewEquippedUpgrades()" class="button">View Equipped</button> <!-- New button -->
    <button onclick="closeUpgrades()" class="button">Close</button>
    <div id="message" style="color: red;"></div>
</div>

<div id="sandbox-overlay" role="dialog" aria-modal="true" aria-label="Sandbox Mode Editor" style="display:block; border:1px solid #ccc; padding:1em; max-width:700px; margin:auto; font-family: sans-serif;">
  <button id="sandbox-close" title="Close Sandbox Mode" style="float:right; font-size:1.5em; background:none; border:none; cursor:pointer;">×</button>

  <h2>Sandbox Mode Editor</h2>

  <div id="sandbox-tabs" role="tablist" aria-label="Sandbox Mode Tabs" style="display:flex; gap:1em; margin-bottom:1em; border-bottom: 1px solid #ccc;">
    <button role="tab" aria-selected="true" id="tab-insert" class="active" tabindex="0" style="padding:0.5em 1em; border:none; background:#eee; cursor:pointer;">Insert Element</button>
    <button role="tab" aria-selected="false" id="tab-charmod" tabindex="-1" style="padding:0.5em 1em; border:none; background:none; cursor:pointer;">Character Modifiers</button>
    <button role="tab" aria-selected="false" id="tab-charmod2" tabindex="-1" style="padding:0.5em 1em; border:none; background:none; cursor:pointer;">Modifiers 2</button>
    <button role="tab" aria-selected="false" id="tab-mapmod" tabindex="-1" style="padding:0.5em 1em; border:none; background:none; cursor:pointer;">Map Modifier</button>
  </div>

  <div id="sandbox-content">
    <!-- Insert Element Tab -->
    <div id="content-insert" class="tab-content" role="tabpanel" aria-labelledby="tab-insert">
      <div id="elements-pane" style="float:left; width:40%; margin-right:2%;">
        <input type="search" id="elements-search" aria-label="Search CSS classes" placeholder="Search CSS classes..." style="width:100%; padding:0.5em; margin-bottom:0.5em; box-sizing:border-box;" />
        <div id="elements-list" role="listbox" tabindex="0" aria-label="CSS Classes list" style="border:1px solid #ccc; height:200px; overflow-y:auto; padding:0.5em;"></div>
      </div>

      <div id="preview-pane" style="float:left; width:55%; border:1px solid #ccc; padding:1em; box-sizing:border-box;">
        <div id="element-preview" aria-live="polite" aria-atomic="true" aria-relevant="additions" style="min-height:2em; margin-bottom:1em; font-weight:bold; font-size:1.2em;">Select an element</div>
        <div id="spawn-control" style="margin-bottom:1em;">
          <label for="spawn-count" style="display:block; margin-bottom:0.25em;">Spawn count:</label>
          <input type="number" id="spawn-count" min="1" max="100" value="1" style="width:60px; margin-right:0.5em;" />
          <button id="spawn-btn" style="padding:0.3em 0.8em; margin-right:0.5em;">Spawn</button>
          <button id="change-spawn-btn" disabled style="padding:0.3em 0.8em;">Change Spawn Count</button>
        </div>
        <div>
          <strong>Spawned Elements:</strong>
          <div id="spawn-list" aria-live="polite" aria-atomic="true" style="min-height:70px; border:1px solid #ddd; padding:0.5em; overflow-y:auto; max-height:150px;"></div>
        </div>
      </div>
      <div style="clear:both;"></div>
    </div>

    <!-- Character Modifiers Tab -->
    <div id="content-charmod" class="tab-content" role="tabpanel" aria-labelledby="tab-charmod" hidden style="padding:1em; border:1px solid #ccc;">
      <label for="player-speed" style="display:block; margin-bottom:0.5em;">Player Speed (px/frame):</label>
      <input type="number" id="player-speed" min="1" max="20" value="5" style="width:80px; margin-bottom:1em;" />

      <label for="bullet-speed" style="display:block; margin-bottom:0.5em;">Bullet Speed (px/frame):</label>
      <input type="number" id="bullet-speed" min="1" max="20" value="5" style="width:80px; margin-bottom:1em;" />

      <button class="apply-btn" id="apply-charmod" style="padding:0.5em 1em;">Apply</button>
    </div>

    <!-- Modifiers 2 Tab -->
    <div id="content-charmod2" class="tab-content" role="tabpanel" aria-labelledby="tab-charmod2" hidden style="padding:1em; border:1px solid #ccc;">
      <label for="max-jumps" style="display:block; margin-bottom:0.5em;">Max Jumps (1=single, 2=double, 3=triple):</label>
      <input type="number" id="max-jumps" min="1" max="3" value="1" style="width:80px; margin-bottom:1em;" />

      <label for="player-lives" style="display:block; margin-bottom:0.5em;">Player Lives:</label>
      <input type="number" id="player-lives" min="1" max="20" value="3" style="width:80px; margin-bottom:1em;" />

      <button class="apply-btn" id="apply-charmod2" style="padding:0.5em 1em;">Apply</button>
    </div>

    <!-- Map Modifier Tab -->
    <div id="content-mapmod" class="tab-content" role="tabpanel" aria-labelledby="tab-mapmod" hidden style="padding:1em; border:1px solid #ccc;">
      <label for="background-color" style="display:block; margin-bottom:0.5em;">Game Background Color:</label>
      <input type="color" id="background-color" value="#333333" style="margin-bottom:1em;" />
      <button class="apply-btn" id="apply-mapmod" style="padding:0.5em 1em;">Apply</button>
    </div>
  </div>
</div>


        <div id="score">Score: 0</div>
        <div id="shop-score">Shop Score: 0</div>
        <div id="lives">Lives: 3</div>
        <div id="level">Level: 1</div>
        <div id="timer">Timer: 0</div>
        <div id="instructions">
            <p>Press Arrow Up to Jump</p>
            <p>Use Arrow Left/Right to Move</p>
            <p>Press Space to Shoot</p>
            <p>Press Z for Power-Up</p>
            <p>Press E to interact</p>
            <button onclick="showGameModeOptions()">Start Game</button> <!-- Start Game Button -->
            <button onclick="togglePause()">Pause/Resume</button>
            <button onclick="openUpgrades()">Open Upgrades</button>
        </div>
        <div id="cutscene">
            <p>Get ready for the next level!</p>
            <button onclick="continueGame()">Continue</button>
        </div>
    <div id="equipped-upgrades" style="display: none;"> <!-- Initially hidden -->
        <h3>Equipped Upgrades:</h3>
        <!-- Equipped upgrades will be displayed here -->
    </div>
<div id="game-mode-options" style="display: none;"> 
    <button onclick="startGamee()" class="button">Story Mode</button>
    <button id="endless-mode-btn" onclick="showLevelOptions()" class="button" style="display: none;">Endless Mode</button>
    <button onclick="startSandboxMode()" class="button" style="background:#c39;">Sandbox Mode</button>
</div>
    <div id="level-options" style="display: none;"> 
        <button onclick="startEndlessMode(1)" class="button" >Level 1</button> <!-- Level 1 Button -->
        <button onclick="startEndlessMode(2)" class="button">Level 2</button> <!-- Level 2 Button -->
        <button onclick="startEndlessMode(3)" class="button">Level 3</button> <!-- Level 3 Button -->
        <button onclick="startEndlessMode(4)" class="button">Level 4</button> <!-- Level 4 Button -->
        <button onclick="startEndlessMode(5)" class="button">Level 5</button> <!-- Level 4 Button -->

    </div>

    </div>
        <div id="level-intro">
            <p id="level-text">Get Ready for Adventure!</p>
            <button onclick="startLevel()">Start Level</button>
        </div>
       <div id="level-intro2">
            <p id="level-text">Get Ready for Adventure!</p>
            <button onclick="restartGame()">Start Endless mode</button>
        </div>
        <div id="boss-fight">
            <p>Defeat the Boss!</p>
        </div>
        <div id="game-over">
            <p>Game Over!</p>
            <button onclick="restartGame()">Restart</button>
        </div>
        <div id="boss-hallway">
            <p>You have entered the boss hallway! Prepare yourself!</p>
            <button onclick="startBossFight()">Proceed</button>
        </div>
        <div id="boss-health-bar">
            <div id="boss-health"></div>
        </div>
        <div id="power-up-message"></div>
        <div id="interact-message"></div>
        <div id="friend"></div>
    </div>
 
    <script>
            const gameContainer = document.getElementById('game-container');
            const gameWorld = document.getElementById('game-world');
            const player = document.getElementById('player');
            const scoreDisplay = document.getElementById('score');
            const maxUpgrades = 5; // Maximum number of upgrades you can equip
              let selectedElementDiv = null;
            const livesDisplay = document.getElementById('lives');
            const levelDisplay = document.getElementById('level');
            const timerDisplay = document.getElementById('timer');
            const instructions = document.getElementById('instructions');

            const cutscene = document.getElementById('cutscene');
            const levelIntro = document.getElementById('level-intro');
            const levelText = document.getElementById('level-text2');
            const levelIntro2 = document.getElementById('level-intro2');
            const levelText2 = document.getElementById('level-text');
            const bossFightScreen = document.getElementById('boss-fight');
            const gameOverScreen = document.getElementById('game-over');
            const intro = document.getElementById('intro');
            const dialoguePara = document.querySelector('#dialogue p');
const upgradesPerPage = 1; // Number of upgrades to show per page
            const bossHallway = document.getElementById('boss-hallway');
            const bossHealthBar = document.getElementById('boss-health-bar');
            const bossHealthDisplay = document.getElementById('boss-health');
let currentGameMode; // Temporary variable to store the current game mode

let currentEndlessLevel = localStorage.getItem('endlessLevel') ? parseInt(localStorage.getItem('endlessLevel')) : 1; // Endless Mode Level Tracking
let storyModeLevel = localStorage.getItem('storyLevel') ? parseInt(localStorage.getItem('storyLevel')) : 1; // Story Mode Level Tracking
let isEndlessMode = false; // Track if currently in Endless Mode
            let bulletSpeed = 5; // Initialize bullet speed
// Other variables...
            let phaseStartTime = null; // Track the start time of the boss phase
            let playerScore = localStorage.getItem('playerScore') ? parseInt(localStorage.getItem('playerScore')) : 0;
            const powerUpMessage = document.getElementById('power-up-message');
            let upgradesEquipped = []; // Store equipped upgrades
            const viruses = [];
            const interactMessage = document.getElementById('interact-message');
            const propertiesContainer = document.getElementById('properties-container');
            const friend = document.getElementById('friend');
            const obstacleSpawnDistance = 500; // Distance before the right edge
            let playerPositionX = 50;
            let upgradesPurchased = [];
            let boostDrainer = null;
            let selectedDiv = null;
            let boostDrainerLaser = null;
            let boostDrainerHP = 3;
const sandboxOverlay = document.getElementById('sandbox-overlay');
const sandboxClose = sandboxOverlay.querySelector('#sandbox-close');

const tabs = Array.from(sandboxOverlay.querySelectorAll('#sandbox-tabs button[role="tab"]'));
const tabContents = Array.from(sandboxOverlay.querySelectorAll('.tab-content'));

const elementsSearch = sandboxOverlay.querySelector('#elements-search');
const elementsList = sandboxOverlay.querySelector('#elements-list');
const elementPreview = sandboxOverlay.querySelector('#element-preview');
const spawnCountInput = sandboxOverlay.querySelector('#spawn-count');
const spawnButton = sandboxOverlay.querySelector('#spawn-btn');
const changeSpawnButton = sandboxOverlay.querySelector('#change-spawn-btn');
const spawnList = sandboxOverlay.querySelector('#spawn-list');

// Character Modifiers and others
const playerSpeedInput = sandboxOverlay.querySelector('#player-speed');
const bulletSpeedInput = sandboxOverlay.querySelector('#bullet-speed');
const applyCharmodButton = sandboxOverlay.querySelector('#apply-charmod');

const maxJumpsInput = sandboxOverlay.querySelector('#max-jumps');
const playerLivesInput = sandboxOverlay.querySelector('#player-lives');
const applyCharmod2Button = sandboxOverlay.querySelector('#apply-charmod2');

const backgroundColorInput = sandboxOverlay.querySelector('#background-color');
const applyMapmodButton = sandboxOverlay.querySelector('#apply-mapmod');
            let boostDrainerState = "moving"; // "moving", "green", "yellow", "red", "firing", "dead"
            let boostDrainerAttackTimeout = null;
            const boostDrainerAttackXOffset = 250; // how close to player it moves before attack
            const boostDrainerSpeed = 1.0; // pixels per frame
            let virusDroneHits = 0;  // tracks hits on Virus Drone
            let playerPositionY = 0;
  let currentSelectedClass = null;
  // Store spawned elements with counts: { className: count, elements: [DOM elements] }
            let playerVelocityX = 0;
            let objectSpawnDistance = 300; // Distance from the right edge to spawn new objects
            let playerVelocityY = 0;
            let removedEnemies = [];
            let phaseThreeStarted = false; // Flag to track if Phase Three has started
            let phaseThreeStarted1 = false; // Flag to track if Phase Three has started
            let phaseThreeStarted3 = false; // Flag to track if Phase Three has started
            let bossDefeatedMessageDisplayed = false; // Flag to track if the defeated message has been displayed
            let playerMaxSpeed = 5;
            const playerJumpStrength = 12;
            let jumpCount = 0;
            let maxJumps = 1;
            let isDoubleJumpEnabled = false;
            let isJumping = false;
            let isCycling = false;  // Lock to prevent concurrent calls
            let isPaused = false;
            let canShoot = true;
            let waveCooldown = false; // Track if a wave is on cooldown
            let bossAttacking = false;
            let bossAttackPhase = 0;
            let gameInterval;
            let obstacles = [];
              let allCssClasses = [];
const spawnedElements = {};
            let enemies = [];
            const shownPreMessages = {};
            let bullets = [];
let currentSearchResults = [];
let currentPage = 0;
const elementsPerPage = 5;
            let powerUps = [];
            let boostDrainerChain = null;
            let isTeleporting = false; // Track whether teleport is available
            let platforms = [];
            let bossDoors = [];
            let maxPlayerPositionX = 50;  // Track furthest progress
            let coins = [];
            let score = 0;
            let isInBossDoor = false;
            let lives = 3;
            let level = localStorage.getItem('playerLevel') ? parseInt(localStorage.getItem('playerLevel')) : 1;
            const gravity = 0.5;
            const maxLevels = 5;
            let movingLeft = false, movingRight = false;
            let currentDirection = 1;
            let currentPowerUp = null;
            let powerUpTimer = 0;
            let gameScrollPosition = 0;
            let maxGameScrollPosition = 0; // Holds furthest right camera scroll so far
            let leftBoundaryX = 0; // Moving left boundary for player position
            const bossScoreThreshold = 1;
            const dialogues = [
                "Player: Hey friend! What a nice day for an adventure!",
                "Friend: Indeed! Maybe we should explore the caves.",
                "Player: What's that over there? Is it the King?",
                "King: Haha, I've found you! You're coming with me!",
                "Friend: Player, help me!"
            ];
            let dialogueIndex = 0;
            let boss = null;
            let bossHealth = 100;
            let bossShielded = true;
            let bossPowerObtained = false;
            let bossFightActive = false;
 
const allPowerUpTypes = [
    "super-speed", "invincibility", "teleportation",
    "reflective-shield", "double-shot", "extra-life", 
    "score-boost", "mega-jump", "energy-blast", "light-speed", 
    "blazing-trail", "sonic-wave", "armor", "telekinetic", 
    "camouflage", "dimension-shift", "energy-drain", "mind-control", 
    "hologram", "fire", "ice", "hypno"
];
 
            window.addEventListener('keydown', handleKeydown);
            window.addEventListener('keyup', handleKeyup);


const upgrades = [
    { name: 'Super Speed', price: 4500, effect: 'Increase speed by 10%', id: 'speedBoost' },
    { name: 'Super bullet', price: 1200, effect: 'Faster bullet speed', id: 'doubleDamage' },
    { name: 'Double jump', price: 7500, effect: 'Double jump', id: 'doubleJump' },
    { name: 'Extra Lives', price: 2500, effect: 'Gain 3 extra lives', id: 'ExtraLives' }, // Add this line for Extra Lives
    // Add more upgrades as needed
];

function getCssClasses() {
    const classes = new Set();
    for (const sheet of document.styleSheets) {
        try {
            if (!sheet.cssRules) continue; // skip if no rules available
            for (const rule of sheet.cssRules) {
                if (rule.selectorText) {
                    const selectors = rule.selectorText.split(/\s*,\s*/);
                    selectors.forEach(selector => {
                        // Match class names in selectors (e.g. ".enemy", ".split-enemy", ".boss-door")
                        const matches = selector.match(/\.(\w[\w-]*)/g);
                        if (matches) {
                            matches.forEach(cls => classes.add(cls.substring(1)));
                        }
                    });
                }
            }
        } catch (e) {
            // Ignore CORS protected stylesheets
        }
    }
    return Array.from(classes).sort();
}

// Render elements with search and preview support



function showEndlessModeButton() {
    const endlessBtn = document.getElementById('endless-mode-btn');
    if (endlessBtn) {
        endlessBtn.style.display = 'inline-block';
        endlessBtn.disabled = false;
    }
}

// Function to select an upgrade
// Function to select the current upgrade
function selectUpgrade(index) {
    selectedUpgrade = upgrades[index]; // Select the upgrade at the given index
}

function updateShopScoreDisplay() {
    const shopScoreDisplay = document.getElementById('shop-score');
    shopScoreDisplay.textContent = `Shop Score: ${playerScore}`; // Display the total amount
}

// Function to display current selected upgrade details
function displaySelectedUpgrade() {
    const upgradeInfo = document.getElementById("upgrade-list");
    upgradeInfo.innerHTML += `<br><strong>Selected Upgrade:</strong><br>
        ${selectedUpgrade.name}<br>
        Price: ${selectedUpgrade.price}<br>
        Effect: ${selectedUpgrade.effect}<br>`;
}

// Declare the selectedUpgrade at the top
let selectedUpgrade = null;
let currentUpgradeIndex = 0; // Keep track of the currently selected upgrade

// Function to open upgrades
function openUpgrades() {
    document.getElementById("instructions").style.display = "none"; // Hide main menu
    document.getElementById("upgrades-menu").style.display = "block"; // Show upgrades menu
    displayUpgradeOptions(); // Display available upgrades
    selectUpgrade(currentUpgradeIndex); // Start with first upgrade selected
}



function closeUpgrades() {
    document.getElementById("upgrades-menu").style.display = "none"; // Hide upgrades menu
    document.getElementById("instructions").style.display = "flex"; // Show main menu again
}

// Function to buy the selected upgrade
// Function to buy the selected upgrade
// Function to buy the selected upgrade

        function showGameModeOptions() {
            document.getElementById('instructions').style.display = 'none'; // Hide start button
            document.getElementById('game-mode-options').style.display = 'block'; // Show game mode options
        }

        // Function to show level options for Endless Mode
        function showLevelOptions() {
            document.getElementById('game-mode-options').style.display = 'none'; // Hide game mode options
            document.getElementById('level-options').style.display = 'block'; // Show level buttons
        }




function startEndlessMode(chosenLevel) {
    console.log('Endless Mode Selected for Level:', chosenLevel); // Debug log
        document.getElementById('level-options').style.display = 'none'; // Hide level options
    // Set the game mode to Endless
    localStorage.setItem('gameMode', 'endless'); // This sets the gameMode in local storage
    isEndlessMode = true; // Indicate that we are now in endless mode
    currentEndlessLevel = chosenLevel; // Set the chosen level for this session
    
    localStorage.setItem('endlessLevel', currentEndlessLevel); // Save the selected level to local storage

    resetGame(); // Reset your game state

    switchLevelBackground(); // Set the correct background according to currentEndlessLevel

    spawnEndlessEntities(); // Spawn enemies based on the current endless level

checkCollisionWithPlatformsAndObstacles();

    gameInterval = setInterval(gameLoop, 1000 / 60); // Start the game loop    
}

// Ensure the currentEndlessLevel is used in your functions where needed, 
// for instance in the game loop or resetGame function if appropriate
window.addEventListener('load', () => {
    loadEquippedUpgrades();

    const endlessUnlocked = localStorage.getItem('endlessModeUnlocked') === 'true';

    const endlessBtn = document.getElementById('endless-mode-btn');

    const sandboxOverlay = document.getElementById('sandbox-overlay');
    if (sandboxOverlay) {
        sandboxOverlay.style.display = 'none';
    }

  loadAllCssClasses();
  updateCharModInputs();
  updateCharMod2Inputs();
  updateMapModInput();
  changeSpawnButton.disabled = true;

    if (endlessUnlocked) {
        // Show endless mode button properly
        if (endlessBtn) {
            endlessBtn.style.display = 'inline-block';  // Show
            endlessBtn.disabled = false;
            endlessBtn.style.visibility = 'visible';
            endlessBtn.removeAttribute('hidden');
        }
    } else {
        // Hide endless mode button initially
        if (endlessBtn) {
            endlessBtn.style.display = 'none';
        }
    }

    // Reset temp variables - only if you really intend to reset them on load
    currentGameMode = null;
    currentEndlessLevel = null;
});

// Store purchased upgrades separately

// Function to buy and equip/unequip upgrades
function buyUpgrade() {
    const upgrade = upgrades[currentPage]; // Get the currently displayed upgrade
    if (!upgrade) {
        return displayMessage("Please select an upgrade.");
    }

    const score = parseInt(localStorage.getItem('playerScore')) || 0;
    const upgradeIndex = upgradesEquipped.indexOf(upgrade.id);
    const purchasedIndex = upgradesPurchased.indexOf(upgrade.id);

    // If the upgrade is already equipped
    if (upgradeIndex > -1) {
        // Unequip logic
        upgradesEquipped.splice(upgradeIndex, 1);
        removeUpgradeEffects(upgrade); // Remove effects of the unequipped upgrade
        displayMessage(`${upgrade.name} has been unequipped!`);
    } else {
        // If the upgrade is already purchased but not equipped
        if (purchasedIndex > -1) {
            // Just equip the upgrade
            upgradesEquipped.push(upgrade.id);
            applyUpgrade(upgrade); // Apply effects of the newly equipped upgrade
            displayMessage(`${upgrade.name} has been equipped!`);
        } else {
            // Check if the player has enough score to buy the upgrade
            if (score < upgrade.price) {
                return displayMessage("You need more score to buy this upgrade.");
            }

            // Deduct the cost and "purchase" the upgrade
            localStorage.setItem('playerScore', score - upgrade.price);
            upgradesPurchased.push(upgrade.id); // Mark the upgrade as purchased
            upgradesEquipped.push(upgrade.id); // Equip it
            applyUpgrade(upgrade); // Apply effects of the newly equipped upgrade
            displayMessage(`${upgrade.name} has been equipped!`);
        }
    }

    // Save the equipped upgrades and purchased upgrades to local storage
    saveUpgrades();
    
    // Refresh equipped display if needed
    updateEquippedDisplay(); 

    // Update the button text or state accordingly
    updateButtonText(upgrade.id);
}

function loadEquippedUpgrades() {
    const savedUpgradesEquipped = localStorage.getItem('upgradesEquipped');
    if (savedUpgradesEquipped) {
        upgradesEquipped = JSON.parse(savedUpgradesEquipped); // Update contents instead of reassigning with const
        upgradesEquipped.forEach(upgradeId => {
            const upgrade = upgrades.find(up => up.id === upgradeId);
            if (upgrade) {
                applyUpgrade(upgrade); // Apply effects of loaded upgrades
            }
        });
    }

    const savedUpgradesPurchased = localStorage.getItem('upgradesPurchased');
    if (savedUpgradesPurchased) {
        upgradesPurchased = JSON.parse(savedUpgradesPurchased); // Update contents
    }
}

// Function to save the upgrades to local storage
function saveUpgrades() {
    localStorage.setItem('upgradesEquipped', JSON.stringify(upgradesEquipped));
    localStorage.setItem('upgradesPurchased', JSON.stringify(upgradesPurchased));
}

// Function to update the button text based on the equipped state
function updateButtonText(upgradeId) {
    const upgrade = upgrades.find(up => up.id === upgradeId);
    if (upgrade) {
        const button = document.getElementById('upgrade-list'); // Assume the button has this ID
        const isEquipped = upgradesEquipped.indexOf(upgradeId) > -1;
        button.textContent = isEquipped ? "Unequip" : "Buy Upgrade"; 
    }
}

// Function to remove effects when unequipping an upgrade
function removeUpgradeEffects(upgrade) {
    switch (upgrade.id) {
        case 'speedBoost':
            playerMaxSpeed -= 1.5; // Revert speed increase
            break;
        case 'doubleDamage':
            bulletSpeed -= 7;
            break;
        case 'doubleJump':
            maxJumps = 1
            isDoubleJumpEnabled = false; // Enable double jump
            console.log('Double Jump Activated!');
            break;
        case 'ExtraLives': // New case for Extra Lives upgrade
            removeLife();
            console.log('Extra lives granted! Total lives:', lives); // Log the new lives total
            break;
        // Add additional cases for removing effects of new upgrades here
    }
}

function startGamee() {
                localStorage.setItem('gameMode', 'story'); // Set game mode to endless
                startGame();
}

// Function to apply effects of an upgrade
function applyUpgrade(upgrade) {
    switch (upgrade.id) {
        case 'speedBoost':
            playerMaxSpeed += 2; // Increase speed
            break;
        case 'doubleDamage':
            bulletSpeed += 7;
            break;
        case 'doubleJump':
            maxJumps = 2; // Allow an additional jump
            isDoubleJumpEnabled = true; // Enable double jump
            console.log('Double Jump Activated! You can now jump again mid-air.');
            break;
        case 'ExtraLives': // New case for Extra Lives upgrade
            gainExtraLife2();
            console.log('Extra lives granted! Total lives:', lives); // Log the new lives total
            break;
        // Add additional cases for new upgrades here
    }
}

// Function to view equipped upgrades
function viewEquippedUpgrades() {
    const equippedList = document.getElementById("equipped-upgrades");
    
    // Toggle display of the equipped upgrades
    if (equippedList.style.display === "none") {
        equippedList.style.display = "block"; // Show the equipped upgrades
        updateEquippedDisplay(); // Update the display with currently equipped upgrades
    } else {
        equippedList.style.display = "none"; // Hide the equipped upgrades
    }
}

// Function to update the equipped display
function viewEquippedUpgrades() {
    // Open a new blank tab
    const equippedWindow = window.open("", "_blank");
    
    // Create the HTML content for the equipped upgrades
    let equippedContent = '<html><head><title>Equipped Upgrades</title></head><body>';
    equippedContent += '<h3>Equipped Upgrades:</h3>'; // Add header

    if (upgradesEquipped.length === 0) {
        equippedContent += "<p>No upgrades equipped.</p>"; // Message when no upgrades are equipped
    } else {
        upgradesEquipped.forEach(id => {
            const upgrade = upgrades.find(upg => upg.id === id);
            if (upgrade) {
                equippedContent += `
                    <div>
                        <strong>${upgrade.name}</strong><br>
                        Price: ${upgrade.price}<br>
                        Effect: ${upgrade.effect}<br>
                    </div>
                    <hr>
                `;
            }
        });
    }

    equippedContent += '</body></html>'; // Close HTML tags
    
    // Write the content to the new window
    equippedWindow.document.write(equippedContent);
    equippedWindow.document.close(); // Close the document for rendering
}

function updateEquippedDisplay() {
    const equippedList = document.getElementById("equipped-upgrades");
    equippedList.innerHTML = ""; // Clear the current display

    if (upgradesEquipped.length === 0) {
        equippedList.innerHTML = "<p>No upgrades equipped.</p>"; // Handle the case where no upgrades are equipped
    } else {
        upgradesEquipped.forEach(id => {
            const upgrade = upgrades.find(upg => upg.id === id);
            if (upgrade) {
                equippedList.innerHTML += `
                    <div>
                        <strong>${upgrade.name}</strong><br>
                        Price: ${upgrade.price}<br>
                        Effect: ${upgrade.effect}<br>
                    </div>
                    <hr>
                `;
            }
        });
    }
}

if (upgradesEquipped.includes(selectedUpgrade.id)) {
    // Unequip logic
    const index = upgradesEquipped.indexOf(selectedUpgrade.id);
    if (index > -1) upgradesEquipped.splice(index, 1);
    displayMessage(`${selectedUpgrade.name} is now unequipped!`);
} else {
    // Equip logic
    localStorage.setItem('playerScore', score - selectedUpgrade.price);
    upgradesEquipped.push(selectedUpgrade.id);
    displayMessage(`${selectedUpgrade.name} has been equipped!`);
}

// Refresh equipped display
updateEquippedDisplay(); // Call it here to update the UI

function updateNavigationButtons(totalUpgrades) {
    const prevBtn = document.querySelector('#upgrades-menu button[onclick="previousUpgrade()"]');
    const nextBtn = document.querySelector('#upgrades-menu button[onclick="nextUpgrade()"]');
    
    prevBtn.disabled = currentPage === 0; // Disable if on the first page
    nextBtn.disabled = (currentPage + 1) * upgradesPerPage >= totalUpgrades; // Disable if on the last page
}

function startSandboxMode() {
    const overlay = document.getElementById('sandbox-overlay');
    overlay.style.display = 'flex';  // Show the overlay as flex container
    level = 1
  loadAllCssClasses();
  updateCharModInputs();
  updateCharMod2Inputs();
currentSearchResults = allCssClasses.slice();
renderElementsListPage();
  updateMapModInput();
  changeSpawnButton.disabled = true;
}

// Function to display messages to the player
function displayMessage(text, seconds = 3) {
    bossMessageElement.textContent = text; // example
    bossMessageElement.style.display = "block";
    setTimeout(() => {
        bossMessageElement.style.display = "none";
    }, seconds * 1000);
}

function nextUpgrade() {
    if (currentPage < upgrades.length - 1) {
        currentPage++;
        displayUpgradeOptions();
    }
}

function previousUpgrade() {
    if (currentPage > 0) {
        currentPage--;
        displayUpgradeOptions();
    }
}

function displayUpgradeOptions() {
    const upgradeList = document.getElementById("upgrade-list");
    const upgrade = upgrades[currentPage];


    const equipped = upgradesEquipped.includes(upgrade.id) ? " (Equipped)" : ""; // Check if equipped
    upgradeList.innerHTML = `
        <strong>${upgrade.name}</strong>${equipped}<br>
        Price: ${upgrade.price}<br>
        Effect: ${upgrade.effect}<br>
    `;

    // Update navigation buttons
    updateNavigationButtons();
}

 
function handleKeydown(e) {
    switch (e.key) {
        case 'ArrowLeft':
            movingLeft = true;
            currentDirection = -1;
            break;
        case 'ArrowRight':
            movingRight = true;
            currentDirection = 1;
            break;
        case 'ArrowUp':
            handleJump();
            break;
        case ' ': // Space bar for shooting
            if (canShoot) {
                shootBullet(currentDirection);
                canShoot = false;
                setTimeout(() => canShoot = true, 300);
            }
            break;
        case 'z':
        case 'Z': // Power-Up activation
            if (currentPowerUp) { // Check if there is a power-up to use
                usePowerUp();
            } else if (bossPowerObtained) { // Charge if the boss power is obtained and no power-up is active
                isCharging = true;
                chargeTime = 0;
            }
            break;
        case 'e':
        case 'E':
            interact(); // Trigger the interact function when 'E' is pressed
            break;
    }
}
 
function handleKeyup(e) {
    switch (e.key) {
        case 'ArrowLeft':
            movingLeft = false;
            break;
        case 'ArrowRight':
            movingRight = false;
            break;
        case 'z':
        case 'Z':
            if (bossPowerObtained && isCharging) {
                isCharging = false;
                shootLaserBlast(chargeTime);
            }
            break;
    }
}
 
 
function handleJump() {
    if (playerPositionY === 0) { // If the player is on the ground, perform a regular jump
        playerVelocityY = playerJumpStrength; // Apply jump force
        jumpCount = 1; // Set jump count to indicate first jump
        isJumping = true; // Set jumping status to true
    } else if (jumpCount < maxJumps) { // Allow double jump if jump count allows
        doubleJump(); // Call double jump function
    }
}
 
            function nextDialogue() {
                if (dialogueIndex < dialogues.length - 1) {
                    dialogueIndex++;
                    dialoguePara.textContent = dialogues[dialogueIndex];
                } else {
                    intro.style.display = 'none';
                    startGame();
                }
            }



function doubleJump() {
    if (jumpCount < maxJumps) { // Check if the player can still jump
        playerVelocityY = playerJumpStrength; // Apply jump force
        jumpCount++; // Increment the jump count
        isJumping = true; // Set jumping status to true
    }
}
 
            function shootBullet(direction) {
                const bullet = createBullet(direction);
                bullets.push({ element: bullet, direction });
                gameWorld.appendChild(bullet);
 
                if (currentPowerUp === 'double-shot') {
                    const altBullet = createBullet(direction + 1);
                    bullets.push({ element: altBullet, direction });
                    gameWorld.appendChild(altBullet);
                }
 
                if (currentPowerUp === 'speed-bullet') {
                    const sideBullet1 = createBullet(direction + 6);
                    const sideBullet2 = createBullet(direction - 6);
                    bullets.push({ element: sideBullet1, direction });
                    bullets.push({ element: sideBullet2, direction });
                    gameWorld.appendChild(sideBullet1);
                    gameWorld.appendChild(sideBullet2);
                }
            }
 
            function createBurst(x, y) {
                const burst = document.createElement('div');
                burst.classList.add('burst');
                burst.style.left = x + 'px';
                burst.style.bottom = y + 'px';
                gameWorld.appendChild(burst);
                setTimeout(() => burst.remove(), 500);
            }
 
function moveCamera() {
    if (!isInBossDoor) {
        let proposedScroll = Math.max(0, playerPositionX - (gameContainer.offsetWidth / 2));

        if (proposedScroll > maxGameScrollPosition) {
            maxGameScrollPosition = proposedScroll;
        }
        gameScrollPosition = maxGameScrollPosition;
    } else {
        // Inside boss door, camera follows player freely (no scrolling restrictions)
        gameScrollPosition = Math.max(0, playerPositionX - (gameContainer.offsetWidth / 2));
    }

    gameWorld.style.transform = `translateX(${-gameScrollPosition}px)`;
}

// Function to reset player and possibly generate more obstacles
function resetPlayerPosition() {
    playerPositionX = 50; // Reset to starting position
    player.style.left = playerPositionX + 'px'; // Ensure the player is positioned correctly

    // Optionally, regenerate obstacles or enemies here
    regenerateEntities(); // Call a function that generates new obstacles and/or enemies
}

// Function to regenerate entities
function regenerateEntities() {
    // Logic to create and append new obstacles/enemies depending on your game mechanics
    for (let i = 0; i < 5; i++) { // Change the number to spawn desired quantity
        spawnObstacle(); // or spawnEnemy(); as needed
    }
}
 
let summonCooldown = 0;
 
function summonAllies() {
    for (let i = 0; i < 3; i++) {
        let ally = createElement('ally', [], parseInt(player.style.left) + (i * 30));
        ally.style.bottom = player.style.bottom;
        gameWorld.appendChild(ally);
 
        let destroyCount = 0;
        let moveInterval = setInterval(() => {
            ally.style.left = (parseInt(ally.style.left) + 5) + 'px';
 
            enemies.forEach((enemy, index) => {
                if (checkCollision(ally, enemy) && destroyCount < 3) {
                    enemy.remove();
                    enemies.splice(index, 1);
                    destroyCount++;
                }
            });
 
            if (destroyCount >= 3) {
                ally.remove();
                clearInterval(moveInterval);
            }
        }, 50);
 
        setTimeout(() => {
            ally.remove();
            clearInterval(moveInterval);
        }, 5000);
    }
}
 
 
 
function createBulletTrail(x, y) {
    const trail = document.createElement('div');
    trail.classList.add('bullet-trail');
    trail.style.left = x + 'px';
    trail.style.bottom = y + 'px';
    gameWorld.appendChild(trail);
 
    setTimeout(() => {
        trail.style.opacity = '0';
        setTimeout(() => trail.remove(), 300);
    }, 50);
}
 
function moveBullets() {
    bullets.forEach((bulletObj, index) => {
        const bullet = bulletObj.element;
        const bulletDirection = bulletObj.direction;

        // Calculate new position
        const newX = parseInt(bullet.style.left) + (bulletDirection * bulletSpeed);
        bullet.style.left = newX + 'px';

        createBulletTrail(newX, parseInt(bullet.style.bottom));

        // Remove if out of bounds
        if (newX > gameScrollPosition + gameContainer.offsetWidth || newX < 0) {
            bullet.remove();
            bullets.splice(index, 1);
        } else {
            // Check collisions with enemies
            for (let enemyIndex = 0; enemyIndex < enemies.length; enemyIndex++) {
                const enemy = enemies[enemyIndex];
                if (checkCollision(bullet, enemy)) {
                    if (enemy.classList.contains('reflective-enemy')) {
                        // Handle reflective enemy bullet collision
                        handleBulletCollisionWithReflectiveEnemy(enemy, bullet);
                        bullet.remove();
                        bullets.splice(index, 1);
                        break;
                    } else if (enemy.classList.contains('boost-drainer')) {
                        // Handle boost drainer bullet collision
                        if (handleBoostDrainerHit(bulletObj, index)) {
                            // Bullet handled and removed inside handler
                            break;
                        }
                    } else {
                        // Handle other enemy hits
                        handleEnemyHit(enemy, enemyIndex);
                        createBurst(newX, parseInt(bullet.style.bottom));
                        bullet.remove();
                        bullets.splice(index, 1);
                        break;
                    }
                }
            }
            checkBossHit();
        }
    });
}
 
function handleEnemyHit(enemy, enemyIndex) {
    if (enemy.classList.contains('split-enemy')) {
        handleSplitterEnemyHit(enemy, enemyIndex);
    } else if (enemy.classList.contains('infected')) {
        // Existing infected enemy logic...
        let shieldHitsLeft = parseInt(enemy.dataset.shieldHitsLeft) || 0;

        if (shieldHitsLeft > 0) {
            shieldHitsLeft--;
            enemy.dataset.shieldHitsLeft = shieldHitsLeft.toString();

            if (shieldHitsLeft === 0) enemy.classList.remove('shielded');

            enemy.style.opacity = '0.5';
            setTimeout(() => {
                if (enemy) enemy.style.opacity = '0.8';
            }, 150);
            return;
        }

        let health = parseInt(enemy.dataset.health) || 1;
        health--;

        if (health <= 0) {
            enemy.remove();
            enemies.splice(enemyIndex, 1);
        } else {
            enemy.dataset.health = health.toString();
            enemy.style.opacity = '0.5';
            setTimeout(() => {
                if (enemy) enemy.style.opacity = '0.8';
            }, 150);
        }
    } else {
        // Normal enemy - destroy immediately
        enemy.remove();
        enemies.splice(enemyIndex, 1);
    }

    score += 10;
    playerScore += 50;
    localStorage.setItem('playerScore', playerScore);
    updateDisplay();
}
 
function startGame() {
    // Hide game mode options and other screens
    document.getElementById("game-mode-options").style.display = "none";
    gameOverScreen.style.display = 'none';
    instructions.style.display = 'none';

    // Retrieve the game mode from local storage
    const gameMode = localStorage.getItem('gameMode');

    if (gameMode === 'story') {
        // Logic for starting Story Mode
        resetGame(false); // Continue from current Story Mode level
        levelIntro.style.display = 'flex'; // Show level intro for Story Mode
    } else if (gameMode === 'endless') {
        // Logic for starting Endless Mode
        if (!localStorage.getItem('endlessLevel')) {
            localStorage.setItem('endlessLevel', '1'); // Start Endless level at 1 if not set
        }
        resetGame(false); // Continue from last saved Endless level
        levelIntro.style.display = 'flex'; // Show level intro for Endless Mode
    } else {
        // Default to Story Mode if no mode is set
        localStorage.setItem('gameMode', 'story'); // Default to Story Mode
        localStorage.setItem('storyLevel', '2'); // Set initial level for Story Mode
        resetGame(true); // Start a new game
        levelIntro.style.display = 'flex'; // Show level intro screen
    }
}
 
            function startLevel() {
                levelIntro.style.display = 'none';
                gameInterval = setInterval(gameLoop, 1000 / 60);
            }
 
function resetGame(isNewGame = false) {
    lives = upgradesEquipped.includes('ExtraLives') ? 6 : 3; // Set lives based on the Extra Lives upgrade

    // Reset player state variables
    playerPositionX = 50; 
    playerPositionY = 0; 
    playerVelocityX = 0; 
    playerVelocityY = 0; 
    isJumping = false;
    jumpCount = 0;
    isDoubleJumpEnabled = false; 
    gameScrollPosition = 0; 
    
    clearAllElements(); // Clear all game entities

    // Reset the level based on the game mode.
    const gameMode = localStorage.getItem('gameMode');
    if (gameMode === 'endless') {
        level = localStorage.getItem('endlessLevel') 
                ? parseInt(localStorage.getItem('endlessLevel')) // Retrieve endless level
                : 1; // Start at Level 1 if none found
    } else {
        level = localStorage.getItem('storyLevel') 
                ? parseInt(localStorage.getItem('storyLevel')) 
                : 1; // Default for story mode
    }

    switchLevelBackground(); // Set the background according to the current level

    updateDisplay(); // Reflect updates on the UI
}


 
function updateDisplay() {
    if (isEndlessMode) {
        // For Endless Mode
        levelDisplay.textContent = `Level: ${currentEndlessLevel}`;
    } else {
        // For Story Mode
        levelDisplay.textContent = `Level: ${storyModeLevel}`;
    }
    scoreDisplay.textContent = `Score: ${score}`;
    livesDisplay.textContent = `Lives: ${lives}`;
    timerDisplay.textContent = `Timer: ${powerUpTimer}`;
}
 



function updatePlayerPosition() {
    // Calculate velocity based on input
    if (movingRight) {
        playerVelocityX = playerMaxSpeed;
    } else if (movingLeft) {
        playerVelocityX = -playerMaxSpeed;
    } else {
        playerVelocityX = 0;
    }

    // Tentative new position
    let newPlayerX = playerPositionX + playerVelocityX;

    if (!isInBossDoor) {
        // Moving border and player left clamp applied only outside boss door/fight
        let proposedScroll = Math.max(0, newPlayerX - (gameContainer.offsetWidth / 2));

        if (proposedScroll > leftBoundaryX) {
            leftBoundaryX = proposedScroll;
        }

        if (newPlayerX < leftBoundaryX) {
            // Clamp player so they cannot move backward beyond moving border
            newPlayerX = leftBoundaryX;
        }
    }
    // Inside boss door, no restrictions on player X movement
    playerPositionX = newPlayerX;
    player.style.left = playerPositionX + 'px';

    // Jump/gravity logic stays the same...

    let onPlatform = checkCollisionWithPlatformsAndObstacles();

    platforms.forEach(platform => {
        if (checkCollision(player, platform) && playerVelocityY < 0) {
            playerPositionY = parseInt(platform.style.bottom) + platform.offsetHeight;
            playerVelocityY = 0;
            isJumping = false;
            jumpCount = 0;
            onPlatform = true;
        }
    });

    if (!onPlatform || isJumping) {
        playerVelocityY -= gravity;
        playerPositionY += playerVelocityY;

        if (playerPositionY <= 0) {
            playerPositionY = 0;
            playerVelocityY = 0;
            isJumping = false;
            jumpCount = 0;
        }
    } else {
        playerVelocityY = 0;
    }
    player.style.bottom = playerPositionY + 'px';

    // Move camera (handles boss door differently)
    moveCamera();
}


 
function spawnEntities() {
    if (!isPaused && !bossFightActive) {
        if (Math.random() < 0.003) spawnObstacle();
        
        // Spawn enemies based on the current level
        if (level === 1) {
            if (Math.random() < 0.005) spawnEnemy();
            if (Math.random() < 0.003) spawnFlyingEnemy();
            if (Math.random() < 0.002) spawnObstacle();
        } else if (level === 2) {
            if (Math.random() < 0.005) spawnEnemy();
            if (Math.random() < 0.002) spawnObstacle();
            if (Math.random() < 0.003) spawnChargingEnemy(); // Charging enemy option for Level 2
            if (Math.random() < 0.001) spawnSniperEnemy(); // Sniper enemy option for Level 2
        } else if (level === 3) {
            if (Math.random() < 0.005) spawnEnemy();
            if (Math.random() < 0.002) spawnObstacle();
            if (Math.random() < 0.003) spawnFlyingEnemy(); // Flying enemy option for Level 3
            if (Math.random() < 0.001) spawnReflectiveEnemy(); // Reflective enemy option for Level 3
        } else if (level === 4) {
            if (Math.random() < 0.001) spawnLaserEnemy();
            if (Math.random() < 0.002) spawnSplitterEnemy();
        } else if (level === 5) {
            if (Math.random() < 0.005) spawnEnemy();
            if (Math.random() < 0.002) spawnVirusDrone();
            if (Math.random() < 0.001) spawnSplitterEnemy();
        }

        if (Math.random() < 0.002 && !currentPowerUp) spawnPowerUp();
        if (Math.random() < 0.001) spawnPlatform();
        if (Math.random() < 0.003) spawnCoin();



        // Manage boss door spawning only if in Story Mode
        if (localStorage.getItem('gameMode') === 'story') {
            if (bossDoors.length === 0 && score >= level * bossScoreThreshold && enemies.length === 0) {
                spawnBossDoor();
            }
        }
    }
}
 

function cleanUpObjects() {
    // Remove obstacles that are too far to the left
    obstacles = obstacles.filter(obstacle => {
        const position = parseInt(obstacle.style.left);
        if (position < -obstacle.offsetWidth) {
            obstacle.remove(); // Remove from the DOM
            return false; // Do not keep this object in the active array
        }
        return true; // Keep this object in the active array
    });

    // Similarly for enemies
    enemies = enemies.filter(enemy => {
        const position = parseInt(enemy.style.left);
        if (position < -enemy.offsetWidth) {
            enemy.remove(); // Remove from the DOM
            return false; // Do not keep this object in the active array
        }
        return true; // Keep this object in the active array
    });
}

            function moveElements() {
                moveArray(obstacles, 2, 15);
                moveArray(enemies, 1, 30);
                moveArray(coins, 2, 0);
                moveArray(powerUps, 2, 0, true);
                moveArray(platforms, 1, 0);
                moveFlyingEnemies();
                moveSniperEnemies();
                moveLaserEnemies();
                moveReflectiveEnemies();
                moveSplitterEnemies();
                moveChargingEnemies();
                moveStealthEnemies();
                moveVirusDrones();
                moveBullets();
                moveNewEnemies();
                moveBoostDrainer()
            }

// Spawn a Laser Enemy (like a sniper — fixed x, y)
function spawnLaserEnemy() {
    const leftPos = gameScrollPosition + gameContainer.offsetWidth;
    const laserEnemy = createElement('laser-enemy', enemies, leftPos);
    laserEnemy.style.bottom = '300px';
    laserEnemy.style.width = '30px';
    laserEnemy.style.height = '30px';
    laserEnemy.style.backgroundColor = 'purple';
    laserEnemy.dataset.laserState = 'warning';
    laserEnemy.dataset.lastDamageTime = '0';
    laserEnemy._warningLine = null;
    laserEnemy._laserBeam = null;
    // createElement already does append and enemies.push
}

// Call every frame in moveEnemies or gameLoop
function moveLaserEnemies() {
    enemies.forEach(enemy => {
        if (!enemy.classList.contains('laser-enemy')) return;

        if (enemy.dataset.laserState === 'warning') {
            if (!enemy._warningLine) {
                createWarningLine(enemy);
                setTimeout(() => {
                    enemy.dataset.laserState = 'active';
                    if (enemy._warningLine) {
                        enemy._warningLine.remove();
                        enemy._warningLine = null;
                    }
                    if (enemy._warningLineUpdateInterval) {
                        clearInterval(enemy._warningLineUpdateInterval);
                        enemy._warningLineUpdateInterval = null;
                    }
                    activateLaserBeam(enemy);
                }, 1000);
            }
            // ⚠️ WARNING LINE DOES NOT DAMAGE PLAYER - NO COLLISION CHECK!
        } else if (enemy.dataset.laserState === 'active') {
            const lastDamageTime = parseInt(enemy.dataset.lastDamageTime) || 0;
            const now = Date.now();

            if (enemy._laserBeam && checkCollision(enemy._laserBeam, player)) {
                if (now - lastDamageTime > 1000) { // damage cooldown 1s
                    reduceLives();
                    enemy.dataset.lastDamageTime = now.toString();
                }
            }
        }
    });
}

 
            function spawnObstacle() {
                const obstacle = createElement('obstacle', obstacles, gameScrollPosition + gameContainer.offsetWidth);
                obstacle.style.bottom = '0px';
            }
 
            function spawnEnemy() {
                const baseEnemy = createElement('enemy', enemies, gameScrollPosition + gameContainer.offsetWidth);
                baseEnemy.style.bottom = '0px';
 
                const chance = Math.random();
                if (chance < 0.3) {
                    spawnTeleporterEnemy();
                } else if (chance < 0.7) {
                    spawnVelocityEnemy();
                } else if (chance < 0.9) {
                    spawnStickyEnemy();
                }
            }

function moveVirusDrones() {
    viruses.forEach((virus, vIndex) => {
        if (!virus.infectedCount) virus.infectedCount = 0; // init counter

        // Pick target enemy for infection
        if (!virus.targetEnemy || !enemies.includes(virus.targetEnemy)) {
            virus.targetEnemy = null;
            if (enemies.length > 0) {
                virus.targetEnemy = enemies[Math.floor(Math.random() * enemies.length)];
            } else {
                // No target, fly left and clean up if off-screen
                virus.style.left = (parseInt(virus.style.left) - parseInt(virus.dataset.speed)) + 'px';
                if(parseInt(virus.style.left) < gameScrollPosition - virus.offsetWidth) {
                    virus.remove();
                    viruses.splice(vIndex, 1);
                    virusDroneHits = 0;
                }
                return;
            }
        }

        const target = virus.targetEnemy;

        const virusPosX = parseFloat(virus.style.left) + virus.offsetWidth / 2;
        const virusPosY = parseFloat(virus.style.bottom);
        const enemyPosX = parseFloat(target.style.left) + target.offsetWidth / 2;
        const enemyPosY = parseFloat(target.style.bottom);

        const speedH = parseFloat(virus.dataset.speed) || 5;
        const speedV = 10;

        // Horizontal move gently towards target
        if (Math.abs(virusPosX - enemyPosX) > 5) {
            if (virusPosX < enemyPosX) {
                virus.style.left = (parseFloat(virus.style.left) + speedH) + 'px';
            } else {
                virus.style.left = (parseFloat(virus.style.left) - speedH) + 'px';
            }

            // Use smooth vertical cruising instead of forced fixed height (optional)
            const cruisingHeight = 350;
            let virusPosYCurrent = parseFloat(virus.style.bottom) || cruisingHeight;
            if (virusPosYCurrent < cruisingHeight) {
                virus.style.bottom = (virusPosYCurrent + speedV) + 'px';
            } else if (virusPosYCurrent > cruisingHeight) {
                virus.style.bottom = (virusPosYCurrent - speedV) + 'px';
            } else {
                virus.style.bottom = cruisingHeight + 'px';
            }
        } else {
            // Move vertically down inside enemy for infection smoothly
            const targetInsideY = enemyPosY + target.offsetHeight / 2;
            if (virusPosY > targetInsideY + 2) {
                // Smooth downward movement clamped to not go below targetInsideY + 2 
                let newBottom = virusPosY - speedV;
                if (newBottom < targetInsideY + 2) {
                    newBottom = targetInsideY + 2;
                }
                virus.style.bottom = newBottom + 'px';
            } else {
                infectEnemy(target);

                virus.infectedCount++; // Increment infection count
                virus.targetEnemy = null; // Reset target

                if (virus.infectedCount >= 3) {
                    // Destroy virus drone after infecting 3 enemies
                    virus.remove();
                    viruses.splice(vIndex, 1);
                    virusDroneHits = 0;
                }
            }
        }

        // Check bullets hitting virus drone - keep your existing logic here as needed
        bullets.forEach((bulletObj, bIndex) => {
            const bullet = bulletObj.element;
            if (checkCollision(virus, bullet)) {
                bullet.remove();
                bullets.splice(bIndex, 1);

                virusDroneHits++;
                if (virusDroneHits >= 3) {
                    virus.remove();
                    viruses.splice(vIndex, 1);
                    virusDroneHits = 0;
                    enemies.forEach(e => {
                        if (e.classList.contains('infected')) {
                            cureEnemy(e);
                        }
                    });
                }
            }
        });

        // Remove virus drone if off screen left
        if (parseFloat(virus.style.left) < gameScrollPosition - virus.offsetWidth) {
            virus.remove();
            viruses.splice(vIndex, 1);
            virusDroneHits = 0;
        }
    });
}

function createWarningLine(enemy) {
    if (enemy._warningLine) {
        enemy._warningLine.remove();
        enemy._warningLine = null;
    }

    const warning = document.createElement('div');
    warning.classList.add('laser-warning-line');

    const width = 6;

    const enemyLeft = parseInt(enemy.style.left);
    const enemyBottom = parseInt(enemy.style.bottom);
    const enemyHeight = enemy.offsetHeight;
    const left = enemyLeft + enemy.offsetWidth / 2 - width / 2;

    warning.style.position = 'absolute';
    warning.style.left = left + 'px';
    warning.style.bottom = '0px';
    warning.style.width = width + 'px';
    warning.style.height = (enemyBottom + enemyHeight) + 'px';
    warning.style.backgroundColor = 'yellow';
    warning.style.opacity = '0.7';
    warning.style.zIndex = '9';

    gameWorld.appendChild(warning);
    enemy._warningLine = warning;

    if (enemy._warningLineUpdateInterval) clearInterval(enemy._warningLineUpdateInterval);
    enemy._warningLineUpdateInterval = setInterval(() => {
        if (!enemy._warningLine) {
            clearInterval(enemy._warningLineUpdateInterval);
            enemy._warningLineUpdateInterval = null;
            return;
        }
        const curLeft = parseInt(enemy.style.left);
        const curBottom = parseInt(enemy.style.bottom);
        const leftPos = curLeft + enemy.offsetWidth / 2 - width / 2;
        enemy._warningLine.style.left = leftPos + 'px';
        enemy._warningLine.style.height = (curBottom + enemy.offsetHeight) + 'px';
    }, 16);
}

function activateLaserBeam(enemy) {
    if (enemy._warningLine) {
        enemy._warningLine.remove();
        enemy._warningLine = null;
    }
    if (enemy._warningLineUpdateInterval) {
        clearInterval(enemy._warningLineUpdateInterval);
        enemy._warningLineUpdateInterval = null;
    }
    if (enemy._laserBeam) {
        enemy._laserBeam.remove();
        enemy._laserBeam = null;
    }

    const laser = document.createElement('div');
    laser.classList.add('laser-beam');

    const laserWidth = 8;
    const enemyLeft = parseInt(enemy.style.left);
    const enemyBottom = parseInt(enemy.style.bottom);
    const enemyHeight = enemy.offsetHeight;
    const left = enemyLeft + enemy.offsetWidth / 2 - laserWidth / 2;

    laser.style.position = 'absolute';
    laser.style.left = left + 'px';
    laser.style.bottom = '0px';
    laser.style.width = laserWidth + 'px';
    laser.style.height = (enemyBottom + enemyHeight) + 'px';
    laser.style.backgroundColor = 'red';
    laser.style.opacity = '0.9';
    laser.style.zIndex = '10';

    gameWorld.appendChild(laser);
    enemy._laserBeam = laser;

    enemy._laserBeamUpdateInterval = setInterval(() => {
        if (!enemy._laserBeam) {
            clearInterval(enemy._laserBeamUpdateInterval);
            enemy._laserBeamUpdateInterval = null;
            return;
        }
        const curLeft = parseInt(enemy.style.left);
        const curBottom = parseInt(enemy.style.bottom);
        const leftPos = curLeft + enemy.offsetWidth / 2 - laserWidth / 2;

        enemy._laserBeam.style.left = leftPos + 'px';
        enemy._laserBeam.style.height = (curBottom + enemy.offsetHeight) + 'px';
    }, 16);

    setTimeout(() => {
        if (enemy._laserBeam) {
            enemy._laserBeam.remove();
            enemy._laserBeam = null;
        }
        clearInterval(enemy._laserBeamUpdateInterval);
        enemy._laserBeamUpdateInterval = null;

        enemy.dataset.laserState = 'cooldown';

        setTimeout(() => {
            enemy.dataset.laserState = 'warning';
        }, 3000);
    }, 2000);
}

// Infect Enemy function
// Infect Enemy function - updated for multiple shield hits and faster speed
function infectEnemy(enemy) {
    if (enemy.classList.contains('infected')) return; // Already infected
    enemy.classList.add('infected', 'shielded');

    enemy.dataset.health = '1';          // 1 health after shield
    enemy.dataset.shieldHitsLeft = '2';  // 2 shield hits before health

    // Store or retrieve base speed
    let baseSpeed = parseInt(enemy.dataset.baseSpeed) || 1;
    if (!enemy.dataset.baseSpeed) {
        baseSpeed = parseInt(enemy.dataset.speed) || 1;
        enemy.dataset.baseSpeed = baseSpeed.toString();
    }
    enemy.dataset.speed = (baseSpeed * 3).toString(); // Speed is tripled

    enemy.dataset.powerful = 'true';

    // Visual effects
    enemy.style.opacity = '0.8';
    enemy.style.filter = 'drop-shadow(0 0 5px lime)';
}

// Handle bullet collision with shielded enemy - place this inside your bullet collision code
function handleBulletCollisionWithInfectedEnemy(enemy, bulletIndex) {
    if (enemy.classList.contains('infected') && enemy.classList.contains('shielded')) {
        let shieldHitsLeft = parseInt(enemy.dataset.shieldHitsLeft) || 0;
        shieldHitsLeft--;

        // Shield hit logic to decrement shield hits
        if (shieldHitsLeft <= 0) {
            // Shield broken, now damage health
            enemy.dataset.shieldHitsLeft = '0';
            // Decrement health by 1 on each bullet after shield is down
            let health = parseInt(enemy.dataset.health) || 2; // default infected health 2
            health--;

            if (health <= 0) {
                // Enemy dies
                enemy.remove();
                enemies = enemies.filter(e => e !== enemy);
            } else {
                enemy.dataset.health = health.toString();
                // Maybe flash enemy to indicate hit
                enemy.style.opacity = '0.5';
                setTimeout(() => {
                    if (enemy) enemy.style.opacity = '0.8';
                }, 150);
            }
        } else {
            // Shield still active
            enemy.dataset.shieldHitsLeft = shieldHitsLeft.toString();
            // Flash on shield hit
            enemy.style.opacity = '0.5';
            setTimeout(() => {
                if (enemy) enemy.style.opacity = '0.8';
            }, 150);
        }

        // Remove the bullet after hit
        bullets[bulletIndex].element.remove();
        bullets.splice(bulletIndex, 1);

        return true;
    }
    return false;
}

// Cure enemy restores normal speed and removes shield
function cureEnemy(enemy) {
    enemy.classList.remove('infected', 'shielded');
    enemy.style.pointerEvents = 'auto';
    enemy.style.opacity = '1';
    enemy.style.filter = 'none';

    // Reset speed to baseSpeed or default 1
    enemy.dataset.speed = enemy.dataset.baseSpeed || '1';
    enemy.dataset.shieldHitsLeft = '0';
    enemy.dataset.health = '1'; // normal enemies 1 HP
    enemy.dataset.powerful = 'false';

    // You may reset other enemy attributes here if applied.
}


// Enhance Enemy stats (called on infection)
function enhanceEnemy(enemy) {
    // Example: double speed and fire rate if enemy shoots
    const speed = parseInt(enemy.dataset.speed) || 1;
    enemy.dataset.speed = speed * 2;

    // If enemy shoots bullets (like sniper), reduce cooldown or increase damage
    if(enemy.dataset.lastShotTime) {
        enemy.dataset.shootCooldown = (parseInt(enemy.dataset.shootCooldown) || 3000) / 2; 
    }

    // You can add more attribute enhancements here, e.g. health, damage, size
}

// Normalize Enemy back to default (called on cure)
function normalizeEnemy(enemy) {
    const speed = parseInt(enemy.dataset.speed) || 2;
    enemy.dataset.speed = speed / 2;

    if(enemy.dataset.lastShotTime) {
        enemy.dataset.shootCooldown = (parseInt(enemy.dataset.shootCooldown) || 1500) * 2;
    }

    // Reset any other attributes to normal here
}
 
            function spawnPowerUp() {
                const powerUpTypes = allPowerUpTypes;
                const type = powerUpTypes[Math.floor(Math.random() * powerUpTypes.length)];
                const powerUp = createElement('power-up', powerUps, gameScrollPosition + gameContainer.offsetWidth);
                powerUp.setAttribute('data-type', type);
                powerUp.style.backgroundColor = getPowerUpColor(type);
                powerUp.style.bottom = Math.floor(Math.random() * 100) + 'px';
            }
 
            function spawnCoin() {
                const coin = createElement('coin', coins, gameScrollPosition + gameContainer.offsetWidth);
                coin.style.bottom = Math.floor(Math.random() * 50 + 50) + 'px';
            }
 
function getPowerUpColor(type) {
    switch (type) {
        case 'super-speed': return 'lime';
        case 'invincibility': return 'gold';
        case 'teleportation': return 'violet';
        case 'reflective-shield': return 'aqua';
        case 'double-shot': return 'red';
        case 'extra-life': return 'lightgreen';
        case 'score-boost': return 'coral';
        case 'mega-jump': return 'fuchsia';
        case 'energy-blast': return 'limegreen'; // Specify colors for valid powers
        case 'light-speed': return 'white'; // Define colors for light-speed
        case 'blazing-trail': return 'gold'; // Specify for blazing-trail
        case 'sonic-wave': return 'blueviolet'; // Specify for sonic-wave
        case 'armor': return 'lightgrey'; // Define color for armor
        case 'telekinetic': return 'silver'; // Define color for telekinetic
        case 'camouflage': return 'darkgreen'; // Define color for camouflage
        case 'dimension-shift': return 'black'; // Define color for dimension-shift
        case 'energy-drain': return 'red'; // Define color for energy-drain
        case 'mind-control': return 'purple'; // Define color for mind-control
        case 'hologram': return 'pink'; // Define color for hologram
        case 'fire': return 'red'; // Define color for energy-drain
        case 'ice': return 'darkblue'; // Define color for energy-drain
        case 'hypno': return 'pink'; // Define color for energy-drain
        default: return 'white'; // Fallback for any unknown type
    }
}
 
            function spawnPlatform() {
                const platform = createElement('platform', platforms, gameScrollPosition + gameContainer.offsetWidth);
                platform.style.bottom = Math.floor(Math.random() * 200 + 100) + 'px';
            }
 
            function spawnBossDoor() {
                const bossDoor = createElement('boss-door', bossDoors, gameScrollPosition + gameContainer.offsetWidth + 200);
                bossDoor.style.bottom = '0px';
            }
 
function createElement(className, array, leftPosition, type = '') {
    const element = document.createElement('div');
    element.classList.add(className);
    if (type) element.setAttribute('data-type', type);
    element.style.left = leftPosition + 'px';
    gameWorld.appendChild(element);
    array.push(element);
    return element;
}
 
function moveArray(array, speed, scoreValue, isPowerUp = false) {
    array.forEach((el, index) => {
        el.style.left = (parseInt(el.style.left) - speed) + 'px';
        if (parseInt(el.style.left) < gameScrollPosition - el.offsetWidth) {
            removeElement(el, array, index, 0);
        } else if (checkCollision(player, el)) {
            handleCollision(el, array, index, scoreValue, isPowerUp);
        }
    });
}
 
            function removeElement(el, array, index, scoreValue) {
                el.remove();
                array.splice(index, 1);
                if (scoreValue) {
                    score += scoreValue;
                    updateDisplay();
                }
            }
 
function handleCollision(el, array, index, scoreValue, isPowerUp = false) {
    if (el.classList.contains('coin')) {
        score += 5; // Increase score for collecting a coin
        updateDisplay(); // Update the display if needed
    } 
    
    // Handle power-ups
    else if (isPowerUp) {
        applyPowerUp(el); // Apply power-up effects
    }
    
    // Handle boss door interactions
    else if (el.classList.contains('boss-door')) {
        if (score >= level * bossScoreThreshold) {
            interactMessage.textContent = "Press 'E' to enter boss door."; // Prompt for interaction
            interactMessage.style.display = checkCollision(player, el) ? 'block' : 'none'; // Show message if player is near
            if (checkCollision(player, el) && playerPositionX >= parseInt(el.style.left)) {
                openBossHallway(); // Proceed to boss hallway
            }
        }
    }

    // Handle enemy and obstacle collisions
    else if (el.classList.contains('enemy') || el.classList.contains('obstacle')) {
        reduceLives(); // Reduce player's lives on collision with enemies or obstacles
    }

    // Remove the collided element from the game world
    removeElement(el, array, index, scoreValue);
}
 
            function applyPowerUp(el) {
                if (currentPowerUp || currentPowerUp === 'boss-power-up') return;
 
                const type = el.getAttribute('data-type');
                if (type === 'boss-power-up') {
                    grantBossPowerUp();
                } else {
                    currentPowerUp = type;
                    let duration = 10;
                    activatePowerUp(type);
                    powerUpTimer = duration;
 
                    const powerUpInterval = setInterval(() => {
                        powerUpTimer--;
                        if (powerUpTimer <= 0) {
                            clearInterval(powerUpInterval);
                            resetPowerUp();
                        }
                        updateDisplay();
                    }, 1000);
                }
 
                displayPowerUpMessage(type);
            }

  sandboxClose.addEventListener('click', () => {
    sandbox.style.display = 'none';
  });

  function activateTab(id) {
    tabs.forEach(tab => {
      const active = tab.id === id;
      tab.classList.toggle('active', active);
      tab.setAttribute('aria-selected', active ? 'true' : 'false');
      tab.tabIndex = active ? 0 : -1;
    });
    tabContents.forEach(content => {
      content.setAttribute('aria-hidden', content.getAttribute('aria-labelledby') !== id);
    });
  }

  // Setup tab clicks and keyboard navigation
  tabs.forEach((tab, idx) => {
    tab.addEventListener('click', () => activateTab(tab.id));
    tab.addEventListener('keydown', e => {
      if(e.key === 'ArrowRight' || e.key === 'ArrowLeft') {
        e.preventDefault();
        let nextIdx = (idx + (e.key === 'ArrowRight' ? 1 : tabs.length -1)) % tabs.length;
        activateTab(tabs[nextIdx].id);
        tabs[nextIdx].focus();
      }
    });
  });
  activateTab(tabs[0].id);

  function populateElements(filter = '') {
    elementsList.innerHTML = '';
    const filtered = exampleElements.filter(c => c.toLowerCase().includes(filter.toLowerCase()));
    if(filtered.length === 0){
      elementsList.textContent = "No matching elements.";
      return;
    }
    filtered.forEach(cls => {
      const div = document.createElement('div');
      div.textContent = cls;
      div.tabIndex = 0;
      div.setAttribute('role', 'option');
      div.addEventListener('click', () => selectClass(cls, div));
      div.addEventListener('keydown', e => {
        if (e.key === 'Enter' || e.key === ' ') {
          selectClass(cls, div);
          spawnButton.focus();
        }
      });
      elementsList.appendChild(div);
    });
  }
  populateElements();

  elementsSearch.addEventListener('input', () => populateElements(elementsSearch.value.trim()));


function activatePowerUp(type) {
    switch (type) {
        case 'super-speed':
            player.style.backgroundColor = 'lime';
            playerMaxSpeed += 8; // Increase speed
            break;
        case 'invincibility':
            player.style.backgroundColor = 'gold';
            PlayerInvincibility(); // Implement this function for invincibility
            break;
        case 'teleportation':
            teleportPlayer(); // Implement this function for teleportation
            break;
        case 'reflective-shield':
            activateReflectiveShield(); // Implement the reflective shield functionality
            break;
        case 'double-shot':
            enableDoubleShot(); // Implement functionality for double shot
            break;
        case 'extra-life':
            gainExtraLife(); // Implement functionality for gaining an extra life
            break;
        case 'score-boost':
            boostScore(); // Implement functionality for score boost
            break;
        case 'mega-jump':
            activateMegaJump(); // Implement functionality for mega jump
            break;
        case 'energy-blast':
            activateEnergyBlast(); // Implement functionality for energy blast
            break;
        case 'light-speed':
            player.style.backgroundColor = 'lime';
            playerMaxSpeed += 10; // Increase speed
            break;
        case 'blazing-trail':
            activateBlazingTrail(); // Implement functionality for blazing trail
            break;
        case 'sonic-wave':
            activateSonicWave(); // Implement functionality for sonic wave
            break;
        case 'armor':
            activateArmor(); // Implement functionality for armor
            break;
        case 'telekinetic':
            activateTelekinetic(); // Implement functionality for telekinetic
            break;
        case 'camouflage':
            activateCamouflage(); // Implement functionality for camouflage
            break;
        case 'dimension-shift':
            activateDimensionShift(); // Implement functionality for dimension shift
            break;
        case 'energy-drain':
            activateEnergyDrain(); // Implement functionality for energy drain
            break;
        case 'mind-control':
            activateMindControl(); // Implement functionality for mind control
            break;
        case 'hologram':
            activateHologram(); // Implement functionality for hologram
            break;
        case 'fire':
            shootFire();
            break;
        case 'ice':
            shootIce();
            break;
        case 'hypno':
            shootHypno();
            break;
        default:
            // Consider logging or managing invalid power-up requests
            console.log(`Unknown power-up type: ${type}`);
            break;
    }
}

function handlePlayerEnemyCollision() {
    enemies.forEach((enemy, index) => {
        // Check collision with the player
        if (checkCollision(player, enemy)) {
            if (enemy.classList.contains('frozen')) {
                // If frozen, destroy the enemy
                enemy.remove(); // Remove frozen enemy
                enemies.splice(index, 1); // Remove from the enemies array
                updateDisplay(); // Update any relevant game display elements if needed
            } else {
                // Normal behavior for non-frozen enemies
                reduceLives(); // This would reduce lives for non-frozen collisions
            }
        }
    });
}
 


function allowPlayerMovement(e) {
    switch (e.key) {
        case 'ArrowLeft':
            playerPositionX -= playerMaxSpeed; // Move left
            player.style.left = playerPositionX + 'px';
            break;
        case 'ArrowRight':
            playerPositionX += playerMaxSpeed; // Move right
            player.style.left = playerPositionX + 'px';
            break;
        case ' ': // Space to shoot
            shootBullet(currentDirection); // Allow shooting during freeze
            break;
    }
}
 
function resetPowerUp() {
    currentPowerUp = null; // Also can now be re-assigned
    player.style.backgroundColor = '#4CAF50';
    if (upgradesEquipped.includes('speedBoost')) {
        playerMaxSpeed = 7; // Set the boosted speed or any other value you want
    } else {
        playerMaxSpeed = 5; // Default speed if the upgrade is not equipped
    }
    player.style.opacity = '1';
    if (upgradesEquipped.includes('doubleJump')) {
        isDoubleJumpEnabled = true; // Enable double jump if upgrade is equipped
    } else {
        isDoubleJumpEnabled = false; // Disable double jump otherwise
    }
    clearTimeout(timeSlowTimeout);
    resetGravity();
}
 
            function displayPowerUpMessage(type) {
                powerUpMessage.textContent = `You obtained ${type.replace(/-/g, ' ')}!`;
                powerUpMessage.style.display = 'block';
                setTimeout(() => powerUpMessage.style.display = 'none', 2000);
            }
 
            function grantBossPowerUp() {
                bossPowerObtained = true;
                powerUpMessage.textContent = "Boss Power-Up Obtained!";
                powerUpMessage.style.display = 'block';
                setTimeout(() => powerUpMessage.style.display = 'none', 2000);
            }

function PlayerInvincibility() {
    // Check for collision with enemies
    enemies.forEach((enemy) => {
        if (checkCollision(player, enemy)) {
            if (!isInvincible) { // Only reduce lives if not invincible
                if (lives > 1) {
                    lives--; // Deduct a life when colliding with an enemy
                    updateDisplay(); // Update the displayed lives
                }
            }
        }
    });

    // Immediately reset lives to 3 if they drop below that
    if (lives < 3) {
        lives = 3; // Reset lives to 3 instantly
        updateDisplay(); // Update display to show 3 lives
    }
}
 
            function usePowerUp() {
                if (!currentPowerUp) return;
                switch (currentPowerUp) {
                    case 'ice':
                        shootIce();
                        break;
                    case 'sonic-wave':
                        activateSonicWave();
                        break;
                    case 'fire':
                        shootFire();
                        break;
                    case 'teleportation':
                        teleportPlayer();
                        break;
                    case 'levitate':
                        useLevitate();
                        break;
                    case 'hypno':
                        shootHypno();
                        break;
                    case 'double-shot':
                        shootDouble();
                        break;
                    default:
                        break;
                }
            }
 
function shootIce() {
    const iceBullet = createBullet(currentDirection); // Create the ice bullet
    iceBullet.style.backgroundColor = 'blue'; // Set bullet color to blue
    gameWorld.appendChild(iceBullet);

    const iceBulletObj = { element: iceBullet, direction: currentDirection };
    
    animateBullet(iceBulletObj, 5, (target) => {
        // Check for collision with enemies
        if (target.classList.contains('obstacles')) {
            target.classList.add('frozen'); // Mark the enemy as frozen
            target.style.backgroundColor = '#00f'; // Change color to blue
            target.style.opacity = '0.5'; // Reduce visibility
            target.dataset.isFrozen = 'true'; // Mark enemy as frozen

            // Set a timer to unfreeze
            setTimeout(() => {
                if (target.dataset.isFrozen === 'true') {
                    target.classList.remove('frozen'); // Remove frozen status
                    target.style.backgroundColor = ''; // Reset color
                    target.style.opacity = '1'; // Reset visibility
                    delete target.dataset.isFrozen; // Clear the frozen marker
                }
            }, 5000); // 5 seconds to unfreeze
        }
    });
}
 
            function shootFire() {
                const fireBullet = createBullet(currentDirection);
                fireBullet.style.backgroundColor = 'red';
                gameWorld.appendChild(fireBullet);
 
                const fireBulletObj = { element: fireBullet, direction: currentDirection };
                animateBullet(fireBulletObj, 5, (target) => {
                    if (target.classList.contains('obstacle')) {
                        target.style.transition = 'opacity 0.5s';
                        target.style.opacity = '0';
                        setTimeout(() => target.remove(), 500);
                    }
                });
            }
 
            function useLevitate() {
                player.style.transform = 'translateY(-20px)';
                const levitateUp = setTimeout(() => {
                    player.style.transform = 'translateY(0)';
                    clearTimeout(levitateUp);
                }, 1000);
            }
 
            function enableDoubleShot() {
            }
 
            function createBullet(direction = 1) {
                const bullet = document.createElement('div');
                bullet.classList.add('bullet');
                bullet.style.backgroundColor = '#FFD700';
                bullet.style.left = (playerPositionX + player.offsetWidth / 2 - 5) + 'px';
                bullet.style.bottom = (playerPositionY + player.offsetHeight / 2) + 'px';
                return bullet;
            }
 
            function shootHypno() {
                const hypnoBullet = createBullet(currentDirection);
                hypnoBullet.style.backgroundColor = 'pink';
                gameWorld.appendChild(hypnoBullet);
 
                const hypnoBulletObj = { element: hypnoBullet, direction: currentDirection };
                animateBullet(hypnoBulletObj, 5, (target) => {
                    if (target.classList.contains('enemy') && !target.classList.contains('hypnotized')) {
                        target.classList.add('hypnotized');
                        target.style.backgroundColor = 'pink';
                        hypnotizeEnemy(target);
                    }
                });
            }
 
            function shootDouble() {
                const bullet1 = createBullet(currentDirection);
                const bullet2 = createBullet(currentDirection);
                bullets.push({ element: bullet1, direction: currentDirection });
                bullets.push({ element: bullet2, direction: currentDirection });
                gameWorld.appendChild(bullet1);
                gameWorld.appendChild(bullet2);
            }
 
function hypnotizeEnemy(enemy) {
    let destroyCount = 0; // Count how many enemies are destroyed by this hypnotized enemy
    const moveInterval = setInterval(() => {
        let nearestEnemy = findNearestEnemyTo(enemy);
        if (!nearestEnemy) {
            enemy.remove(); // If no nearest enemy, remove this one
            clearInterval(moveInterval); // Stop interval
            return;
        }

        let ex = parseInt(enemy.style.left);
        let ey = parseInt(enemy.style.bottom);
        let nex = parseInt(nearestEnemy.style.left);
        let ney = parseInt(nearestEnemy.style.bottom);

        let dx = nex - ex;
        let dy = ney - ey;
        let distance = Math.sqrt(dx * dx + dy * dy);

        if (distance < 5) {
            destroyCount++;
            createBurst(nex, ney); // Create an effect when destroying enemies
            nearestEnemy.remove();
            enemies = enemies.filter(e => e !== nearestEnemy); // Clean up enemies

            if (destroyCount >= 3) { // Define a limit for multiple enemies hypnotized
                enemy.remove(); // Remove this hypnotized enemy after doing its effects
                clearInterval(moveInterval); // Stop interval
            }
        } else {
            let angle = Math.atan2(dy, dx); // Calculate angle to move towards the nearest enemy
            enemy.style.left = (ex + Math.cos(angle) * 2) + 'px'; // Move slightly towards
            enemy.style.bottom = (ey + Math.sin(angle) * 2) + 'px';
        }
    }, 1000 / 60); // Run update at 60 FPS
}
 
            function findNearestEnemyTo(sourceEnemy) {
                let minDistance = Infinity;
                let closestEnemy = null;
 
                enemies.forEach(enemy => {
                    if (enemy !== sourceEnemy) {
                        let distance = calculateDistance(sourceEnemy, enemy);
                        if (distance < minDistance) {
                            minDistance = distance;
                            closestEnemy = enemy;
                        }
                    }
                });
 
                return closestEnemy;
            }
 
            function calculateDistance(el1, el2) {
                let el1Rect = el1.getBoundingClientRect();
                let el2Rect = el2.getBoundingClientRect();
                let dx = (el1Rect.left + el1Rect.width / 2) - (el2Rect.left + el2Rect.width / 2);
                let dy = (el1Rect.top + el1Rect.height / 2) - (el2Rect.top + el2Rect.height / 2);
                return Math.sqrt(dx * dx + dy * dy);
            }
 
            function enableDoubleJump(enable = true) {
                isDoubleJumpEnabled = enable;
            }

function moveBoostDrainer() {
    if (!boostDrainer) return;

    // Move left slowly
    let currentX = parseInt(boostDrainer.style.left);
    boostDrainer.style.left = (currentX - 0.5) + 'px'; // Adjust speed here

    // Remove if off-screen left
    if (currentX < gameScrollPosition - boostDrainer.offsetWidth) {
        removeBoostDrainer();
        return;
    }

    // Update chain line connecting player and boost drainer
    if (boostDrainerChain) {
        updateChainLine(boostDrainer, boostDrainerChain, player);
    }
}
 
function teleportPlayer() {
    if (isTeleporting) return; // Prevent multiple teleports in quick succession

    // Set cooldown
    isTeleporting = true; // Set to true to indicate teleport in progress

    // Calculate teleportation distance
    const teleportDistance = 145; // Increase this to a larger value for more noticeable teleport

    // Determine player current direction
    let teleportOffset = teleportDistance * currentDirection; // Use currentDirection to allow for left (-1) and right (1) teleporting

    // Update player position
    playerPositionX += teleportOffset; // Move the player in the direction they are facing
    playerPositionX = Math.max(0, Math.min(gameWorld.offsetWidth - player.offsetWidth, playerPositionX)); // Ensure player stays in bounds

    // Log positions for debugging
    console.log('Teleporting to position:', playerPositionX);

    player.style.left = playerPositionX + 'px'; // Update player's position on screen

    // Set a timeout for the cooldown
    setTimeout(() => {
        isTeleporting = false; // Reset teleport ability after cooldown
    }, 1000); // 1000 milliseconds = 1 second cooldown
}
 
            function toggleGravity() {
                const originalGravity = gravity;
                gravity = -gravity;
                setTimeout(() => {
                    gravity = originalGravity;
                }, 5000);
            }
 
function resetGravity() {
    gravity = Math.abs(gravity); // Needs to ensure gravity is declared with let or var
}
 
            function freezeEnemies() {
                enemies.forEach(enemy => {
                    enemy.style.transition = 'opacity 1s';
                    enemy.style.opacity = '0.2';
                    enemy.classList.add('frozen-enemy');
                });
                setTimeout(() => {
                    enemies.forEach(enemy => {
                        enemy.style.opacity = '1';
                        enemy.classList.remove('frozen-enemy');
                    });
                }, 5000);
            }
 
            function createClone() {
                const clone = createElement('player', [], playerPositionX + 50);
                clone.style.bottom = playerPositionY + 'px';
                clone.style.backgroundColor = '#00F';
                clone.style.border = '2px dashed #FFF';
                gameWorld.appendChild(clone);
                setTimeout(() => clone.remove(), 5000);
            }
 
            function triggerShockwave() {
                const shockwaveRadius = 10000;
                enemies.forEach(enemy => {
                    const dist = calculateDistance(player, enemy);
                    if (dist < shockwaveRadius) {
                        createBurst(parseInt(enemy.style.left), parseInt(enemy.style.bottom));
                        enemy.remove();
                    }
                });
            }
 
            function absorbEnergy() {
                score += 50;
                updateDisplay();
            }
 
            function shrinkPlayer() {
                player.style.transform = 'scale(0.5)';
                setTimeout(() => player.style.transform = 'scale(1)', 5000);
            }
 
            function growPlayer() {
                player.style.transform = 'scale(1.5)';
                setTimeout(() => player.style.transform = 'scale(1)', 5000);
            }
 
            function healPlayer() {
                if (lives < 5) {
                    lives++;
                    updateDisplay();
                }
            }
 
            function activateShield() {
                player.style.border = '3px solid purple';
                player.style.opacity = '0.6';
                lives = Math.min(lives + 1, 7);
                updateDisplay();
            }
 
            function gainExtraLife() {
                lives = Math.min(lives + 1, 7);
                updateDisplay();
            }

function gainExtraLife2() {
    lives = Math.min(lives + 3, 6); // Increase lives by 3, ensuring it doesn't exceed 5
    updateDisplay(); // Update the display to reflect the new number of lives
}

function removeLife() {
    lives = Math.max(lives - 3, 3); // Decrease lives by 3, ensuring it doesn't fall below 3
    updateDisplay(); // Update the display to reflect the new number of lives
}
 
            function boostScore() {
                score += 100;
                updateDisplay();
            }
 
let consecutiveJumps = 0; // Initialize a variable to track consecutive jumps
const maxJumpCount = 3; // Maximum number of normal jumps before triggering a mega jump
const megaJumpMultiplier = 1.5; // Multiplier for the mega jump

function activateMegaJump() {
    if (consecutiveJumps < maxJumpCount) {
        // Perform a normal jump if within the max jump limit
        playerVelocityY = playerJumpStrength; // Regular jump value
        consecutiveJumps++; // Increment consecutive jumps
    } else {
        // Trigger a mega jump if max jump limit has been reached
        playerVelocityY = playerJumpStrength * megaJumpMultiplier; // Apply mega jump
        consecutiveJumps = 0; // Reset consecutive jumps to 0 after a mega jump
    }
    isJumping = true; // Set the jumping status to true
}

// Call this function whenever the player lands to reset the consecutive jumps count
function checkLanding() {
    if (playerPositionY <= 0) { // Assuming ground level is at y = 0
        consecutiveJumps = 0; // Reset consecutive jumps when landing
    }
}
 
            function activateReflectiveShield() {
                player.style.border = '3px dashed cyan';
                const reflectInterval = setInterval(() => {
                    bullets.forEach((bullet, index) => {
                        if (checkCollision(player, bullet.element)) {
                            bullet.direction *= -1;
                        }
                    });
                }, 1000 / 60);
 
                setTimeout(() => {
                    player.style.border = '';
                    clearInterval(reflectInterval);
                }, 5000);
            }
 
            function activateRegeneration() {
                const regenerationInterval = setInterval(() => {
                    if (lives < 5) lives++;
                    updateDisplay();
                    if (!currentPowerUp || currentPowerUp !== 'regeneration') {
                        clearInterval(regenerationInterval);
                    }
                }, 2000);
            }
 
            function activateMagnet() {
                const magnetInterval = setInterval(() => {
                    coins.forEach(coin => {
                        const coinX = parseInt(coin.style.left);
                        const coinY = parseInt(coin.style.bottom);
                        const dx = playerPositionX - coinX;
                        const dy = playerPositionY - coinY;
                        if (Math.sqrt(dx * dx + dy * dy) < 100) {
                            coin.style.left = (coinX + dx * 0.1) + 'px';
                            coin.style.bottom = (coinY + dy * 0.1) + 'px';
                        }
                    });
 
                    if (!currentPowerUp || currentPowerUp !== 'magnet') {
                        clearInterval(magnetInterval);
                    }
                }, 1000/ 60);
            }
 
            let timeSlowTimeout;
 
            function slowDownTime() {
                const originalTiming = 1000 / 60;
                clearInterval(gameInterval);
                gameInterval = setInterval(gameLoop, originalTiming * 2);
                timeSlowTimeout = setTimeout(() => {
                    clearInterval(gameInterval);
                    gameInterval = setInterval(gameLoop, originalTiming);
                }, 5000);
            }
 
function activateEnergyBlast() {
    const blastRadius = 100; // Define the radius of the blast
    const burst = document.createElement('div'); // Create a burst element
    burst.classList.add('energy-blast'); // Assign a class for styles
    burst.style.left = (playerPositionX - blastRadius) + 'px'; // Position the burst to the player's location
    burst.style.bottom = (playerPositionY - blastRadius) + 'px'; // Center the burst around the player
    gameWorld.appendChild(burst); // Add the burst to the game world

    // Set a timeout to remove the burst effect after a duration
    setTimeout(() => {
        burst.remove(); // Remove the burst after showing it
    }, 500); // Keep the burst visible for half a second

    // Identify and destroy nearby enemies
    let enemiesToRemove = enemies.filter(enemy => calculateDistance(player, enemy) < blastRadius);
    enemiesToRemove.forEach(enemy => {
        createBurst(parseInt(enemy.style.left), parseInt(enemy.style.bottom)); // Create an explosion effect at enemy's location
        enemy.remove(); // Remove the enemy from the game
        enemies = enemies.filter(e => e !== enemy); // Ensure the enemy is removed from the enemies array
    });

    updateDisplay(); // Update the display to reflect any changes (like score)
}

function initializeBossHealth() {
    bossHealth = level === 3 ? 250 : 100; // Example health values based on level
    updateDisplay();
}
 
function activateBlazingTrail() {
    let trailInterval = setInterval(() => {
        const trail = document.createElement('div');
        trail.className = 'bullet'; // Using the same class for stylistic purposes
        trail.style.left = (playerPositionX + player.offsetWidth / 2) + 'px'; // Position trail based on player's location
        trail.style.bottom = (playerPositionY + player.offsetHeight / 2) + 'px'; // Center the trail on the player
        trail.style.backgroundColor = 'orange'; // Trail color
        gameWorld.appendChild(trail); // Add the trail to the game

        // Check collision with enemies
        enemies.forEach((enemy, enemyIndex) => {
            if (checkCollision(trail, enemy)) {
                // Create burst effect for visual feedback
                const burst = document.createElement('div');
                burst.className = 'burst'; // The CSS class for the burst effect
                burst.style.left = enemy.style.left; // Position it at the enemy's position
                burst.style.bottom = enemy.style.bottom; // Position it at the enemy's position
                gameWorld.appendChild(burst);
                
                // Clean up burst after a short duration
                setTimeout(() => burst.remove(), 500); // Remove burst after 0.5 seconds
                
                // Remove enemy
                enemy.remove(); // Remove the enemy from game
                enemies.splice(enemyIndex, 1); // Remove from enemies array to prevent future collisions
            }
        });

        // Remove the trail after a short duration
        setTimeout(() => trail.remove(), 500); // Remove trail after 0.5 seconds
    }, 100); // The interval for creating the trails

    // Automatically clear the interval after a certain time, e.g., 5 seconds
    setTimeout(() => {
        clearInterval(trailInterval); // Clear the interval for the trail creation
    }, 5000);
}

 
function activateSonicWave() {
    if (waveCooldown) return; // Prevent activation if already on cooldown
    waveCooldown = true; // Set cooldown to prevent further activation

    const wave = document.createElement('div');
    wave.className = 'wave'; // Class for wave styling
    wave.style.left = (playerPositionX - 50) + 'px'; // Center the wave below the player
    wave.style.bottom = (playerPositionY - 50) + 'px'; // Position just below player
    wave.style.backgroundColor = 'cyan'; // Wave color
    wave.style.width = '100px'; // Width of the wave
    wave.style.height = '100px'; // Height of the wave
    wave.style.position = 'absolute'; // Ensure proper positioning
    gameWorld.appendChild(wave); // Add the wave to the game world

    let destroyedBlocks = 0; // Track how many blocks have been destroyed

    // Move the wave forward quickly
    let waveInterval = setInterval(() => {
        wave.style.left = (parseInt(wave.style.left) + 10) + 'px'; // Move wave to the right

        // Check for collision with obstacles
        obstacles.forEach((block, index) => {
            if (checkCollision(wave, block) && destroyedBlocks < 3) { // Destroy only until 3 blocks
                // Create burst effect
                const burst = document.createElement('div'); 
                burst.className = 'burst';
                burst.style.left = block.style.left; 
                burst.style.bottom = block.style.bottom; 
                gameWorld.appendChild(burst);
                
                setTimeout(() => burst.remove(), 500); // Remove burst after half a second
                
                block.remove(); // Remove the obstacle
                obstacles.splice(index, 1); // Remove from the array
                destroyedBlocks++; // Increment the destroyed block count
            }
        });

        // Cleanup if wave goes off screen
        if (parseInt(wave.style.left) > gameWorld.offsetWidth) {
            clearInterval(waveInterval); // Stop moving the wave if it goes off screen
            wave.remove(); // Remove the wave
            resetWave(); // Reset block destruction count
            return; // Exit the function
        }
    }, 50); // Adjust speed of the wave as needed

    // Automatically remove the wave after a brief time
    setTimeout(() => {
        clearInterval(waveInterval); // Ensure the interval is cleared after time is up
        wave.remove(); // Remove the wave
        resetWave(); // Reset properties after the effect finishes
    }, 2000); // Duration of the wave effect (2 seconds)
}

// Reset wave properties for future use
function resetWave() {
    destroyedBlocks = 0; // Reset the number of destroyed blocks for future waves
    waveCooldown = false; // Reset cooldown state
}
 
            function activateArmor() {
                player.style.border = '3px solid steelblue';
                lives = Math.min(lives + 3, 5);
                updateDisplay();
            }
 
function activateTelekinetic() {
    const forceInterval = setInterval(() => {
        enemies.forEach((enemy, index) => {
            const enemyX = parseInt(enemy.style.left) + enemy.offsetWidth / 2; // Get center position
            const enemyY = parseInt(enemy.style.bottom) + enemy.offsetHeight / 2; // Get center position
            const dx = playerPositionX - enemyX;
            const dy = playerPositionY - enemyY;

            // Check if the player is within a certain distance (e.g., 100 pixels)
            if (Math.sqrt(dx * dx + dy * dy) < 100) {
                // Move the enemy upwards slightly
                enemy.style.bottom = (enemyY + 2) + 'px'; // Adjust height as necessary for feel
            } else if (enemyY > 0) { // Only lower it if above 0
                // Bring the enemy back down to ground level smoothly
                enemy.style.bottom = (enemyY - 2) + 'px'; // Adjust to bring back down
                // Stop exactly at the ground level if necessary
                if (parseInt(enemy.style.bottom) < 0) {
                    enemy.style.bottom = '0px'; // Prevent going below 0
                }
            }
        });
    }, 1000 / 60); // Update at 60 FPS

    // Optional: Set a timeout for how long telekinesis lasts
    setTimeout(() => clearInterval(forceInterval), 5000); // Lasts for 5 seconds
}
 
            function activateCamouflage() {
                player.style.opacity = '0.2';
                setTimeout(() => player.style.opacity = '1', 5000);
            }
 
// Array to temporarily hold removed enemies

function activateDimensionShift() {
    // Change the background color to indicate the shift
    gameWorld.style.backgroundColor = 'black';

    // Hide and remove all enemies in the game world
    enemies.forEach((enemy, index) => {
        enemy.style.transition = 'opacity 1s'; // Set transition for fading effect
        enemy.style.opacity = '0'; // Start fading the enemy
        setTimeout(() => {
            enemy.remove(); // Remove from the DOM after fading
            enemies.splice(index, 1); // Remove from the enemies array
        }, 1000); // Match the timeout to the fade-out duration (1 second)
    });

    // Hide and remove all obstacles in the game world
    obstacles.forEach((obstacle, index) => {
        obstacle.style.transition = 'opacity 1s'; // Set transition for fading effect
        obstacle.style.opacity = '0'; // Start fading the obstacle
        setTimeout(() => {
            obstacle.remove(); // Remove from the DOM after fading
            obstacles.splice(index, 1); // Remove from the obstacles array
        }, 1000); // Match the timeout to the fade-out duration (1 second)
    });

    // Reset background color after a period
    setTimeout(() => {
        gameWorld.style.backgroundColor = ''; // Reset the background color after 5 seconds

        // Restore removed enemies
        removedEnemies.forEach(removedEnemy => {
            // Re-create the enemy in the game world
            const newEnemy = createElement(removedEnemy.className, enemies, gameScrollPosition + gameContainer.offsetWidth);
            newEnemy.style.bottom = '0px'; // Reset position
            gameWorld.appendChild(newEnemy); // Append back to game world
        });

        // Clear out the removedEnemies array for future use
        removedEnemies = [];

        // If you have obstacles that should be restored, handle that here as well
        // You may need to keep track of removed obstacles in a similar way if needed
    }, 5000); // Keep the black background for 5 seconds
}
 
            function activateEnergyDrain() {
                const drainInterval = setInterval(() => {
                    if (score > 0) {
                        score -= 1;
                        updateDisplay();
                    }
                }, 100);
 
                setTimeout(() => clearInterval(drainInterval), 5000);
            }
 
function activateMindControl() {
    const hypnotizeRange = 250; // Set hypnotize range in pixels (you can adjust this)

    // Loop through all enemies
    enemies.forEach(enemy => {
        const enemyX = parseInt(enemy.style.left) + (enemy.offsetWidth / 2); // Get the center of the enemy
        const enemyY = parseInt(enemy.style.bottom) + (enemy.offsetHeight / 2); // Get the center of the enemy
        const dx = playerPositionX - enemyX; // Calculate horizontal distance
        const dy = playerPositionY - enemyY; // Calculate vertical distance

        // Check if within the hypnotize range
        const distance = Math.sqrt(dx * dx + dy * dy); // Calculate distance to the player
        if (distance < hypnotizeRange) {
            if (!enemy.classList.contains('hypnotized')) {
                enemy.classList.add('hypnotized'); // Mark enemy as hypnotized
                enemy.style.backgroundColor = 'violet'; // Change color to indicate hypnotization
                
                // Call the function to handle hypnosis effects
                hypnotizeEnemy(enemy);
            }
        }
    });
}
 
function activateHologram() {
    const hologram = document.createElement('div');
    hologram.className = 'hologram'; // Use a hologram class for styling
    hologram.style.position = 'absolute';
    hologram.style.left = `${playerPositionX - 25}px`; // Position the hologram centered relative to player
    hologram.style.bottom = `${playerPositionY}px`; // Vertical alignment with player
    hologram.style.width = '50px'; // Fixed width for better visibility
    hologram.style.height = '50px'; // Fixed height for better visibility
    hologram.style.backgroundColor = 'rgba(0, 0, 255, 0.5)'; // Semi-transparent blue color
    hologram.style.borderRadius = '50%'; // Round shape
    hologram.style.zIndex = '100'; // Ensure the hologram is above other elements
    gameWorld.appendChild(hologram); // Add the hologram to the game world

    // Pulsate effect
    let scale = 5;
    const pulseSpeed = 0.05; // Adjust pulsate speed
    const maxScale = 1.2; // Maximum scale for pulsate
    const minScale = 1; // Minimum scale for pulsate
    
    const pulseInterval = setInterval(() => {
        scale += pulseSpeed * Math.sin(Date.now() / 500); // Use sine for smooth pulsating effect
        scale = Math.max(minScale, Math.min(scale, maxScale)); // Clamp scale
        hologram.style.transform = `scale(${scale})`;
    }, 100); // Make it appear smooth

    // Behavior to distract nearby enemies
    enemies.forEach(enemy => {
        const enemyX = parseInt(enemy.style.left) + (enemy.offsetWidth / 2);
        const enemyY = parseInt(enemy.style.bottom) + (enemy.offsetHeight / 2);
        const dx = playerPositionX - enemyX;
        const dy = playerPositionY - enemyY;
        const distance = Math.sqrt(dx * dx + dy * dy);

        if (distance < 100) { // If enemy is within distraction range
            // Smoothly move the enemy away from the hologram
            const moveAmount = 50; // The distance to move away
            const newLeft = enemyX + (dx > 0 ? moveAmount : -moveAmount); // Move away from hologram
            enemy.style.transition = 'left 0.5s'; // Smooth movement transition
            enemy.style.left = `${newLeft}px`;
        }
    });

    // Remove the hologram after 5 seconds
    setTimeout(() => {
        clearInterval(pulseInterval); // Stop the pulsating effect
        hologram.remove(); // Remove hologram from the game world
    }, 7500);
}
 
function animateBullet(bulletObj, speed, impactCallback = () => {}) {
    const bulletInterval = setInterval(() => {
        const bullet = bulletObj.element;
        const newLeft = parseInt(bullet.style.left) + (bulletObj.direction * speed);
        bullet.style.left = newLeft + 'px';

        if (newLeft > gameScrollPosition + gameContainer.offsetWidth || newLeft < 0) {
            bullet.remove();
            clearInterval(bulletInterval);
            return;
        }

        for (const target of [...obstacles, ...enemies]) {
            if (checkCollision(bullet, target)) {
                // Handle infected + shielded enemy
                if (target.classList.contains('infected') && target.classList.contains('shielded')) {
                    let shieldHitsLeft = parseInt(target.dataset.shieldHitsLeft) || 2;
                    shieldHitsLeft--;

                    if (shieldHitsLeft <= 0) {
                        // Shield broken
                        target.dataset.shieldHitsLeft = '0';
                        target.classList.remove('shielded');

                        let health = parseInt(target.dataset.health) || 1;
                        health--;

                        if (health <= 0) {
                            target.remove();
                            enemies = enemies.filter(e => e !== target);
                        } else {
                            target.dataset.health = health.toString();
                            target.style.opacity = '0.5';
                            setTimeout(() => {
                                if (target) target.style.opacity = '0.8';
                            }, 150);
                        }
                    } else {
                        // Shield still active, just decrement and flash
                        target.dataset.shieldHitsLeft = shieldHitsLeft.toString();
                        target.style.opacity = '0.5';
                        setTimeout(() => {
                            if (target) target.style.opacity = '0.8';
                        }, 150);
                    }

                    createBurst(newLeft, parseInt(bullet.style.bottom));
                    bullet.remove();
                    clearInterval(bulletInterval);
                    return;
                }

                // Hypno bullet effect (no instant death)
                if (bullet.classList.contains('hypno-bullet') && target.classList.contains('enemy') && !target.classList.contains('hypnotized')) {
                    target.classList.add('hypnotized');
                    target.style.backgroundColor = 'pink';
                    hypnotizeEnemy(target);

                    createBurst(newLeft, parseInt(bullet.style.bottom));
                    bullet.remove();
                    clearInterval(bulletInterval);
                    return;
                }

                // Fire bullet effect (fade and remove obstacle)
                if (bullet.classList.contains('fire-bullet') && target.classList.contains('obstacle')) {
                    target.style.transition = 'opacity 0.5s';
                    target.style.opacity = '0';
                    setTimeout(() => target.remove(), 500);
                    createBurst(newLeft, parseInt(bullet.style.bottom));
                    bullet.remove();
                    clearInterval(bulletInterval);
                    return;
                }

                // Ice bullet effect (freeze, no instant death)
                if (bullet.classList.contains('ice-bullet')) {
                    if (target.classList.contains('obstacle') || target.classList.contains('enemy')) {
                        target.classList.add('frozen');
                        target.style.backgroundColor = '#00f';
                        target.style.opacity = '0.5';
                        target.dataset.isFrozen = 'true';

                        setTimeout(() => {
                            if (target.dataset.isFrozen === 'true') {
                                target.classList.remove('frozen');
                                target.style.backgroundColor = '';
                                target.style.opacity = '1';
                                delete target.dataset.isFrozen;
                            }
                        }, 5000);

                        createBurst(newLeft, parseInt(bullet.style.bottom));
                        bullet.remove();
                        clearInterval(bulletInterval);
                        return;
                    }
                }

                // Normal enemies and obstacles: remove on hit
                if (target.classList.contains('enemy') || target.classList.contains('obstacle')) {
                    target.remove();
                    enemies = enemies.filter(e => e !== target);
                    createBurst(newLeft, parseInt(bullet.style.bottom));
                    bullet.remove();
                    clearInterval(bulletInterval);
                    return;
                }

                // Apply other impact effects, if any
                impactCallback(target);

                bullet.remove();
                clearInterval(bulletInterval);
                return;
            }
        }
    }, 1000 / 60);
}
 
function reduceLives() {
    if (player.style.border) {
        player.style.border = '';
        player.style.opacity = '1';
    } else {
        lives--;
        if (lives <= 0) {
            endGame(false); // Call endGame if lives are 0
        } else {
        }
    }
    updateDisplay();
}

function resetBoss() {
    if (boss) {
        if (level === 3) {
            bossHealth = 150; // Restore boss health to 150 for level 3
        } else {
            bossHealth = 100; // Restore boss health for other levels
        }
        updateBossHealth(); // Update the UI to reflect the new health value
    }
}
 
            function checkCollision(rect1, rect2) {
                const rect1Bounds = rect1.getBoundingClientRect();
                const rect2Bounds = rect2.getBoundingClientRect();
                return !(rect1Bounds.top > rect2Bounds.bottom || rect1Bounds.bottom < rect2Bounds.top ||
                        rect1Bounds.left > rect2Bounds.right || rect1Bounds.right < rect2Bounds.left);
            }
 
            function togglePause() {
                if (isPaused) {
                    gameInterval = setInterval(gameLoop, 1000 / 60);
                    isPaused = false;
                } else {
                    clearInterval(gameInterval);
                    isPaused = true;
                }
            }
 
            function clearAllElements() {
                [obstacles, enemies, bullets.map(b => b.element), powerUps, platforms, bossDoors, coins]
                    .forEach(arr => {
                        arr.forEach(el => el.remove());
                        arr.length = 0;
                    });
            }
 
function interact() {
    if (checkCollision(player, friend)) {
        activateFriendDialogue();
    }
    bossDoors.forEach(door => {
        if (checkCollision(player, door)) {
            if (score >= level * bossScoreThreshold) {
                openBossHallway();
            } else {
                openBossHallway();
            }
        }
    });
}
 
            function openBossHallway() {
                bossHallway.style.display = 'flex';
                clearAllElements();
                clearInterval(gameInterval);

                isInBossDoor = true;
            }
 
function startBossFight() {
    bossHallway.style.display = 'none';
    isInBossDoor = true; // enable movement restrictions again if desired
    triggerBossFight();
    gameInterval = setInterval(gameLoop, 1000 / 60); // Ensure the game loop is running for updates
}
 
function incrementLevel() {
    level++; // Increment level

    // Check if the level exceeds 3; if so, reset to 1
    if (level > 3) {
        level = 1; // Reset to Level 1
    }

    playerMaxSpeed = 5; // Reset speed back to normal
    localStorage.setItem('playerLevel', level); // Save updated level in local storage
    updateDisplay(); // Update the game display
    resetGame(); // Reset game state


}
 
            function switchLevelBackground() {
                const backgrounds = ['#333', '#1E90FF', '#228B22', '#a3a3a3','#7208c1'];
                gameContainer.style.backgroundColor = backgrounds[(level - 1) % backgrounds.length];
            }
 
            function continueGame() {
                levelIntro.style.display = 'none';
                gameInterval = setInterval(gameLoop, 1000 / 60);
            }

function spawnEndlessEntities() {
    if (!isPaused && !bossFightActive) {
        if (Math.random() < 0.003) spawnObstacle();
        
        // Spawn enemies based on the current level
        if (level === 1) {
            if (Math.random() < 0.005) spawnEnemy();
            if (Math.random() < 0.003) spawnFlyingEnemy();
            if (Math.random() < 0.002) spawnObstacle();
        } else if (level === 2) {
            if (Math.random() < 0.002) spawnObstacle();
            if (Math.random() < 0.003) spawnChargingEnemy(); // Charging enemy option for Level 2
            if (Math.random() < 0.001) spawnSniperEnemy(); // Sniper enemy option for Level 2
        } else if (level === 3) {
            if (Math.random() < 0.005) spawnEnemy();
            if (Math.random() < 0.003) spawnFlyingEnemy(); // Flying enemy option for Level 3
            if (Math.random() < 0.001) spawnReflectiveEnemy(); // Reflective enemy option for Level 3
        } else if (level === 4) {
            if (Math.random() < 0.001) spawnLaserEnemy(); // Charging enemy option for Level 2
            if (Math.random() < 0.002) spawnSplitterEnemy();
        } else if (level === 5) {
            if (Math.random() < 0.005) spawnEnemy();
            if (Math.random() < 0.003) spawnVirusDrone(); // Charging enemy option for Level 2
            if (Math.random() < 0.001) spawnSniperEnemy(); // Sniper enemy option for Level 2
        }

        if (Math.random() < 0.002 && !currentPowerUp) spawnPowerUp();
        if (Math.random() < 0.001) spawnPlatform();
        if (Math.random() < 0.003) spawnCoin();



        // Manage boss door spawning only if in Story Mode
        if (localStorage.getItem('gameMode') === 'endless') {
            if (bossDoors.length === 0 && score >= level * bossScoreThreshold && enemies.length === 0) {
                spawnBossDoor();
            }
        }
    }
}


 
function gameLoop() {
    if (!isPaused) {
        updatePlayerPosition();

        const gameMode = localStorage.getItem('gameMode');

        if (gameMode === 'endless') {
            spawnEndlessEntities();
            switchLevelBackground();
        } else if (gameMode === 'story') {
            spawnEntities();
        } else if (gameMode === 'sandbox') {
            // Sandbox mode: No auto spawning
            level = 1; // Optional: force level here
        }

        moveElements();

        handlePlayerEnemyCollision();

        updateShopScoreDisplay();

        checkScoreForLevelTransition();
        updateBoostDrainer();
        updateDisplay();
    }
}
 
function endGame(isWin = false) {
    clearInterval(gameInterval);
    
    if (!isWin) {
        // Reset boss health if the game is lost
        resetBoss();
    }
    

    // Display the game over screen with the final score
    gameOverScreen.style.display = 'flex';
    if (localStorage.getItem('gameMode') === 'story') {
        gameOverScreen.innerHTML = `
            <p>${isWin ? 'Congratulations! You won!' : 'Game Over!'}</p>
            <p>Your current score: ${score}</p>
            <button onclick="restartGame2()">Restart</button>
        `;
    } else if (localStorage.getItem('gameMode') === 'endless') {
        gameOverScreen.innerHTML = `
            <p>Endless Mode Over!</p>
            <p>Your score: ${score}</p>
            <button onclick="restartGame()">Restart</button>
        `;
    }
}
 
            function restartGame() {
                gameOverScreen.style.display = 'none';
                resetGame();
                startLevel();
            }

            function restartGame2() {
                gameOverScreen.style.display = 'none';
                resetGame();
                startLevel();
            }
 
            function triggerBossFight() {
                bossFightScreen.style.display = 'flex';
                setTimeout(() => {
                    bossFightScreen.style.display = 'none';
                    startBossLogic();
                }, 2000);
            }
 
            function startBossLogic() {
                bossFightActive = true;
                boss = createElement('boss', [], 600);
                boss.style.bottom = '100px';
                gameWorld.appendChild(boss);
                displayBossHealth();
 
                cycleBossAttacks(); // Start the attack pattern cycle
            }
 
 
 



// Helper function for delay(ms)
function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

// Example placeholder for displayMessage function
// You need to implement or adjust this to your UI


// New asynchronous cycleBossAttacks function


// Helper to sleep (wait) for milliseconds

// Display a message for specified seconds
async function displayMessageTimed(text, seconds) {
    displayMessage(text, seconds);
    await sleep(seconds * 1000);
}

// Displays all pre-attack messages in sequence, then calls and awaits attackFunc
async function preAttackWithMessage(messages, attackFunc) {
    for (const msg of messages) {
        await displayMessageTimed(msg.text, msg.durationSeconds);
    }
    await attackFunc();
}

async function cycleBossAttacks() {
    if (bossHealth <= 0) {
        if (!bossDefeatedMessageDisplayed) {
            bossDefeatedMessageDisplayed = true;
            await displayMessageTimed("Boss Defeated!", 5);
        }
        return;
    }

    if (!phaseStartTime) {
        phaseStartTime = Date.now();
        bossAttackPhase = 0;
    }

    bossAttacking = true;
    bossShielded = true;
    boss.classList.add('boss-shielded');

    const maxBossMoves = (level === 1) ? 4 : (level === 2) ? 4 : 6;

    switch (level) {
        case 1:
            switch (bossAttackPhase) {
                case 0: await bossEnemyBarrage(); break;
                case 1: await bossTargetSlam(); break;
                case 2: await bossNewPower(); break;
                case 3: await bossExplosionRain(); break;
            }
            break;

        case 2:
            switch (bossAttackPhase) {
                case 0: await bossPhaseTwoBarrage(); break;
                case 1: await bossPhaseTwoTargetSlam(); break;
                case 2: await bossPhaseTwoNewPower(); break;
                case 3: await bossPhaseTwoExplosionRain(); break;
            }
            break;

        case 3:
            if (bossAttackPhase === 0 && (Date.now() - phaseStartTime) < 13000) {
                await startPhaseThree();
                return;
            }
            switch (bossAttackPhase) {
                case 0: await bossPhaseThree(); break;
                case 1: await bossPhaseTwoExplosionRain2(); break;
                case 2: await bossPhaseTwoTargetSlam3(); break;
                case 3: await bossPhaseTwoNewPower2(); break;
                case 4: await bossPhaseTwoTargetSlam2(); break;
                case 5: await bossPhase5(); break;
            }
            break;

        case 4:
            if (bossAttackPhase === 0 && (Date.now() - phaseStartTime) < 13000) {
                await startPhaseFour();
                return;
            }
            switch (bossAttackPhase) {
                case 0:
                    await preAttackWithMessage(
                        [{ text: "Lets start with something simple!", durationSeconds: 4 }],
                        EnemyBarrage
                    );
                    break;
                case 1:
                    await preAttackWithMessage(
                        [{ text: "Incredible, a nice worthy foe.", durationSeconds: 3 }],
                        bossPhaseTwoTargetSlam3
                    );
                    break;
                case 2:
                    await preAttackWithMessage(
                        [{ text: "Well nobody has got this far before, your doing somehow great...", durationSeconds: 4 }],
                        bossPhase5
                    );
                    break;
                case 3:
                    await preAttackWithMessage(
                        [{ text: "How are you NOT DEAD YET?", durationSeconds: 3 }],
                        bossPhaseTwoExplosionRain2
                    );
                    break;
                case 4:
                    await preAttackWithMessage(
                        [{ text: "Your actully getting annoying now...", durationSeconds: 3 }],
                        bossPhaseThree
                    );
                    break;
                case 5:
                    await preAttackWithMessage(
                        [{ text: "Alright let me stop talking now its game on.", durationSeconds: 4 }],
                        slidingLaserPhase
                    );
                    break;
            }
            break;

        case 5:
            switch (bossAttackPhase) {
                case 0: await bossPhaseFiveAttackA(); break;
                case 1: await bossPhaseFiveAttackB(); break;
                case 2: await bossPhaseFiveAttackC(); break;
                case 3: await bossPhaseFiveAttackE(); break;
                case 4: await bossPhaseFiveAttackF(); break;
                case 5: await bossPhaseFiveAttackF(); break;
            }
            break;

        default:
            // You might want to handle unexpected level values here as well
            break;
    }

    // Increment phase for next attack
    bossAttackPhase = (bossAttackPhase + 1) % maxBossMoves;

    // Remove shield after 10s and notify player (fire-and-forget, no await needed)
    setTimeout(() => {
        bossShielded = false;
        boss.classList.remove('boss-shielded');
        displayMessage("Boss shield is OFF! Attack now!");
    }, 10000);
}



async function slidingLaserPhase() {
    displayMessage("Sliding laser phase! Jump over the lasers!", 3);
    await sleep(3000);

    const gameWorld = document.getElementById('game-world');
    const gameBounds = gameWorld.getBoundingClientRect();

    // Laser parameters
    const laserWidth = 150;
    const laserHeight = 20;
    const initialSpeed = 3;
    const maxBounces = 4;

    // Create laser elements
    function createLaserElement(y, direction) {
        const el = document.createElement('div');
        el.style.position = 'absolute';
        el.style.width = laserWidth + 'px';
        el.style.height = laserHeight + 'px';
        el.style.backgroundColor = 'red';
        el.style.bottom = y + 'px';
        el.style.left = (gameBounds.width / 2 - laserWidth / 2) + 'px'; // center horizontally
        el.style.borderRadius = '5px';
        el.style.zIndex = '100';
        gameWorld.appendChild(el);

        return {
            element: el,
            y: y,
            speed: initialSpeed,
            direction: direction,
            bounces: 0,
            destroyed: false,
            get left() {
                return this.element.offsetLeft;
            },
            set left(val) {
                this.element.style.left = val + 'px';
            },
            get right() {
                return this.left + laserWidth;
            },
            remove() {
                if (this.element.parentElement) {
                    this.element.parentElement.removeChild(this.element);
                }
                this.destroyed = true;
            }
        };
    }

    // Instantiate two lasers
    const lasers = [
        createLaserElement(gameBounds.height * 0.3, 1),
        createLaserElement(gameBounds.height * 0.5, -1)
    ];

    // Check collision between laser and player
    function laserCollidesWithPlayer(laser) {
        const laserRect = laser.element.getBoundingClientRect();
        const playerRect = player.getBoundingClientRect();

        return !(
            playerRect.right < laserRect.left ||
            playerRect.left > laserRect.right ||
            playerRect.bottom < laserRect.top ||
            playerRect.top > laserRect.bottom
        );
    }

    return new Promise(resolve => {
        function animate() {
            // If both destroyed, end phase
            if (lasers.every(l => l.destroyed)) {
                displayMessage("Sliding laser phase complete!", 3);
                setTimeout(() => {
                    resolve();
                    cycleBossAttacks();
                }, 3000);
                return;
            }

            lasers.forEach(laser => {
                if (laser.destroyed) return;

                let newLeft = laser.left + laser.speed * laser.direction;

                // Bounce left wall
                if (newLeft <= 0) {
                    newLeft = 0;
                    laser.direction *= -1;
                    laser.bounces++;
                    laser.speed *= 1.3; // speed up

                    if (laser.bounces >= maxBounces) {
                        laser.remove();
                        return;
                    }
                }

                // Bounce right wall
                if (newLeft + laserWidth >= gameBounds.width) {
                    newLeft = gameBounds.width - laserWidth;
                    laser.direction *= -1;
                    laser.bounces++;
                    laser.speed *= 1.3;

                    if (laser.bounces >= maxBounces) {
                        laser.remove();
                        return;
                    }
                }

                laser.left = newLeft;

                // Damage player if colliding
                if (laserCollidesWithPlayer(laser)) {
                    lives = Math.max(0, lives - 1);
                    displayMessage(`Ouch! Lives left: ${lives}`, 1);

                    // Optional knockback or player jump boost can be added here
                }
            });

            requestAnimationFrame(animate);
        }

        animate();
    });
}

function bossPhase5() {
    const blockWidth = 80;
    const blockHeight = 20;

    const lavaRiseSpeed = 4;           // pixels per tick
    const lavaRiseInterval = 100;      // ms
    const warningDuration = 1000;      // 1 second warning before lava rises
    const totalPhases = 3;
    const obstacleWidth = 30;   // Add this line
    const obstacleHeight = 30;  // Add this line
    const platformHeights = [100, 200, 300];
    const laserWarningDuration = 1000; // 1 second yellow warning before laser fires
    const laserPhaseDuration = 6000;   // total laser active time per phase (6 seconds)
    const laserBaseInterval = 1000;    // starting laser shoot interval

    const obstacles = [];
    const warningLines = [];
    const lasers = [];

    const gameWorld = document.getElementById('game-world');

    let currentPhase = 0;
    let lavaHeight = 0;
    let lavaInterval;
    let lastDamageTime = 0;

    // Save original jump settings
    let originalMaxJumps = maxJumps;
    let originalDoubleJumpEnabled = isDoubleJumpEnabled;

    let laserIntervalId = null;
    let laserTimeoutId = null;

    // Create or get lava element
    let lavaElement = gameWorld.querySelector('.lava');
    if (!lavaElement) {
        lavaElement = document.createElement('div');
        lavaElement.className = 'lava';
        Object.assign(lavaElement.style, {
            position: 'absolute',
            width: '100%',
            bottom: '0',
            backgroundColor: 'red',
            height: '0px',
            zIndex: '5',
            transition: 'height 0.1s linear',
        });
        gameWorld.appendChild(lavaElement);
    }

    // Clear existing platforms and obstacles
    function clearPlatformsAndObstacles() {
        obstacles.forEach(o => o.remove());
        obstacles.length = 0;

        const blocks = [...gameWorld.querySelectorAll('div')].filter(el =>
            el.style.backgroundColor === 'blue' &&
            el.offsetWidth === blockWidth &&
            el.offsetHeight === blockHeight
        );
        blocks.forEach(b => b.remove());
    }



    // Create a block platform
    function spawnBlock(x, y) {
        const block = document.createElement('div');
        Object.assign(block.style, {
            position: 'absolute',
            width: blockWidth + 'px',
            height: blockHeight + 'px',
            backgroundColor: 'blue',
            left: x + 'px',
            bottom: y + 'px',
            zIndex: '10',
        });
        gameWorld.appendChild(block);
        return block;
    }

    // Create obstacle near block to jump on
    function spawnObstacle(x, y) {
        const obstacle = document.createElement('div');
        obstacle.className = 'obstacle';
        Object.assign(obstacle.style, {
            position: 'absolute',
            width: obstacleWidth + 'px',
            height: obstacleHeight + 'px',
            backgroundColor: 'orange',
            left: x + 'px',
            bottom: y + 'px',
            zIndex: '10',
        });
        gameWorld.appendChild(obstacle);
        obstacles.push(obstacle);
        return obstacle;
    }

    function spawnPhasePlatforms(phase) {
        clearPlatformsAndObstacles();
        const yPos = platformHeights[phase];
        const xs = [100, 300, 500];

        xs.forEach(x => spawnBlock(x, yPos));
        xs.forEach(x => spawnObstacle(x + 70, yPos));
    }

    // Get player’s distance from bottom of gameWorld
    function getPlayerBottomOffset() {
        const playerRect = player.getBoundingClientRect();
        const worldRect = gameWorld.getBoundingClientRect();
        return worldRect.bottom - playerRect.bottom;
    }

    function setTripleJump() {
        maxJumps = 3;
        isDoubleJumpEnabled = true;
        jumpCount = 0;
    }

    function restoreJumpSettings() {
        maxJumps = originalMaxJumps;
        isDoubleJumpEnabled = originalDoubleJumpEnabled;
        jumpCount = 0;
    }

    function startLavaPhase() {
        displayMessage("Lava is rising soon! Prepare yourself!");
        setTimeout(() => {
            lavaHeight = 0;
            lavaElement.style.height = '0px';
            setTripleJump();
            lavaInterval = setInterval(riseLava, lavaRiseInterval);
        }, warningDuration);
    }

    // Lava rising step
    function riseLava() {
        const maxLavaHeight = platformHeights[currentPhase];

        if (lavaHeight < maxLavaHeight) {
            lavaHeight += lavaRiseSpeed;
            if (lavaHeight > maxLavaHeight) lavaHeight = maxLavaHeight;
            lavaElement.style.height = lavaHeight + 'px';

            const playerBottomPx = parseFloat(player.style.bottom) || 0;
            const playerVelocityDown = playerVelocityY <= 0;

// Remove or comment out this block inside riseLava:
if (playerBottomPx < lavaHeight && playerVelocityDown) {
    playerPositionY = lavaHeight;
    playerVelocityY = 0;
    isJumping = false;
    jumpCount = 0;
    player.style.bottom = playerPositionY + 'px';
}

            const now = Date.now();
            if (checkCollision(player, lavaElement)) {
                const playerBottom = getPlayerBottomOffset();
                if (playerBottom < lavaHeight && (now - lastDamageTime) > 1000) {
                    reduceLives();
                    lastDamageTime = now;
                }
            }
        } else {
            clearInterval(lavaInterval);
            startLaserPhase();
        }
    }

    // Create a warning line (yellow) above a block
    function createWarningLine(block) {
        const warning = document.createElement('div');
        warning.style.position = 'absolute';
        warning.style.width = blockWidth + 'px';
        warning.style.height = '5px';
        warning.style.backgroundColor = 'yellow';
        warning.style.left = block.style.left;
        warning.style.bottom = (parseInt(block.style.bottom) + blockHeight) + 'px';
        warning.style.zIndex = '20';
        gameWorld.appendChild(warning);
        warningLines.push(warning);
        return warning;
    }

    // Create a laser beam (red) that shoots upwards from a block
    function createLaser(block) {
        const laser = document.createElement('div');
        laser.style.position = 'absolute';
        laser.style.width = '50px';
        laser.style.height = '200px'; // laser beam height
        laser.style.backgroundColor = 'red';
        laser.style.left = (parseInt(block.style.left) + blockWidth / 2 - 3) + 'px'; // centered on block
        laser.style.bottom = (parseInt(block.style.bottom) + blockHeight) + 'px';
        laser.style.zIndex = '15';
        gameWorld.appendChild(laser);
        lasers.push(laser);

        // Remove laser after 0.5s
        setTimeout(() => {
            laser.remove();
            lasers.splice(lasers.indexOf(laser), 1);
        }, 500);
        return laser;
    }

    // Remove warning lines
    function clearWarningLines() {
        warningLines.forEach(w => w.remove());
        warningLines.length = 0;
    }

    // Remove all active lasers
    function clearLasers() {
        lasers.forEach(l => l.remove());
        lasers.length = 0;
    }

    // Laser phase variables
    let laserPhaseTimer = 0;
    let currentLaserInterval = laserBaseInterval;

    // Laser damage cooldown for player (similar to lava damage)
    let laserLastDamageTime = 0;

    // Laser Phase logic:
    // Every currentLaserInterval ms: choose a random block platform and:
    // - Draw a yellow warning line 1 second before laser fires
    // - After 1s, fire laser & damage player if in laser zone (once per laser)
    function laserTick() {
        if (laserPhaseTimer >= laserPhaseDuration) {
            // Laser phase ended
            clearInterval(laserIntervalId);
            clearWarningLines();
            clearLasers();
            lavaInterval = setInterval(lowerLava, lavaRiseInterval);
            return;
        }

        laserPhaseTimer += currentLaserInterval;

        // Get all current blocks (platforms player can jump on)
        const blocks = [...gameWorld.querySelectorAll('div')].filter(el =>
            el.style.backgroundColor === 'blue' &&
            el.offsetWidth === blockWidth &&
            el.offsetHeight === blockHeight
        );
        if (blocks.length === 0) return;

        // Pick a random block different from last one if possible
        let chosenBlock = blocks[Math.floor(Math.random() * blocks.length)];

        // WARNING LINE
        const warning = createWarningLine(chosenBlock);

        // After 1s fire laser & damage
        setTimeout(() => {
            warning.remove();
            warningLines.splice(warningLines.indexOf(warning), 1);

            const laser = createLaser(chosenBlock);

            // Check if player is in laser zone vertically and horizontally approx.
            const now = Date.now();
            const playerLeftPx = parseFloat(player.style.left) || 0;
            const playerRightPx = playerLeftPx + player.offsetWidth;

            const blockLeft = parseInt(chosenBlock.style.left);
            const blockRight = blockLeft + blockWidth;

            const laserTop = parseInt(laser.style.bottom) + parseInt(laser.style.height);
            const playerBottom = parseFloat(player.style.bottom) || 0;
            const playerTop = playerBottom + player.offsetHeight;

            // Check horizontal overlap
            const horizontalOverlap = playerRightPx > blockLeft && playerLeftPx < blockRight;
            // Check vertical overlap with laser beam
            const verticalOverlap = playerBottom < laserTop && playerTop > parseInt(laser.style.bottom);

            if (horizontalOverlap && verticalOverlap && (now - laserLastDamageTime) > 1000) {
                reduceLives();
                laserLastDamageTime = now;
            }
        }, laserWarningDuration);
    }

    // Lower lava smoothly after laser phase ends
    function lowerLava() {
        if (lavaHeight > 0) {
            lavaHeight -= lavaRiseSpeed;
            if (lavaHeight < 0) lavaHeight = 0;
            lavaElement.style.height = lavaHeight + 'px';

            // Adjust player standing on lava during lowering
            const playerBottomPx = parseFloat(player.style.bottom) || 0;
            const playerVelocityDown = playerVelocityY <= 0;
            if (playerBottomPx < lavaHeight && playerVelocityDown) {
                playerPositionY = lavaHeight;
                playerVelocityY = 0;
                isJumping = false;
                jumpCount = 0;
                player.style.bottom = playerPositionY + 'px';
            }
        } else {
            clearInterval(lavaInterval);
            // Next phase
            currentPhase++;
            if (currentPhase < totalPhases) {
                currentLaserInterval = Math.max(laserBaseInterval - currentPhase * 150, 400); // speeds up laser shooting each phase
                laserPhaseTimer = 0;
                spawnPhasePlatforms(currentPhase);
                startLavaPhase();
            } else {
                displayMessage("Lava and laser phases complete! Prepare for next boss attack.");
                setTimeout(() => {
                    clearPlatformsAndObstacles();
                    lavaElement.style.height = '0px';
                    restoreJumpSettings();
                    cycleBossAttacks();
                }, 2000);
            }
        }
    }

    // Start lava rising phases as before
    currentPhase = 0;
    spawnPhasePlatforms(currentPhase);
    displayMessage("Prepare! Lava will start rising soon!");

    setTimeout(() => {
        startLavaPhase();
    }, 1500);

    // Overwrite startLavaPhase so that after lava rises fully, laser phase starts
    function startLavaPhase() {
        displayMessage("Lava is rising soon! Prepare yourself!");
        setTimeout(() => {
            lavaHeight = 0;
            lavaElement.style.height = '0px';
            setTripleJump();
            lavaInterval = setInterval(riseLava, lavaRiseInterval);
        }, warningDuration);
    }

    // Modify riseLava to start laser phase after rising fully
    function riseLava() {
        const maxLavaHeight = platformHeights[currentPhase];

        if (lavaHeight < maxLavaHeight) {
            lavaHeight += lavaRiseSpeed;
            if (lavaHeight > maxLavaHeight) lavaHeight = maxLavaHeight;
            lavaElement.style.height = lavaHeight + 'px';

            const playerBottomPx = parseFloat(player.style.bottom) || 0;
            const playerVelocityDown = playerVelocityY <= 0;

            if (playerBottomPx < lavaHeight && playerVelocityDown) {
                playerPositionY = lavaHeight;
                playerVelocityY = 0;
                isJumping = false;
                jumpCount = 0;
                player.style.bottom = playerPositionY + 'px';
            }

const now = Date.now();
if (checkCollision(player, lavaElement)) {
    const playerBottom = getPlayerBottomOffset();
    console.log(`Collision! playerBottom=${playerBottom}, lavaHeight=${lavaHeight}`);
    if (playerBottom < lavaHeight && (now - lastDamageTime) > 1000) {
        console.log("Reducing lives from lava collision");
        reduceLives();
        lastDamageTime = now;
    }
}
        } else {
            clearInterval(lavaInterval);
            displayMessage("Warning! Lasers incoming!");
            startLaserPhase();
        }
    }

    // Laser phase start
    function startLaserPhase() {
        laserPhaseTimer = 0;
        laserLastDamageTime = 0;
        laserIntervalId = setInterval(laserTick, currentLaserInterval);

        // Laser phase ends after fixed duration
        laserTimeoutId = setTimeout(() => {
            clearInterval(laserIntervalId);
            clearWarningLines();
            clearLasers();
            displayMessage("Lava retreating... Prepare for next rise!");
            lavaInterval = setInterval(lowerLava, lavaRiseInterval);
        }, laserPhaseDuration);
    }
}

function checkCollisionWithPlatformsAndObstacles() {
    const playerLeft = playerPositionX;
    let playerBottom = playerPositionY;
    const playerWidth = player.offsetWidth;
    const playerHeight = player.offsetHeight;

    let onPlatform = false;

    // Check platforms
    const blocks = [...gameWorld.querySelectorAll('div')].filter(el =>
        el.style.backgroundColor === 'blue' &&
        el.offsetWidth === 80 &&
        el.offsetHeight === 20
    );

    for (const block of blocks) {
        const blockLeft = parseInt(block.style.left);
        const blockBottom = parseInt(block.style.bottom);
        const blockRight = blockLeft + block.offsetWidth;
        const blockTop = blockBottom + block.offsetHeight;

        const horizontalOverlap = playerLeft + playerWidth > blockLeft && playerLeft < blockRight;
        const nextPlayerBottom = playerBottom + playerVelocityY;

        if (
            horizontalOverlap &&
            playerBottom >= blockTop &&
            nextPlayerBottom <= blockTop &&
            playerVelocityY <= 0
        ) {
            playerPositionY = blockTop;
            playerVelocityY = 0;
            isJumping = false;
            jumpCount = 0;
            onPlatform = true;
            break;
        } else if (
            horizontalOverlap &&
            playerBottom >= blockTop - 1 &&
            playerBottom <= blockTop + 1 &&
            playerVelocityY === 0
        ) {
            playerPositionY = blockTop;
            isJumping = false;
            jumpCount = 0;
            onPlatform = true;
            break;
        }
    }

    // Check obstacles with same logic
    for (const obstacle of obstacles) {
        const obLeft = parseInt(obstacle.style.left);
        const obBottom = parseInt(obstacle.style.bottom);
        const obRight = obLeft + obstacle.offsetWidth;
        const obTop = obBottom + obstacle.offsetHeight;

        const horizontalOverlap = playerLeft + playerWidth > obLeft && playerLeft < obRight;
        const nextPlayerBottom = playerBottom + playerVelocityY;

        if (
            horizontalOverlap &&
            playerBottom >= obTop &&
            nextPlayerBottom <= obTop &&
            playerVelocityY <= 0
        ) {
            playerPositionY = obTop;
            playerVelocityY = 0;
            isJumping = false;
            jumpCount = 0;
            onPlatform = true;
            break;
        } else if (
            horizontalOverlap &&
            playerBottom >= obTop - 1 &&
            playerBottom <= obTop + 1 &&
            playerVelocityY === 0
        ) {
            playerPositionY = obTop;
            isJumping = false;
            jumpCount = 0;
            onPlatform = true;
            break;
        }
    }

    return onPlatform;
}

function bossPhaseTwoTargetSlam2() {
    const warningLineHeight = 5; // Height of the warning line
    const rodWidth = 80; // Width of the laser rod
    const rodHeight = 300; // Height of the rod
    const rodColor = 'red'; // Color of the rod
    const laserSpawnTime = 500; // Time between spawn of lasers
    const totalWarnings = 12; // Total number of laser warnings
    let warningCount = 0; // Counter for warnings
    const warningPositions = []; // Store positions for warnings

    function spawnWarningLine() {
        // Create a warning line
        const warningLine = document.createElement('div');
        warningLine.classList.add('warning-line');
        warningLine.style.width = '80px'; // Width of the warning line
        warningLine.style.height = `${warningLineHeight}px`;
        warningLine.style.backgroundColor = 'yellow'; // Set color
        warningLine.style.position = 'absolute';
        const warningLinePosition = Math.random() * (gameContainer.offsetWidth - 80); // Random horizontal position
        warningLine.style.left = `${warningLinePosition}px`; // Set position
        warningLine.style.bottom = '50px'; // Slightly above player position
        gameWorld.appendChild(warningLine);

        // Wait for 0.5 seconds, then spawn the laser rod above
        setTimeout(() => {
            // Create a rod above the warning line
            const rod = document.createElement('div');
            rod.classList.add('rod'); // Add a class for styling
            rod.style.width = `${rodWidth}px`;
            rod.style.height = `${rodHeight}px`;
            rod.style.backgroundColor = rodColor;
            rod.style.position = 'absolute';
            rod.style.left = `${warningLinePosition + 25}px`; // Center the rod above the warning line
            rod.style.bottom = '0px'; // Start at ground level

            gameWorld.appendChild(rod); // Add rod to the game world

            // Damage player if they are still there
            if (checkCollision(player, rod)) {
                reduceLives(); // Damage the player
            }

            // Remove the rod after a brief duration
            setTimeout(() => {
                rod.remove(); // Clean up after the rod
            }, 200); // Keep the rod visible for 200 ms

            // Remove the warning line
            warningLine.remove();
        }, 500); // Spawn the rod after 500 milliseconds
    }

    // Spawn warning lines and lasers at intervals
    const spawnWarningsInterval = setInterval(() => {
        if (warningCount >= totalWarnings) {
            clearInterval(spawnWarningsInterval); // Stop after total warnings
            cycleBossAttacks(); // Proceed to the next boss cycle
            return; // Exit the function
        }

        spawnWarningLine(); // Spawn a warning line
        warningCount++; // Increase warning count
    }, laserSpawnTime); // Spawn a warning every 500 ms
}

function bossPhaseTwoNewPower2() {
    const laserCount = 3;               // Number of lasers per burst
    const laserRadius = 80;             // Distance lasers start from boss center (for initial pos)
    const laserWidth = 20;
    const laserHeight = 20;
    const laserColor = 'red';
    const healColor = 'green';
    const healChance = 0.2;
    const maxBursts = 8;
    const laserInterval = 2000;         // Time between bursts

    let burstCount = 0;

    const bounceLimit = 1; // Number of bounces before laser is destroyed

    // Assume these globals (define globally)
    // const boss = document.getElementById('boss');
    // const player = document.getElementById('player');
    // const gameWorld = document.getElementById('gameWorld');

    // Get game world boundaries once
    const worldRect = gameWorld.getBoundingClientRect();

    function createLasers() {
        const bossRect = boss.getBoundingClientRect();

        for (let i = 0; i < laserCount; i++) {
            const angle = (i * 2 * Math.PI) / laserCount; // spread lasers evenly around circle

            // Create laser element
            const laser = document.createElement('div');
            laser.classList.add('laser');
            laser.style.position = 'absolute';
            laser.style.width = `${laserWidth}px`;
            laser.style.height = `${laserHeight}px`;
            laser.style.backgroundColor = laserColor;
            laser.style.borderRadius = '2px';

            // Initial position roughly at boss position + offset by radius along angle
            // Calculate relative to gameWorld top-left (absolute positioning)
            const startX = bossRect.left + bossRect.width/2 + Math.cos(angle)*laserRadius - laserWidth/2;
            const startY = bossRect.top + bossRect.height/2 + Math.sin(angle)*laserRadius - laserHeight/2;

            laser.style.left = `${startX}px`;
            laser.style.top = `${startY}px`;

            gameWorld.appendChild(laser);

            // Velocity vector (pixels per frame)
            // Let's say speed = 4px per frame (~60fps, adjust as needed)
            const speed = 4;
            let vx = Math.cos(angle)*speed;
            let vy = Math.sin(angle)*speed;

            let bounces = 0;

            // Use requestAnimationFrame for smooth animation
            function animate() {
                if (!laser.parentElement) return; // Laser removed/destroyed

                // Current position
                let x = parseFloat(laser.style.left);
                let y = parseFloat(laser.style.top);

                // Move laser
                x += vx;
                y += vy;

                // Check boundaries (bounce off gameWorld edges)
                if (x <= 0) { 
                    x = 0;
                    vx = -vx;
                    bounces++;
                }
                if (y <= 0) { 
                    y = 0;
                    vy = -vy;
                    bounces++;
                }
                if (x + laserWidth >= worldRect.width) {
                    x = worldRect.width - laserWidth;
                    vx = -vx;
                    bounces++;
                }
                if (y + laserHeight >= worldRect.height) {
                    y = worldRect.height - laserHeight;
                    vy = -vy;
                    bounces++;
                }

                laser.style.left = `${x}px`;
                laser.style.top = `${y}px`;

                // Collision with player
                // Here you can improve detection, currently simple AABB
                const playerRect = player.getBoundingClientRect();
                const laserRect = laser.getBoundingClientRect();

                if (!(playerRect.right < laserRect.left ||
                    playerRect.left > laserRect.right ||
                    playerRect.bottom < laserRect.top ||
                    playerRect.top > laserRect.bottom)) {

                    // On collision, heal or damage once:
                    if (Math.random() < healChance) {
                        gainExtraLife && gainExtraLife();
                    } else {
                        reduceLives();
                    }

                    // Remove laser immediately on hit
                    laser.remove();
                    return;
                }

                // Remove laser after 2 bounces
                if (bounces > bounceLimit) {
                    laser.remove();
                    return;
                }

                requestAnimationFrame(animate);
            }

            requestAnimationFrame(animate);
        }
    }

    // Interval that runs burstCount times, then stops
    const laserBurstInterval = setInterval(() => {
        if (burstCount >= maxBursts) {
            clearInterval(laserBurstInterval);
            cycleBossAttacks && cycleBossAttacks();
            return;
        }

        createLasers();
        burstCount++;
    }, laserInterval);
}



// Call function to test
// bossPhaseTwoNewPower2();


function startPhaseThree() {
    if (phaseThreeStarted) return; // Prevent running it multiple times
    phaseThreeStarted = true; // Set flag to true once started

    initializeBossHealth(); // Sets the boss health based on the current level

    const messages = [
        "Player: Oh god what is this",
        "Boss: All the moves and powers i had...",
        "Boss: But this time your not going to get pass this.",
        "Boss: This is your final game",
        "Player: alright lets take a bet on that!",
    ];

    let phase3MessageIndex = 0; // Track which message is currently displayed

    function displayMessages() {
        if (phase3MessageIndex < messages.length) {
            displayMessage(messages[phase3MessageIndex]);
            phase3MessageIndex++;
            setTimeout(displayMessages, 3000); // Display the next message after 3 seconds
        } else {
            // Once messages are done, start the boss attack cycle
            cycleBossAttacks(); // Start boss attacks
        }
    }

    displayMessages(); // Start displaying messages
}



// Wait until boss exists, then change color
function changeBossColorBlue() {
  if (!boss) {
    console.warn("Boss element not ready!");
    return;
  }
  boss.style.backgroundColor = 'blue';
}

function changeBossColorBlue2() {
  if (!boss) {
    console.warn("Boss element not ready!");
    return;
  }
  boss.style.backgroundColor = 'yellow';
}

// Call it when appropriate, no await needed
function startPhaseFour() {
    console.log("startPhaseFour called");

    if (typeof phaseThreeStarted === "undefined") {
        console.error("phaseThreeStarted is not defined!");
    }
    if (phaseThreeStarted) {
        console.log("Phase 3 already started.");
        return;
    }
    phaseThreeStarted = true;
    console.log("Starting Phase Four logic.");

    if (typeof initializeBossHealth !== "function") {
        console.error("initializeBossHealth is not defined!");
    }
    initializeBossHealth();

    // Set up level-specific behaviors
    let messages;
    let preMessageFunction = function() {};
    let endMessageFunction = function() {};

    console.log("Level:", level);

    if (level === 4) {
        messages = [
            "Boss: Well well well...",
            "Boss: THIS? is what my brother was talking about!",
            "Boss: You look so weak haha..",
            "Boss: Well i should introduce myself",
            "Boss: Im the strongest cube ever!",
            "Player: Well he just told me that already so a big flex ig...",
            "Boss: Intersting... you seem somewhat smart.",
            "Player: Well knowing this is the last boss fight i will end you!...",
            "Boss: Alright lets get started then!",
        ];
        preMessageFunction = changeBossColorBlue;
        endMessageFunction = cycleBossAttacks;
    } else if (level === 5) {
        messages = [
            "System: Welcome to your final test.",
            "Player: What do you mean?",
            "System: To unlock life you must win..",
            "Player: Alright lets do it!",
        ];
        preMessageFunction = changeBossColorBlue2;
        endMessageFunction = cycleBossAttacks;
    } else {
        messages = [
            "Boss: Well well well...",
            "Boss: THIS? is what my brother was talking about!",
            "Boss: You look so weak haha..",
            "Boss: Well i should introduce myself",
            "Boss: Im the strongest cube ever!",
            "Player: Well he just told me that already so a big flex ig...",
            "Boss: Intersting... you seem somewhat smart.",
            "Player: Well knowing this is the last boss fight i will end you!...",
            "Boss: Alright lets get started then!",
        ];
        preMessageFunction = changeBossColorBlue;
        endMessageFunction = cycleBossAttacks;
    }
    if (typeof preMessageFunction !== "function") {
        console.error("preMessageFunction is not a function!");
    }
    preMessageFunction();

    let phase3MessageIndex = 0;

    function displayMessages() {
        if (phase3MessageIndex < messages.length) {
            if (typeof displayMessage !== "function") {
                console.error("displayMessage is not defined!");
            }
            displayMessage(messages[phase3MessageIndex]);
            phase3MessageIndex++;
            setTimeout(displayMessages, 3000);
        } else {
            if (typeof endMessageFunction !== "function") {
                console.error("endMessageFunction is not a function!");
            }
            cycleBossAttacks();
        }
    }

    displayMessages();
}



function startPhaseFive() {
    if (phaseThreeStarted) return;
    phaseThreeStarted = true;

    initializeBossHealth();
    changeBossColorBlue2();

    const messages = [
        "System: Welcome to your final test.",
        "Player: What do you mean?",
        "System: To unlock life you must win..",
        "Player: Alright lets do it!",
    ];

    let phase3MessageIndex = 0;

    function displayMessages() {
        if (phase3MessageIndex < messages.length) {
            console.log("Displaying message:", messages[phase3MessageIndex]);
            displayMessage(messages[phase3MessageIndex]);
            phase3MessageIndex++;
            setTimeout(displayMessages, 3000);
        } else {
            console.log("Messages done. Starting boss attacks...");
            cycleBossAttacks();
        }
    }

    displayMessages();
}


function bossPhaseTwoTargetSlam() {
  const maxSlams = 4;
  const groundLevel = 0;
  const hoverHeight = 100;
  const slamDurationDown = 400;    // Faster slam down
  const slamHoldDuration = 1200;   // Hold slam a bit shorter
  const slamDurationUp = 600;      // Faster slam up
  const slamCooldown = 700;        // Faster cooldown between slams

  // Reduce lives should be defined globally / externally
  // This function just calls it
  function reduceLives() {
    if (lives > 0) {
      lives--;
      console.log("Player hit by boss slam! Lives Remaining:", lives);
      // Trigger additional feedback if needed
    }
  }

  function createBurst(x, y) {
    // Your burst effect implementation here
    console.log(`Burst at (${x}, ${y})`);
  }

  // Animate CSS bottom property with transition and Promise-based resolution
  function animateBottomPosition(targetBottom, duration) {
    return new Promise((resolve) => {
      let resolved = false;

      function onTransitionEnd(e) {
        if (e.propertyName === 'bottom' && !resolved) {
          resolved = true;
          boss.removeEventListener('transitionend', onTransitionEnd);
          resolve();
        }
      }

      boss.addEventListener('transitionend', onTransitionEnd);
      boss.style.transition = `bottom ${duration}ms ease-in-out`;
      boss.style.bottom = `${targetBottom}px`;

      // Safety fallback if transitionend does not fire
      setTimeout(() => {
        if (!resolved) {
          resolved = true;
          boss.removeEventListener('transitionend', onTransitionEnd);
          resolve();
        }
      }, duration + 50);
    });
  }

  // Get bounding rects for player, boss, and boss parent
  function getRects() {
    return {
      playerRect: player.getBoundingClientRect(),
      bossRect: boss.getBoundingClientRect(),
      parentRect: boss.parentElement.getBoundingClientRect()
    };
  }

  // Axis-aligned bounding box collision detection
  function isCollision(rect1, rect2) {
    return !(
      rect1.right < rect2.left ||
      rect1.left > rect2.right ||
      rect1.bottom < rect2.top ||
      rect1.top > rect2.bottom
    );
  }

  // Monitor collision during slam hold, damage max once per second
  function monitorCollisionDuringSlam(duration) {
    return new Promise((resolve) => {
      const hitCooldown = 1000; // ms between allowed hits
      let lastHitTimestamp = 0;
      const startTime = performance.now();

      function check(time) {
        if (time - startTime >= duration) {
          resolve();
          return;
        }

        const { playerRect, bossRect } = getRects();

        if (isCollision(playerRect, bossRect)) {
          if (time - lastHitTimestamp > hitCooldown && lives > 0) {
            reduceLives();
            lastHitTimestamp = time;
            shakeScreen(); // Assuming you defined shakeScreen globally
          }
        }

        if (lives <= 0) {
          resolve(); // Stop if no lives left
          return;
        }

        requestAnimationFrame(check);
      }

      requestAnimationFrame(check);
    });
  }

  async function performSlam() {
    let slamCount = 0;

    while (slamCount < maxSlams) {
      // Position boss instantly above player horizontally
      const { playerRect, parentRect } = getRects();
      const playerCenterX = playerRect.left - parentRect.left + playerRect.width / 2;

      boss.style.transition = 'none';
      boss.style.left = `${playerCenterX - boss.offsetWidth / 2}px`;
      boss.style.bottom = `${hoverHeight}px`;

      // Wait for next frame so changes apply
      await new Promise(resolve => requestAnimationFrame(resolve));

      // Shorter hover pause for snappier feel
      await new Promise(resolve => setTimeout(resolve, 300));

      shakeScreen();

      // Slam down
      await animateBottomPosition(groundLevel, slamDurationDown);

      createBurst(playerCenterX, groundLevel);

      // Hold slam while monitoring collision damage
      await monitorCollisionDuringSlam(slamHoldDuration);

      // Slam back up
      await animateBottomPosition(hoverHeight, slamDurationUp);

      slamCount++;

      // Cooldown before next slam
      await new Promise(resolve => setTimeout(resolve, slamCooldown));
    }

    console.log("Slam attack finished");

    if (typeof resetBossPosition === 'function') {
      resetBossPosition();
    }

    if (typeof cycleBossAttacks === 'function') {
      setTimeout(cycleBossAttacks, 5000); // Faster cycle after slam attack
    }
  }

  performSlam();
}

function bossPhaseTwoTargetSlam3() {
    let slamCount = 0;
    const maxSlams = 6;
    const groundLevel = 0;   
    const hoverHeight = 100; 
    const slamDurationDown = 200;
    const slamHoldDuration = 1000;
    const slamDurationUp = 700;
    const slamCooldown = 450;
    let slamActive = false;

    // assuming boss and player are defined globally or in the outer scope
    // e.g. const boss = document.getElementById('boss');
    // const player = document.getElementById('player');

    function sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    function monitorCollisionDuringSlam(duration) {
        const startTime = Date.now();
        let lastHitTime = 0;   // added to throttle reduceLives

        return new Promise((resolve) => {
            const interval = setInterval(() => {
                const now = Date.now();
                if (now - startTime >= duration) {
                    clearInterval(interval);
                    resolve();
                    return;
                }

                if (checkCollision(player, boss)) {
                    // Only reduce lives if at least 1000ms (1 second) passed since last hit
                    if (now - lastHitTime >= 1000) {
                        reduceLives();
                        console.log("Player hit by the boss slam! Lives Remaining: " + lives);
                        lastHitTime = now;
                    }
                }
            }, 50);
        });
    }

    function animateBottomPosition(targetBottom, duration) {
        return new Promise(resolve => {
            function onTransitionEnd(event) {
                if (event.propertyName === 'bottom') {
                    boss.removeEventListener('transitionend', onTransitionEnd);
                    resolve();
                }
            }
            boss.addEventListener('transitionend', onTransitionEnd);
            void boss.offsetWidth;
            boss.style.transition = `bottom ${duration}ms ease-in-out`;
            boss.style.bottom = `${targetBottom}px`;
        });
    }

    async function performSlam() {
        while (slamCount < maxSlams) {
            slamActive = true;

            const playerRect = player.getBoundingClientRect();
            const parentRect = boss.parentElement.getBoundingClientRect();

            const playerX = playerRect.left - parentRect.left + playerRect.width / 2;

            boss.style.transition = 'none';
            boss.style.left = `${playerX - boss.offsetWidth / 2}px`;
            boss.style.bottom = `${hoverHeight}px`;

            await sleep(250);

            shakeScreen();

            await animateBottomPosition(groundLevel, slamDurationDown);

            createBurst(playerX, groundLevel);

            await monitorCollisionDuringSlam(slamHoldDuration);

            await animateBottomPosition(hoverHeight, slamDurationUp);

            slamCount++;
            slamActive = false;

            await sleep(slamCooldown);
        }

        console.log('Slam attack finished');
        resetBossPosition();
        setTimeout(cycleBossAttacks, 10000);
    }

    performSlam();
}

function bossTargetSlam() {
    let slamCount = 0;
    const maxSlams = 4;
    const groundLevel = 0;   
    const hoverHeight = 100; 
    const slamDurationDown = 500;   
    const slamHoldDuration = 1500;  
    const slamDurationUp = 700;     
    const slamCooldown = 1000;      

    // Track if a slam is currently active
    let slamActive = false;

    // Promise-based sleep
    function sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    // Collision check: AABB rectangle intersection
    function checkCollision(elem1, elem2) {
        const r1 = elem1.getBoundingClientRect();
        const r2 = elem2.getBoundingClientRect();
        return !(
            r1.right < r2.left ||
            r1.left > r2.right ||
            r1.bottom < r2.top ||
            r1.top > r2.bottom
        );
    }

    // Placeholder for player's lives remaining, define accordingly
    let lives = 3;

    // Reduces player's lives safely
reduceLives();

    // Shake screen effect placeholder — implement your own or remove

shakeScreen();

    // Create burst effect placeholder — implement as needed
    function createBurst(x, y) {
        console.log(`Burst at (${x}, ${y})`);
    }

    // Animate bottom position with transition and Promise
    function animateBottomPosition(targetBottom, duration) {
        return new Promise(resolve => {
            function onTransitionEnd(event) {
                if (event.propertyName === 'bottom') {
                    boss.removeEventListener('transitionend', onTransitionEnd);
                    resolve();
                }
            }
            boss.addEventListener('transitionend', onTransitionEnd);

            // Force reflow to apply transition properly
            void boss.offsetWidth;

            boss.style.transition = `bottom ${duration}ms ease-in-out`;
            boss.style.bottom = `${targetBottom}px`;
        });
    }

    // Monitor collision during slamHoldDuration, but only reduce lives once per second max
    async function monitorCollisionDuringSlam(duration) {
        return new Promise((resolve) => {
            let lastHitTime = 0;

            const interval = setInterval(() => {
                const now = Date.now();

                if (now - lastHitTime >= 1000 && checkCollision(player, boss)) {
                    reduceLives();
                    lastHitTime = now;
                }

                if (now >= startTime + duration) {
                    clearInterval(interval);
                    resolve();
                }
            }, 50);

            const startTime = Date.now();
        });
    }

    async function performSlam() {
        while (slamCount < maxSlams) {
            slamActive = true;

            // Calculate player and boss parent positions to align boss over player horizontally
            const playerRect = player.getBoundingClientRect();
            const parentRect = boss.parentElement.getBoundingClientRect();

            // Player center X inside boss parent container
            const playerX = playerRect.left - parentRect.left + playerRect.width / 2;

            // Position boss instantly above player at hover height
            boss.style.transition = 'none';
            boss.style.left = `${playerX - boss.offsetWidth / 2}px`;
            boss.style.bottom = `${hoverHeight}px`;

            await sleep(500); // hover delay

            shakeScreen();

            // Slam down
            await animateBottomPosition(groundLevel, slamDurationDown);

            createBurst(playerX, groundLevel);

            // Check collision during slam hold, max once per 1000ms
            await monitorCollisionDuringSlam(slamHoldDuration);

            // Slam back up
            await animateBottomPosition(hoverHeight, slamDurationUp);

            slamCount++;
            slamActive = false;

            await sleep(slamCooldown);
        }

        console.log("Slam attack finished");
        if (typeof resetBossPosition === 'function') {
            resetBossPosition();
        }
        if (typeof cycleBossAttacks === 'function') {
            setTimeout(cycleBossAttacks, 10000);
        }
    }

    performSlam();
}







function bossPhaseTwoNewPower() {
    let bossSlideCount = 0; // Count how many times the boss has slid side to side
    const bossMaxSlides = 5; // Maximum number of slides
    let direction = 1; // 1 for right, -1 for left
    let canDamagePlayer = true; // Flag to control damage timing
    
    // Set the boss to ground level and an initial position
    boss.style.bottom = '0px'; // Set boss to ground level
    boss.style.left = '50px'; // Starting position; adjust as needed

    // Get the width of the game world for boundary checks
    const gameWorldWidth = gameWorld.offsetWidth;

    // Interval to move the boss
    const slideInterval = setInterval(() => {
        // Move the boss
        const currentLeft = parseInt(boss.style.left);
        const nextLeft = currentLeft + (4 * direction); // Move by 4 pixels

        // Check for wall collision
        if (nextLeft < 0 || nextLeft + boss.offsetWidth > gameWorldWidth) {
            direction *= -1; // Reverse direction upon hitting the wall
            bossSlideCount++; // Increment the slide count
            
            // Bounce back the boss a little to ensure it doesn't stay stuck
            boss.style.left = (currentLeft + (4 * direction)) + 'px'; // Adjust position slightly after collision
        } else {
            boss.style.left = nextLeft + 'px'; // Move the boss
        }

        // Check collision with the player
        if (checkCollision(boss, player)) {
            // Reduce lives every second when colliding
            if (canDamagePlayer) {
                reduceLives(); // Damage the player if they collide with the boss
                canDamagePlayer = false; // Prevent further damage until the cooldown
                setTimeout(() => {
                    canDamagePlayer = true; // Reset after 1 second
                }, 1000);
            }
        }

        // Stop sliding after the specified number of slides and trigger the next boss cycle
        if (bossSlideCount >= bossMaxSlides) {
            clearInterval(slideInterval); // Stop the sliding movement
            resetBossPosition();
            cycleBossAttacks(); // Call this function to start the next boss cycle
        }
    }, 3); // Faster interval for rapid movement
}


function bossPhaseTwoExplosionRain2() {
    const blockWidth = 30; // Width of the falling blocks
    const blockHeight = 10; // Height of the falling blocks
    const blockSpeed = 5; // Speed of block movement (pixels per frame)
    const blocks = []; // Array to hold active blocks
    const spawnInterval = 500; // Time between block spawns (in milliseconds)
    const duration = 15000; // Total duration of the attack (in milliseconds)
    const leftRightDuration = 5500; // Move blocks left/right for 3 seconds
    const upDownDuration = duration - leftRightDuration; // Then move blocks up/down for 7 seconds

    // Keep track of current phase
    let phase = 'leftRight'; // 'leftRight' or 'upDown'
    let phaseStartTime = performance.now();

    // Function to spawn a block for the left/right phase
    function spawnBlockLeftRight() {
        const block = document.createElement('div');
        block.classList.add('explosive-block');
        block.style.width = `${blockWidth}px`;
        block.style.height = `${blockHeight}px`;
        block.style.position = 'absolute';
        block.style.backgroundColor = 'red';

        // Spawn from left or right side randomly
        const fromLeft = Math.random() < 0.5;
        block.dataset.fromLeft = fromLeft; // Store direction in dataset

        // Set initial horizontal position (off screen)
        block.style.left = fromLeft ? `${-blockWidth}px` : `${window.innerWidth}px`;
        // Random vertical position on screen
        block.style.bottom = `${Math.random() * (window.innerHeight - blockHeight)}px`;
        document.body.appendChild(block);

        blocks.push(block);
    }

  window.startSandboxMode = function() {
    sandboxOverlay.style.display = 'flex';

    // Initialize interface state
    loadAllCssClasses();
    updateCharModInputs();
    updateCharMod2Inputs();
    updateMapModInput();
  };



    // Function to spawn a block for the up/down phase
    function spawnBlockUpDown() {
        const block = document.createElement('div');
        block.classList.add('explosive-block');
        block.style.width = `${blockWidth}px`;
        block.style.height = `${blockHeight}px`;
        block.style.position = 'absolute';
        block.style.backgroundColor = 'red';

        // Spawn from bottom or top randomly
        const fromBottom = Math.random() < 0.5;
        block.dataset.fromBottom = fromBottom;

        // Random horizontal position on the screen
        block.style.left = `${Math.random() * (window.innerWidth - blockWidth)}px`;
        // Initial vertical position (off screen)
        block.style.bottom = fromBottom ? `${-blockHeight}px` : `${window.innerHeight}px`;
        document.body.appendChild(block);

        blocks.push(block);
    }

    // Function to update/move the blocks based on current phase
    function updateBlocks() {
        for (let i = blocks.length - 1; i >= 0; i--) {
            const block = blocks[i];
            if (!document.body.contains(block)) { 
                // Remove any blocks that were removed from DOM
                blocks.splice(i, 1);
                continue;
            }

            if (phase === 'leftRight') {
                // Move horizontally toward center of screen
                let currentLeft = parseFloat(block.style.left);
                const moveDir = block.dataset.fromLeft === 'true' ? 1 : -1; // left->right is +1, right->left is -1
                const newLeft = currentLeft + (blockSpeed * moveDir);
                block.style.left = `${newLeft}px`;

                // If block moved completely off screen past opposite side, remove it
                if (moveDir === 1 && newLeft > window.innerWidth) {
                    block.remove();
                    blocks.splice(i, 1);
                    continue;
                }
                if (moveDir === -1 && newLeft < -blockWidth) {
                    block.remove();
                    blocks.splice(i, 1);
                    continue;
                }
            } else if (phase === 'upDown') {
                // Move blocks vertically up or down
                let currentBottom = parseFloat(block.style.bottom);
                const moveDir = block.dataset.fromBottom === 'true' ? 1 : -1; // bottom->top = +1, top->bottom = -1
                const newBottom = currentBottom + (blockSpeed * moveDir);
                block.style.bottom = `${newBottom}px`;

                // Remove if off screen vertically
                if (moveDir === 1 && newBottom > window.innerHeight) {
                    block.remove();
                    blocks.splice(i, 1);
                    continue;
                }
                if (moveDir === -1 && newBottom < -blockHeight) {
                    block.remove();
                    blocks.splice(i, 1);
                    continue;
                }
            }

            // Check collision with player (assuming player is accessible globally)
            if (checkCollision(player, block)) {
                reduceLives();
                block.remove();
                blocks.splice(i, 1);
            }
        }
    }

    // Interval to spawn blocks depending on the phase
    let spawnBlocksInterval = setInterval(() => {
        if (phase === 'leftRight') {
            spawnBlockLeftRight();
        } else if (phase === 'upDown') {
            spawnBlockUpDown();
        }
    }, spawnInterval);

    // Animation frame loop to move blocks
    function animationLoop() {
        const now = performance.now();

        // Switch phase after respective time
        if (phase === 'leftRight' && now - phaseStartTime >= leftRightDuration) {
            phase = 'upDown';
            phaseStartTime = now;

            // Remove all existing blocks from leftRight phase immediately
            blocks.forEach(block => block.remove());
            blocks.length = 0;
        } else if (phase === 'upDown' && now - phaseStartTime >= upDownDuration) {
            // End attack and clean up
            clearInterval(spawnBlocksInterval);
            blocks.forEach(block => block.remove());
            blocks.length = 0;
            cycleBossAttacks();
            return; // Stop the animation loop
        }

        updateBlocks();
        requestAnimationFrame(animationLoop);
    }

    requestAnimationFrame(animationLoop);
}



function spawnBoostDrainer() {
    if (boostDrainer) return;

    const spawnX = gameScrollPosition + gameContainer.offsetWidth + 50;
    const spawnY = Math.random() * 200 + 50;

    boostDrainer = document.createElement('div');
    boostDrainer.classList.add('boost-drainer');
    boostDrainer.style.left = spawnX + 'px';
    boostDrainer.style.bottom = spawnY + 'px';
    gameWorld.appendChild(boostDrainer);

    // Create chain element
    boostDrainerChain = document.createElement('div');
    boostDrainerChain.classList.add('boost-drainer-chain');
    gameWorld.appendChild(boostDrainerChain);

    boostDrainerHP = 3;
    boostDrainerState = "moving"; // Start moving state
}

// Call this inside your main game loop or movement update function
function updateBoostDrainer() {
    if (!boostDrainer) return;

    const playerX = playerPositionX;
    let enemyX = parseInt(boostDrainer.style.left);

    switch (boostDrainerState) {
        case 'moving':
            const targetX = playerX + boostDrainerAttackXOffset;

            if (enemyX > targetX) {
                enemyX -= boostDrainerSpeed;
                boostDrainer.style.left = enemyX + 'px';
            } else {
                // Reached attack position, start attack cycle
                boostDrainerState = 'green';
                boostDrainer.style.backgroundColor = 'green'; // Visual green state
                boostDrainer.classList.remove('yellow', 'red');

                boostDrainerAttackTimeout = setTimeout(() => {
                    boostDrainerState = 'yellow';
                    boostDrainer.style.backgroundColor = 'yellow';
                    boostDrainer.classList.add('yellow');
                    
                    boostDrainerAttackTimeout = setTimeout(() => {
                        boostDrainerState = 'red';
                        boostDrainer.style.backgroundColor = 'red';
                        boostDrainer.classList.remove('yellow');
                        boostDrainer.classList.add('red');

                        fireBoostDrainerLaser(3); // Repeat laser fire 3 times
                    }, 1000);
                }, 1000);
            }
            break;
        // other states can be no movement
        default:
            break;
    }

    // Update the chain line only when moving or in states where player and drainer exist
    if (boostDrainerChain) {
        updateChainLine(boostDrainer, boostDrainerChain, player);
    }
}

function fireBoostDrainerLaser(timesLeft) {
    if (!boostDrainer || timesLeft <= 0) {
        removeBoostDrainer();
        return;
    }

    boostDrainerState = 'firing';

    // Create laser div or reuse existing laser if you want smooth transition
    if (boostDrainerLaser) {
        boostDrainerLaser.remove();
        boostDrainerLaser = null;
    }

    boostDrainerLaser = document.createElement('div');
    boostDrainerLaser.classList.add('boost-laser');

    const left = parseInt(boostDrainer.style.left) + boostDrainer.offsetWidth / 2 - 2; 
    boostDrainerLaser.style.left = left + 'px';
    boostDrainerLaser.style.bottom = '0px';
    
    // Laser height can be fixed or adjusted dynamically
    boostDrainerLaser.style.height = '120px';

    gameWorld.appendChild(boostDrainerLaser);

    // Laser stays visible for 0.75s, then disappear, and wait 0.5s before next fire
    setTimeout(() => {
        if(boostDrainerLaser) {
            boostDrainerLaser.remove();
            boostDrainerLaser = null;
        }
        boostDrainerState = 'red'; // Can reset state or handle as needed
        
        setTimeout(() => {
            fireBoostDrainerLaser(timesLeft -1);
        }, 500);
    }, 750);
}

// Update the dotted chain line between two elements
function updateChainLine(fromEl, lineEl, toEl) {
    if (!fromEl || !lineEl || !toEl) return;

    // Get bounding rectangles
    const fromRect = fromEl.getBoundingClientRect();
    const toRect = toEl.getBoundingClientRect();
    const containerRect = gameWorld.getBoundingClientRect();

    // Calculate center point within gameWorld coordinates
    // relative to gameWorld's top-left corner BUT we position absolute with bottom coordinate,
    // so invert Y relative to container
    function centerX(rect) {
        return rect.left - containerRect.left + rect.width / 2;
    }
    function centerYBottom(rect) {
        // bottom coordinate = container height - (rect.top - container top + half height)
        return gameContainer.offsetHeight - (rect.top - containerRect.top + rect.height / 2);
    }

    const x1 = centerX(fromRect);
    const y1 = centerYBottom(fromRect);
    const x2 = centerX(toRect);
    const y2 = centerYBottom(toRect);

    const dx = x2 - x1;
    const dy = y2 - y1;

    const length = Math.sqrt(dx * dx + dy * dy);
    const angle = Math.atan2(dy, dx) * 180 / Math.PI;

    // Adjust the dotted line style here for better positioning
    lineEl.style.width = length + 'px';
    lineEl.style.left = x1 + 'px';
    lineEl.style.bottom = y1 + 'px';
    lineEl.style.transformOrigin = 'left center';
    lineEl.style.transform = `rotate(${angle}deg)`;
}

// Handle when bullet hits the boost drainer
function handleBoostDrainerHit(bulletObj, bulletIndex) {
    if (!boostDrainer) return false;
    if (!checkCollision(bulletObj.element, boostDrainer)) return false;

    // Remove bullet
    bulletObj.element.remove();
    bullets.splice(bulletIndex, 1);

    // Reduce HP
    boostDrainerHP--;
    // Flash
    boostDrainer.style.opacity = '0.5';
    setTimeout(() => {
        if (boostDrainer) boostDrainer.style.opacity = '1';
    }, 150);

    // If dead, remove
    if (boostDrainerHP <= 0) {
        removeBoostDrainer();
    }

    return true; // bullet handled
}

// Remove drainer and chain line cleanup
function removeBoostDrainer() {
    if (boostDrainer) {
        boostDrainer.remove();
        boostDrainer = null;
    }
    if (boostDrainerChain) {
        boostDrainerChain.remove();
        boostDrainerChain = null;
    }
    if (boostDrainerLaser) {
        boostDrainerLaser.remove();
        boostDrainerLaser = null;
    }
    if (boostDrainerAttackTimeout) {
        clearTimeout(boostDrainerAttackTimeout);
        boostDrainerAttackTimeout = null;
    }
    boostDrainerHP = 0;
    boostDrainerState = "dead";
}

function checkBoostDrainerLaserCollision() {
    if (!boostDrainerLaser) return;

    if (checkCollision(player, boostDrainerLaser)) {
        // Hit by laser — destroy enemy & reduce lives
        removeBoostDrainer();
        reduceLives();
    }
}


function bossPhaseTwoExplosionRain() {
    const blockWidth = 30; // Width of the falling blocks
    const blockHeight = 10; // Height of the falling blocks
    const blockSpeed = 5; // Speed of block movement
    const blocks = []; // Array to hold active blocks
    const spawnInterval = 500; // Time between block spawns (in milliseconds)
    const duration = 10000; // Duration of the attack (in milliseconds)

    // Function to create and spawn blocks
    function spawnBlock() {
        const block = document.createElement('div');
        block.classList.add('explosive-block'); // Add a class for styling
        block.style.width = `${blockWidth}px`;
        block.style.height = `${blockHeight}px`;
        block.style.position = 'absolute';
        block.style.backgroundColor = 'red';

        // Determine random left or right spawn position (off screen)
        const side = Math.random() < 0.5 ? -blockWidth : window.innerWidth; 
        block.style.left = side < 0 ? `${side}px` : `${side - blockWidth}px`;
        block.style.bottom = `${Math.random() * window.innerHeight}px`; // Random vertical position
        document.body.appendChild(block);

        // Move block across the screen
        const moveInterval = setInterval(() => {
            const currentLeft = parseInt(block.style.left);
            block.style.left = `${currentLeft + (side < 0 ? blockSpeed : -blockSpeed)}px`; // Move toward center

            // Check if the block is out of bounds
            if (currentLeft < -blockWidth || currentLeft > window.innerWidth) {
                clearInterval(moveInterval); // Stop moving if out of bounds
                block.remove(); // Remove block from DOM
            }

            // Check collision with player
            if (checkCollision(player, block)) {
                reduceLives(); // Reduce player's lives
                block.remove(); // Remove block on collision
                clearInterval(moveInterval); // Stop moving
            }
        }, 1000 / 60); // Move at 60 FPS
        blocks.push(block); // Add the block to the list of active blocks
    }

    // Start spawning blocks
    const spawnBlocksInterval = setInterval(spawnBlock, spawnInterval);

    // Stop spawning after the specified duration and clean up
    setTimeout(() => {
        clearInterval(spawnBlocksInterval);
        blocks.forEach(block => block.remove()); // Remove remaining blocks
        cycleBossAttacks(); // Move to next boss attack cycle
    }, duration);
}

function eded() {
  // === Config ===
  const CONFIG = {
    blockWidth: 80,
    blockHeight: 20,
    obstacleWidth: 40,
    obstacleHeight: 20,
    lavaRiseSpeed: 1,          // pixels per tick
    lavaRiseInterval: 100,     // ms
    phaseLavaHeight: 100,      // lava height per phase
    totalPhases: 3,
    damageCooldown: 1000       // ms cooldown between damage ticks
  };

  // === State ===
  let currentPhase = 0;
  let lavaHeight = 0;
  let lavaIntervalId = null;
  let lastDamageTime = 0;

  // Spawned elements tracking (for cleanup)
  const blocks = [];
  const obstacles = [];

  // Assumes global DOM references:
  // - gameWorld: container element for gameplay (should be position: relative or absolute)
  // - player: player character element
  // - reduceLives(): function that reduces player lives
  // - cycleBossAttacks(): function that triggers after phase completes

  // === Helper: checkCollision ===
  // Simple AABB collision between two elements using getBoundingClientRect

  // === Helper: getPlayerBottomOffset ===
  // Distance in pixels from player's bottom edge to bottom of the game world container.
  function getPlayerBottomOffset() {
    const playerRect = player.getBoundingClientRect();
    const worldRect = gameWorld.getBoundingClientRect();
    return worldRect.bottom - playerRect.bottom; // positive means above bottom
  }

  // === Spawn functions ===
  function createBlock(x) {
    const block = document.createElement('div');
    block.className = 'block';
    Object.assign(block.style, {
      position: 'absolute',
      width: CONFIG.blockWidth + 'px',
      height: CONFIG.blockHeight + 'px',
      backgroundColor: 'blue',
      left: x + 'px',
      bottom: '0',
      zIndex: '10',
    });
    gameWorld.appendChild(block);
    blocks.push(block);
    return block;
  }

  function createObstacle(x) {
    const obstacle = document.createElement('div');
    obstacle.className = 'obstacle';
    Object.assign(obstacle.style, {
      position: 'absolute',
      width: CONFIG.obstacleWidth + 'px',
      height: CONFIG.obstacleHeight + 'px',
      backgroundColor: 'orange',
      left: x + 'px',
      bottom: '0',
      zIndex: '10',
    });
    gameWorld.appendChild(obstacle);
    obstacles.push(obstacle);
    return obstacle;
  }

  // === Spawning initial fixed blocks ===
  function spawnInitialBlocks() {
    [100, 300, 500].forEach(xPos => createBlock(xPos));
  }

  // === Spawning obstacles per phase ===
  function spawnPhaseObstacles() {
    // Could vary per phase dynamically, for now fixed positions
    [150, 350, 550].forEach(xPos => createObstacle(xPos));
  }

  // === Cleanup elements ===
  function cleanupElements() {
    blocks.forEach(b => b.remove());
    obstacles.forEach(o => o.remove());
    blocks.length = 0;
    obstacles.length = 0;

    // Remove lava if any
    const existingLava = gameWorld.querySelector('.lava');
    if (existingLava) existingLava.remove();
  }

  // === Create lava element ===
  function createLava() {
    const lava = document.createElement('div');
    lava.className = 'lava';
    Object.assign(lava.style, {
      position: 'absolute',
      width: '100%',
      height: '0',
      bottom: '0',
      backgroundColor: 'red',
      zIndex: '5',
      transition: 'height 0.1s linear', // smooth growth per interval
    });
    gameWorld.appendChild(lava);
    return lava;
  }

  // === Damage player if touching lava with cooldown ===
  function tryDamagePlayer() {
    const now = Date.now();
    if (now - lastDamageTime < CONFIG.damageCooldown) return; // cooldown active

    if (checkCollision(player, lavaElement)) {
      const playerBottomDist = getPlayerBottomOffset();
      if (playerBottomDist < lavaHeight) {
        reduceLives();
        lastDamageTime = now;
      }
    }
  }

  

  // === Lava rise tick ===
  function onLavaRise() {
    lavaHeight += CONFIG.lavaRiseSpeed;
    lavaElement.style.height = lavaHeight + 'px';

    tryDamagePlayer();

    // Check if current phase lava fully raised
    if (lavaHeight >= (currentPhase + 1) * CONFIG.phaseLavaHeight) {
      clearInterval(lavaIntervalId);
      lavaIntervalId = null;
      currentPhase++;

      if (currentPhase < CONFIG.totalPhases) {
        // Spawn obstacles for next phase
        spawnPhaseObstacles();

        // Reset lava after short delay for player repositioning
        setTimeout(() => {
          lavaHeight = 0;
          lavaElement.style.height = '0px';
          lavaIntervalId = setInterval(onLavaRise, CONFIG.lavaRiseInterval);
        }, 1000);

      } else {
        // Final phase complete, proceed to next boss phase or attacks
        cycleBossAttacks();
      }
    }
  }

  // === Start phase 5 ===
  function startPhase() {
    cleanupElements();

    // Spawn blocks and initial obstacles
    spawnInitialBlocks();
    spawnPhaseObstacles();

    // Create lava element fresh
    lavaElement = createLava();

    // Reset state
    lavaHeight = 0;
    currentPhase = 0;
    lastDamageTime = 0;

    // Start lava rising loop
    lavaIntervalId = setInterval(onLavaRise, CONFIG.lavaRiseInterval);
  }

  // Launch phase 5
  let lavaElement; // define lavaElement here to be accessible in nested functions
  startPhase();
}


function bossPhaseTwoTargetSlam() {
    let slamCount = 0;
    const maxSlams = 4;
    const groundLevel = 0;   
    const hoverHeight = 100; 
    const slamDurationDown = 500;   
    const slamHoldDuration = 1500;  
    const slamDurationUp = 700;     
    const slamCooldown = 1000;      

    // Track if a slam is currently active
    let slamActive = false;

    // Promise-based sleep
    function sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    // Collision check: AABB rectangle intersection
    function checkCollision(elem1, elem2) {
        const r1 = elem1.getBoundingClientRect();
        const r2 = elem2.getBoundingClientRect();
        return !(
            r1.right < r2.left ||
            r1.left > r2.right ||
            r1.bottom < r2.top ||
            r1.top > r2.bottom
        );
    }

    // Placeholder for player's lives remaining, define accordingly
    let lives = 3;

    // Reduces player's lives safely
    function reduceLives() {
        if (lives > 0) {
            lives--;
            console.log("Player hit by boss slam! Lives Remaining:", lives);
        }
    }

    // Shake screen effect placeholder — implement your own or remove
    function shakeScreen() {
        // Example simple console log
        console.log("Screen shakes!");
    }

    // Create burst effect placeholder — implement as needed
    function createBurst(x, y) {
        console.log(`Burst at (${x}, ${y})`);
    }

    // Animate bottom position with transition and Promise
    function animateBottomPosition(targetBottom, duration) {
        return new Promise(resolve => {
            function onTransitionEnd(event) {
                if (event.propertyName === 'bottom') {
                    boss.removeEventListener('transitionend', onTransitionEnd);
                    resolve();
                }
            }
            boss.addEventListener('transitionend', onTransitionEnd);

            // Force reflow to apply transition properly
            void boss.offsetWidth;

            boss.style.transition = `bottom ${duration}ms ease-in-out`;
            boss.style.bottom = `${targetBottom}px`;
        });
    }

    // Monitor collision during slamHoldDuration, but only reduce lives once per second max
    async function monitorCollisionDuringSlam(duration) {
        return new Promise((resolve) => {
            let lastHitTime = 0;

            const interval = setInterval(() => {
                const now = Date.now();

                if (now - lastHitTime >= 1000 && checkCollision(player, boss)) {
                    reduceLives();
                    lastHitTime = now;
                }

                if (now >= startTime + duration) {
                    clearInterval(interval);
                    resolve();
                }
            }, 50);

            const startTime = Date.now();
        });
    }

    async function performSlam() {
        while (slamCount < maxSlams) {
            slamActive = true;

            // Calculate player and boss parent positions to align boss over player horizontally
            const playerRect = player.getBoundingClientRect();
            const parentRect = boss.parentElement.getBoundingClientRect();

            // Player center X inside boss parent container
            const playerX = playerRect.left - parentRect.left + playerRect.width / 2;

            // Position boss instantly above player at hover height
            boss.style.transition = 'none';
            boss.style.left = `${playerX - boss.offsetWidth / 2}px`;
            boss.style.bottom = `${hoverHeight}px`;

            await sleep(500); // hover delay

            shakeScreen();

            // Slam down
            await animateBottomPosition(groundLevel, slamDurationDown);

            createBurst(playerX, groundLevel);

            // Check collision during slam hold, max once per 1000ms
            await monitorCollisionDuringSlam(slamHoldDuration);

            // Slam back up
            await animateBottomPosition(hoverHeight, slamDurationUp);

            slamCount++;
            slamActive = false;

            await sleep(slamCooldown);
        }

        console.log("Slam attack finished");
        if (typeof resetBossPosition === 'function') {
            resetBossPosition();
        }
        if (typeof cycleBossAttacks === 'function') {
            setTimeout(cycleBossAttacks, 10000);
        }
    }

    performSlam();
}

// Function to shake the screen
function shakeScreen() {
    let shakeEffect = document.createElement('div');
    shakeEffect.style.position = "fixed";
    shakeEffect.style.top = "0";
    shakeEffect.style.left = "0";
    shakeEffect.style.width = "100%";
    shakeEffect.style.height = "100%";
    shakeEffect.style.backgroundColor = "rgba(255, 0, 0, 0.5)"; // Flashing effect
    shakeEffect.style.transition = 'transform 0.1s';
    document.body.appendChild(shakeEffect);

    // Shake effect
    const shakeTimes = 15; // Number of shakes
    const shakeDistance = 40; // Distance to shake
    const shakeInterval = 50; // Time between shakes

    for(let i = 0; i < shakeTimes; i++) {
        setTimeout(() => {
            shakeEffect.style.transform = (i % 2 === 0) ? `translateX(-${shakeDistance}px)` : `translateX(${shakeDistance}px)`;
        }, i * shakeInterval);
    }

    // Reset the screen after shaking
    setTimeout(() => {
        shakeEffect.style.transform = 'translateX(0)';
    }, shakeTimes * shakeInterval);

    setTimeout(() => {
        shakeEffect.remove(); // Clean up the shake effect
    }, shakeTimes * shakeInterval + 100); // Ensure it removes after the reset
}

// Function to reset the boss position to the center of the screen
function resetBossPosition() {
    boss.style.left = (gameContainer.offsetWidth / 2 - boss.offsetWidth / 2) + 'px'; // Center the boss
    boss.style.bottom = "100px"; // Reset position
}
 
 


function bossPhaseTwoBarrage() {
    boss.style.animation = "boss-shake 1s infinite alternate"; // Boss shakes

    let spawnCount = 0;
    let spawnInterval = setInterval(() => {
        if (spawnCount >= 15) { // Stops after 10 spawns
            clearInterval(spawnInterval);
            boss.style.animation = ""; // Stop shaking
            setTimeout(cycleBossAttacks, 3000); // Cooldown before next attack
            return;
        }

        let enemy = createElement('enemy', enemies, Math.random() * gameContainer.offsetWidth);
        enemy.style.bottom = "400px"; // Start from top

        let fallSpeed = 12;
        let fallInterval = setInterval(() => {
            enemy.style.bottom = (parseInt(enemy.style.bottom) - fallSpeed) + "px";

            if (parseInt(enemy.style.bottom) <= 0) {
                enemy.style.bottom = "0px"; // Stop at ground level
                clearInterval(fallInterval);
            }

            // Check for collision with player
            if (checkCollision(player, enemy)) {
                reduceLives();
                enemy.remove();
                clearInterval(fallInterval);
            }
        }, 50);

        spawnCount++;
    }, 500); // Spawn every half second
}
 
function bossEnemyBarrage() {
    boss.style.animation = "boss-shake 1s infinite alternate"; // Boss shakes

    let spawnCount = 0;
    let spawnInterval = setInterval(() => {
        if (spawnCount >= 10) { // Stops after 10 spawns
            clearInterval(spawnInterval);
            boss.style.animation = ""; // Stop shaking
            setTimeout(cycleBossAttacks, 3000); // Cooldown before next attack
            return;
        }

        let enemy = createElement('enemy', enemies, Math.random() * gameContainer.offsetWidth);
        enemy.style.bottom = "400px"; // Start from top

        let fallSpeed = 8;
        let fallInterval = setInterval(() => {
            enemy.style.bottom = (parseInt(enemy.style.bottom) - fallSpeed) + "px";

            if (parseInt(enemy.style.bottom) <= 0) {
                enemy.style.bottom = "0px"; // Stop at ground level
                clearInterval(fallInterval);
            }

            // Check for collision with player
            if (checkCollision(player, enemy)) {
                reduceLives();
                enemy.remove();
                clearInterval(fallInterval);
            }
        }, 50);

        spawnCount++;
    }, 500); // Spawn every half second
}
 
 
 
function bossPhaseTwoTargetSlam() {
  const maxSlams = 4;
  const groundLevel = 0;
  const hoverHeight = 100;
  const slamDurationDown = 400;    // Faster slam down
  const slamHoldDuration = 1200;   // Hold slam a bit shorter
  const slamDurationUp = 600;      // Faster slam up
  const slamCooldown = 700;        // Faster cooldown between slams

  // Track if slam is active to avoid overlapping slams
  let slamCount = 0;

  // Player lives placeholder (should come from your global game state)
  // Consider passing lives as param or referencing global store instead

  function reduceLives() {
    if (lives > 0) {
      lives--;
      console.log("Player hit by boss slam! Lives Remaining:", lives);
      // TODO: Trigger player hit animation / feedback here
    }
  }


  // Use Promises to handle CSS transitions cleanly
  function animateBottomPosition(targetBottom, duration) {
    return new Promise((resolve) => {
      let resolved = false;
      
      function onTransitionEnd(e) {
        if (e.propertyName === 'bottom' && !resolved) {
          resolved = true;
          boss.removeEventListener('transitionend', onTransitionEnd);
          resolve();
        }
      }
      
      boss.addEventListener('transitionend', onTransitionEnd);

      // Apply CSS transition
      boss.style.transition = `bottom ${duration}ms ease-in-out`;
      boss.style.bottom = `${targetBottom}px`;

      // Safety fallback in case transitionend doesn't fire:
      setTimeout(() => {
        if (!resolved) {
          resolved = true;
          boss.removeEventListener('transitionend', onTransitionEnd);
          resolve();
        }
      }, duration + 50);
    });
  }

  // Helper to get player and boss rectangles
  function getRects() {
    return {
      playerRect: player.getBoundingClientRect(),
      bossRect: boss.getBoundingClientRect(),
      parentRect: boss.parentElement.getBoundingClientRect()
    };
  }

  // Check AABB collision between two DOMRect objects
  function isCollision(rect1, rect2) {
    return !(
      rect1.right < rect2.left ||
      rect1.left > rect2.right ||
      rect1.bottom < rect2.top ||
      rect1.top > rect2.bottom
    );
  }

  // Smoothly monitor collision during hold using requestAnimationFrame for fast, real-time checks
 function monitorCollisionDuringSlam(duration) {
  return new Promise((resolve) => {
    const hitCooldown = 1000; // ms between allowed hits
    let lastHitTimestamp = 0;
    const startTime = performance.now();

    function check(time) {
      if (time - startTime >= duration) {
        resolve();
        return;
      }

      const { playerRect, bossRect } = getRects();

      if (isCollision(playerRect, bossRect)) {
        if (time - lastHitTimestamp > hitCooldown && lives > 0) {
          reduceLives();
          lastHitTimestamp = time;
          shakeScreen();
        }
      }

      if (lives <= 0) {
        resolve(); // Stop checking if player dead or no lives left
        return;
      }

      requestAnimationFrame(check);
    }

    requestAnimationFrame(check);
  });
}

  async function performSlam() {
    slamCount = 0;

    while (slamCount < maxSlams) {
      // Position boss above player horizontally, instantly (no transition)
      const { playerRect, parentRect } = getRects();
      const playerCenterX = playerRect.left - parentRect.left + playerRect.width / 2;
      boss.style.transition = 'none';  // Remove transition for instant move
      boss.style.left = `${playerCenterX - boss.offsetWidth / 2}px`;
      boss.style.bottom = `${hoverHeight}px`;

      // Let rendering catch up (a frame or short delay)
      await new Promise(resolve => requestAnimationFrame(resolve));

      await new Promise(resolve => setTimeout(resolve, 300)); // small hover pause, quicker than before

      shakeScreen();

      // Slam down animation
      await animateBottomPosition(groundLevel, slamDurationDown);

      createBurst(playerCenterX, groundLevel);

      // Hold slammed position while checking collision multiple times a second, respond quick but not too spammy
      await monitorCollisionDuringSlam(slamHoldDuration);

      // Slam back up
      await animateBottomPosition(hoverHeight, slamDurationUp);

      slamCount++;

      // Cooldown between slams
      await new Promise(resolve => setTimeout(resolve, slamCooldown));
    }

    console.log("Slam attack finished");

    // Reset boss position or continue attack cycles
    if (typeof resetBossPosition === 'function') {
      resetBossPosition();
    }
    if (typeof cycleBossAttacks === 'function') {
      // Reduced delay to chain attacks faster
      setTimeout(cycleBossAttacks, 5000);
    }
  }

  performSlam();
}
 
function bossExplosionRain() {
    boss.style.animation = "boss-shake 1s infinite alternate";

    let dropCount = 0;
    let dropInterval = setInterval(() => {
        if (dropCount >= 10) {
            clearInterval(dropInterval);
            boss.style.animation = "";
            setTimeout(cycleBossAttacks, 3000); // Cooldown before next attack
            return;
        }

        // Randomize the X position based on the player's position
        let playerPositionX = parseInt(player.style.left);
        let explosionBlock = document.createElement('div'); // Corrected to use document.createElement
        explosionBlock.classList.add('explosive-block'); // Add a class if you want to style it later
        explosionBlock.style.position = "absolute"; // Important for positioning
        explosionBlock.style.left = (playerPositionX + Math.random() * 30 - 15) + "px"; // Randomize the horizontal position
        explosionBlock.style.bottom = "400px"; // Start high
        explosionBlock.style.width = "30px"; // Width of the falling block
        explosionBlock.style.height = "10px"; // Height of the falling block
        explosionBlock.style.backgroundColor = "red"; // Color of the falling block
        gameWorld.appendChild(explosionBlock);

        let fallSpeed = 5; // Speed of fall
        let fallInterval = setInterval(() => {
            explosionBlock.style.bottom = (parseInt(explosionBlock.style.bottom) - fallSpeed) + "px";

            if (parseInt(explosionBlock.style.bottom) <= 0) {
                createBurst(parseInt(explosionBlock.style.left), 0); // Create burst effect
                if (checkCollision(explosionBlock, player)) {
                    reduceLives(); // Reduce lives if hit
                }
                explosionBlock.remove(); // Remove block once it hits ground
                clearInterval(fallInterval);
            }
        }, 50); // Update every 50ms

        dropCount++;
    }, 1000); // Drop every second
}


class Laser {
    constructor(x, y, direction, length) {
        this.x = x;
        this.y = y;
        this.direction = direction;  // 'vertical' or 'horizontal'
        this.length = length;
        this.element = null;
    }

    createElement() {
        this.element = document.createElement('div');
        this.element.style.position = 'absolute';
        this.element.style.backgroundColor = 'yellow';
        if (this.direction === 'vertical') {
            this.element.style.width = '4px';
            this.element.style.height = this.length + 'px';
            this.element.style.left = this.x + 'px';
            this.element.style.bottom = this.y + 'px';
        } else {
            this.element.style.height = '4px';
            this.element.style.width = this.length + 'px';
            this.element.style.left = this.x + 'px';
            this.element.style.bottom = this.y + 'px';
        }
        this.element.style.opacity = '0.8';
        this.element.style.zIndex = '1000';
        this.element.classList.add('laser-beam');
        document.getElementById('game-world').appendChild(this.element);
    }

    activate() {
        // Make laser red and fully opaque when activated
        if (!this.element) return;
        this.element.style.backgroundColor = 'red';
        this.element.style.opacity = '1';
    }

    remove() {
        if (this.element && this.element.parentElement) {
            this.element.parentElement.removeChild(this.element);
            this.element = null;
        }
    }

    getBoundingRect() {
        return this.element.getBoundingClientRect();
    }
}

function isPlayerOnLaser(laser) {
    if (!laser.element) return false;
    const playerRect = player.getBoundingClientRect();
    const laserRect = laser.getBoundingRect();

    return !(
        playerRect.right < laserRect.left ||
        playerRect.left > laserRect.right ||
        playerRect.bottom < laserRect.top ||
        playerRect.top > laserRect.bottom
    );
}

// Main laser phase boss move function - call it with await in your attack cycle
async function laserPhaseMove() {
    displayMessage("Dodge the lasers!", 2);
    await sleep(2000); // Wait for player to read the message

    const repeats = 4;
    const gameWorld = document.getElementById('game-world');
    const gameBounds = gameWorld.getBoundingClientRect();

    for (let round = 0; round < repeats; round++) {
        // Spawn lasers
        const lasers = [];

        // Number of lasers per round (can tweak for difficulty)
        const lasersCount = 5;

        for (let i = 0; i < lasersCount; i++) {
            const vertical = Math.random() < 0.5;

            if (vertical) {
                // Random X inside game world boundaries
                const xPos = Math.random() * gameBounds.width;
                // Y set to bottom of game world container - zero
                lasers.push(new Laser(xPos, 0, 'vertical', gameBounds.height));
            } else {
                // Random Y inside game world height
                const yPos = Math.random() * gameBounds.height;
                // X at left edge = 0
                lasers.push(new Laser(0, yPos, 'horizontal', gameBounds.width));
            }
        }

        // Create laser elements in DOM with warning color (yellow)
        lasers.forEach(laser => laser.createElement());

        // Warn lasers blinking: toggle opacity several times for 1 second
        const warningDurationMs = 1000;
        const blinkIntervalMs = 200;
        const blinkCount = warningDurationMs / blinkIntervalMs;
        for (let b = 0; b < blinkCount; b++) {
            lasers.forEach(laser => {
                if (!laser.element) return;
                laser.element.style.opacity = (b % 2 === 0) ? '0.3' : '0.8';
            });
            await sleep(blinkIntervalMs);
        }

        // Set lasers fully visible and red (active)
        lasers.forEach(laser => laser.activate());

        // Damage phase: 2 seconds, check collisions every 100ms
        const damageDurationMs = 2000;
        const damageCheckIntervalMs = 100;
        let elapsed = 0;

        while (elapsed < damageDurationMs) {
            lasers.forEach(laser => {
                if (isPlayerOnLaser(laser)) {
                    lives = Math.max(0, lives - 1);
                    displayMessage(`Hit! Lives: ${lives}`, 1);

                    // TODO: Add your death/game over logic here if lives <= 0
                }
            });
            await sleep(damageCheckIntervalMs);
            elapsed += damageCheckIntervalMs;
        }

        // Remove all lasers from DOM and clear array
        lasers.forEach(laser => laser.remove());
        lasers.length = 0;

        // Short delay before next round
        await sleep(500);
    }

    displayMessage("Laser phase complete!", 2);
    await sleep(2000);

    cycleBossAttacks();
}

// Helper sleep function (if not defined)

function getRandomSpawnCount(min = 1, max = 5) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

async function bossPhaseFiveAttackA() {
    displayMessage("Trial 1", 3);
    await sleep(3000);

    const totalDuration = 25000; // 25 seconds
    const spawnInterval = 500;

    const intervalId = setInterval(() => {
        let count;

        count = getRandomSpawnCount();
        for (let i = 0; i < count; i++) spawnEnemy();

        count = getRandomSpawnCount();
        for (let i = 0; i < count; i++) spawnFlyingEnemy();

        count = getRandomSpawnCount();
        for (let i = 0; i < count; i++) spawnObstacle();
    }, spawnInterval);

    await new Promise(resolve => {
        setTimeout(() => {
            clearInterval(intervalId);
            resolve();
        }, totalDuration);
    });

    await cycleBossAttacks();
}

async function bossPhaseFiveAttackB() {
    displayMessage("Trial 2", 3);
    await sleep(3000);

    const totalDuration = 25000;
    const spawnInterval = 600;

    const intervalId = setInterval(() => {
        let count;

        count = getRandomSpawnCount();
        for (let i = 0; i < count; i++) spawnEnemy();

        count = getRandomSpawnCount();
        for (let i = 0; i < count; i++) spawnChargingEnemy();

        count = getRandomSpawnCount();
        for (let i = 0; i < count; i++) spawnSniperEnemy();
    }, spawnInterval);

    await new Promise(resolve => {
        setTimeout(() => {
            clearInterval(intervalId);
            resolve();
        }, totalDuration);
    });

    await cycleBossAttacks();
}

async function bossPhaseFiveAttackC() {
    displayMessage("Trial 3", 3);
    await sleep(3000);

    const totalDuration = 25000;
    const spawnInterval = 550;

    const intervalId = setInterval(() => {
        let count;

        count = getRandomSpawnCount();
        for (let i = 0; i < count; i++) spawnEnemy();

        count = getRandomSpawnCount();
        for (let i = 0; i < count; i++) spawnFlyingEnemy();

        count = getRandomSpawnCount();
        for (let i = 0; i < count; i++) spawnReflectiveEnemy();
    }, spawnInterval);

    await new Promise(resolve => {
        setTimeout(() => {
            clearInterval(intervalId);
            resolve();
        }, totalDuration);
    });

    await cycleBossAttacks();
}

  sandboxClose.onclick = () => {
    sandboxOverlay.style.display = 'none';
  };

  // Tab switch logic
  tabs.forEach((btn, index) => {
    btn.addEventListener('click', () => {
      for (const t of tabs) {
        t.classList.remove('active');
        t.setAttribute('aria-selected', 'false');
        t.tabIndex = -1;
      }
      for (const c of tabContents) {
        c.hidden = true;
      }
      btn.classList.add('active');
      btn.setAttribute('aria-selected', 'true');
      btn.tabIndex = 0;
      tabContents[index].hidden = false;
    });
  });

  // Load all CSS classes from stylesheets once



  // Render the CSS class search list
function renderElementsListPage() {
  elementsList.innerHTML = '';
  if (currentSearchResults.length === 0) {
    elementsList.textContent = 'No elements found';
    return;
  }
  const startIdx = currentPage * elementsPerPage;
  const pageItems = currentSearchResults.slice(startIdx, startIdx + elementsPerPage);
  pageItems.forEach(cls => {
    const div = document.createElement('div');
    div.textContent = cls;
    div.setAttribute('role', 'option');
    div.setAttribute('tabindex', '-1');
    div.addEventListener('click', () => selectCssClass(cls, div));
    elementsList.appendChild(div);
  });
  renderPageNavigation();
}

  // Search filter hook
elementsSearch.addEventListener('input', () => {
  const val = elementsSearch.value.trim().toLowerCase();
  currentSearchResults = allCssClasses.filter(cls => cls.includes(val));
  currentPage = 0;
  renderElementsListPage();
});

  // Selected element div reference, to toggle style


  // Select css class in list
  function selectCssClass(cls, div) {
    currentSelectedClass = cls;
    if (selectedElementDiv) selectedElementDiv.classList.remove('selected');
    selectedElementDiv = div;
    div.classList.add('selected');
    renderPreviewForClass(cls);
    spawnCountInput.value = updateSpawnCountForClass(cls);
    changeSpawnButton.disabled = !spawnedElements[cls]; // enable if already spawned
  }

  // Return current spawn count for class or default 1
  function updateSpawnCountForClass(cls) {
    return spawnedElements[cls] ? spawnedElements[cls].count : 1;
  }

function renderPageNavigation() {
  // Remove old nav if any
  const oldNav = document.getElementById('elements-list-nav');
  if (oldNav) oldNav.remove();

  // Create nav
  const nav = document.createElement('div');
  nav.id = 'elements-list-nav';
  nav.style.color = 'white';
  nav.style.marginTop = '5px';
  nav.style.textAlign = 'center';

  const totalPages = Math.ceil(currentSearchResults.length / elementsPerPage);

  // Previous button
  const prevBtn = document.createElement('button');
  prevBtn.textContent = 'Prev';
  prevBtn.disabled = currentPage === 0;
  prevBtn.onclick = () => {
    if (currentPage > 0) {
      currentPage--;
      renderElementsListPage();
    }
  };
  nav.appendChild(prevBtn);

  // Show current page info
  const pageInfo = document.createElement('span');
  pageInfo.textContent = ` Page ${currentPage + 1} / ${totalPages} `;
  nav.appendChild(pageInfo);

  const nextBtn = document.createElement('button');
  nextBtn.textContent = 'Next';
  nextBtn.disabled = currentPage >= totalPages - 1;
  nextBtn.onclick = () => {
    if (currentPage < totalPages - 1) {
      currentPage++;
      renderElementsListPage();
    }
  };
  nav.appendChild(nextBtn);

  elementsList.parentNode.appendChild(nav);
}

  function selectClass(cls, div) {
    currentSelectedClass = cls;
    if(selectedDiv) selectedDiv.classList.remove('selected');
    selectedDiv = div;
    div.classList.add('selected');
    renderPreview(cls);
    spawnCountInput.value = spawnedElements[cls]?.count || 1;
    changeSpawnButton.disabled = !spawnedElements[cls];
  }

  function renderPreview(cls) {
    elementPreview.innerHTML = '';
    const sample = document.createElement('div');
    sample.textContent = cls;
    sample.className = cls;
    sample.style.width = '100px';
    sample.style.height = '100px';
    sample.style.border = '1px solid white';
    sample.style.display = 'flex';
    sample.style.justifyContent = 'center';
    sample.style.alignItems = 'center';
    elementPreview.appendChild(sample);
  }

  function renderSpawnedList() {
    spawnList.innerHTML = '';
    for(const cls in spawnedElements) {
      const wrapper = document.createElement('div');
      const span = document.createElement('span');
      span.textContent = `${cls}: ${spawnedElements[cls].count}`;
      const btn = document.createElement('button');
      btn.textContent = 'Remove';
      btn.onclick = () => {
        spawnedElements[cls].elements.forEach(el => el.remove());
        delete spawnedElements[cls];
        renderSpawnedList();
        changeSpawnButton.disabled = true;
        if(currentSelectedClass===cls) spawnCountInput.value = 1;
      };
      wrapper.appendChild(span);
      wrapper.appendChild(btn);
      spawnList.appendChild(wrapper);
    }
  }

  // Render preview element for given CSS class
  function renderPreviewForClass(cls) {
    elementPreview.innerHTML = ''; // Clear

    // Create a sample element with the class inside preview area
    const sample = document.createElement('div');
    sample.textContent = cls;
    sample.classList.add(cls);

    // Some default styling for visibility
    sample.style.width = '100px';
    sample.style.height = '100px';
    sample.style.border = '1px solid #888';
    sample.style.display = 'flex';
    sample.style.justifyContent = 'center';
    sample.style.alignItems = 'center';
    sample.style.userSelect = 'none';

    elementPreview.appendChild(sample);
  }

  // Spawn button click
  spawnButton.addEventListener('click', () => {
    if (!currentSelectedClass) {
      alert('Select a CSS class first!');
      return;
    }
    const count = parseInt(spawnCountInput.value);
    if (isNaN(count) || count < 1) {
      alert('Enter a valid spawn count (1 or greater)');
      return;
    }
    spawnElements(currentSelectedClass, count);
    changeSpawnButton.disabled = false;
  });

  applyCharmodButton.addEventListener('click', () => {
    alert(`Applied Character Modifiers:\nPlayer speed: ${playerSpeedInput.value}\nBullet speed: ${bulletSpeedInput.value}`);
  });
  applyCharmod2Button.addEventListener('click', () => {
    alert(`Applied Modifiers 2:\nMax jumps: ${maxJumpsInput.value}\nPlayer lives: ${playerLivesInput.value}`);
  });
  applyMapmodButton.addEventListener('click', () => {
    alert(`Applied Map Modifier:\nBackground color: ${backgroundColorInput.value}`);
  });

  // Change spawn count for already spawned element
  changeSpawnButton.addEventListener('click', () => {
    if (!currentSelectedClass) return;
    const newCount = parseInt(spawnCountInput.value);
    if (isNaN(newCount) || newCount < 1) {
      alert('Enter a valid spawn count (1 or greater)');
      return;
    }
    updateSpawnCount(currentSelectedClass, newCount);
  });

  // Function to spawn elements inside #game-world
  function spawnElements(cls, count) {
    if (!spawnedElements[cls]) {
      spawnedElements[cls] = { count: 0, elements: [] };
    }

    // Spawn difference new elements if count increased, else remove excess if decreased
    const currentCount = spawnedElements[cls].count;
    const delta = count - currentCount;

    if (delta > 0) {
      // Spawn 'delta' more elements
      for(let i=0; i<delta; i++) {
        const el = document.createElement('div');
        el.classList.add(cls);
        el.style.position = 'absolute';
        // Position: random X between visible view + random Y near bottom (ground)
        el.style.left = `${Math.random() * (gameContainer.offsetWidth - 40) + gameScrollPosition}px`;
        el.style.bottom = `${Math.random() * 50}px`;
        el.title = cls;
        gameWorld.appendChild(el);
        spawnedElements[cls].elements.push(el);
      }
    } else if (delta < 0) {
      for(let i=0; i<Math.abs(delta); i++) {
        const el = spawnedElements[cls].elements.pop();
        if (el) el.remove();
      }
    }
    spawnedElements[cls].count = count;

    // Update spawn list visualization
    renderSpawnList();
  }

  // Update spawn count for existing spawned elements
  function updateSpawnCount(cls, newCount) {
    if (!spawnedElements[cls]) return;
    spawnElements(cls, newCount);
  }

  // Render spawned list
  function renderSpawnList() {
    spawnList.innerHTML = '';
    for (const cls in spawnedElements) {
      const item = document.createElement('div');
      item.id = 'spawn-list-item';
      const span = document.createElement('span');
      span.textContent = `${cls}: ${spawnedElements[cls].count}`;
      const removeBtn = document.createElement('button');
      removeBtn.textContent = 'Remove';
      removeBtn.style.backgroundColor = '#f44336';
      removeBtn.style.color = 'white';
      removeBtn.style.border = 'none';
      removeBtn.style.borderRadius = '4px';
      removeBtn.style.cursor = 'pointer';
      removeBtn.style.padding = '2px 6px';
      removeBtn.style.marginLeft = '10px';
      removeBtn.onclick = () => {
        // Remove elements from DOM
        spawnedElements[cls].elements.forEach(el => el.remove());
        delete spawnedElements[cls];
        renderSpawnList();
        changeSpawnButton.disabled = true;
        if (currentSelectedClass === cls) spawnCountInput.value = 1;
      };
      item.appendChild(span);
      item.appendChild(removeBtn);
      spawnList.appendChild(item);
    }
  }

  // Initialize Character Modifiers inputs with current values
  function updateCharModInputs() {
    playerSpeedInput.value = playerMaxSpeed;
    bulletSpeedInput.value = bulletSpeed;
  }

  applyCharModBtn.addEventListener('click', () => {
    const pspeed = parseFloat(playerSpeedInput.value);
    const bspeed = parseFloat(bulletSpeedInput.value);
    if (isNaN(pspeed) || pspeed < 1) { alert('Invalid player speed'); return; }
    if (isNaN(bspeed) || bspeed < 1) { alert('Invalid bullet speed'); return; }
    playerMaxSpeed = pspeed;
    bulletSpeed = bspeed;

    if (window.playerMaxSpeed !== undefined) window.playerMaxSpeed = playerMaxSpeed;
    if (window.bulletSpeed !== undefined) window.bulletSpeed = bulletSpeed;

    alert(`Player speed set to ${playerMaxSpeed}, bullet speed ${bulletSpeed}`);
  });

  // Modifier 2 inputs
  function updateCharMod2Inputs() {
    maxJumpsInput.value = maxJumps;
    playerLivesInput.value = lives;
  }

  applyCharMod2Btn.addEventListener('click', () => {
    const mjumps = parseInt(maxJumpsInput.value);
    const plives = parseInt(playerLivesInput.value);
    if (isNaN(mjumps) || mjumps < 1 || mjumps > 3) { alert('Max jumps must be 1 to 3'); return; }
    if (isNaN(plives) || plives < 1) { alert('Lives must be at least 1'); return; }

    maxJumps = mjumps;
    lives = plives;

    if (window.maxJumps !== undefined) window.maxJumps = maxJumps;
    if (window.lives !== undefined) window.lives = lives;

    alert(`Max jumps set to ${maxJumps}, lives set to ${lives}`);
  });

  // Map Modifier
  function updateMapModInput() {
    const bgc = window.gameContainer?.style?.backgroundColor || '#333333';
    // Convert rgb(...) to hex if needed or set default
    if (bgc.startsWith('rgb')) {
      backgroundColorInput.value = rgbToHex(bgc);
    } else {
      backgroundColorInput.value = bgc;
    }
  }

  applyMapModBtn.addEventListener('click', () => {
    const val = backgroundColorInput.value;
    gameContainer.style.backgroundColor = val;
  });

  // Simple rgb to hex converter to support initial loading
  function rgbToHex(rgb) {
    const result = rgb.match(/\d+/g);
    if (!result || result.length < 3) return '#333333';
    return "#" + result.slice(0,3).map(x => {
      const hex = parseInt(x).toString(16);
      return hex.length === 1 ? '0' + hex : hex;
    }).join('');
  }

  // Accessibility improvements for list keyboard navigation (optional, can be extended)
elementsList.addEventListener('keydown', e => {
    let items = Array.from(elementsList.children);
    let selectedIndex = items.findIndex(i => i.classList.contains('selected'));
    if (e.key === 'ArrowDown') {
      e.preventDefault();
      let nextIndex = Math.min(selectedIndex + 1, items.length - 1);
      if (selectedIndex >= 0) items[selectedIndex].classList.remove('selected');
      items[nextIndex].classList.add('selected');
      currentSelectedClass = items[nextIndex].textContent;
      renderPreviewForClass(currentSelectedClass);
      spawnCountInput.value = updateSpawnCountForClass(currentSelectedClass);
      changeSpawnButton.disabled = !spawnedElements[currentSelectedClass];
      items[nextIndex].focus();
    }
    if (e.key === 'ArrowUp') {
      e.preventDefault();
      let prevIndex = Math.max(selectedIndex - 1, 0);
      if (selectedIndex >= 0) items[selectedIndex].classList.remove('selected');
      items[prevIndex].classList.add('selected');
      currentSelectedClass = items[prevIndex].textContent;
      renderPreviewForClass(currentSelectedClass);
      spawnCountInput.value = updateSpawnCountForClass(currentSelectedClass);
      changeSpawnButton.disabled = !spawnedElements[currentSelectedClass];
      items[prevIndex].focus();
    }
    if (e.key === 'Enter' && selectedIndex >= 0) {
      spawnButton.click();
    }
});

async function bossPhaseFiveAttackD() {
    displayMessage("Trial 4", 3);
    await sleep(3000);

    const totalDuration = 25000;
    const spawnInterval = 400;

    const intervalId = setInterval(() => {
        let count;

        count = getRandomSpawnCount();
        for (let i = 0; i < count; i++) spawnLaserEnemy();

        count = getRandomSpawnCount();
        for (let i = 0; i < count; i++) spawnSplitterEnemy();

        count = getRandomSpawnCount();
        for (let i = 0; i < count; i++) spawnObstacle();
    }, spawnInterval);

    await new Promise(resolve => {
        setTimeout(() => {
            clearInterval(intervalId);
            resolve();
        }, totalDuration);
    });

    await cycleBossAttacks();
}

async function bossPhaseFiveAttackE() {
    displayMessage("Trial 5", 3);
    await sleep(3000);

    const totalDuration = 25000;
    const spawnInterval = 700;

    const intervalId = setInterval(() => {
        let count;

        count = getRandomSpawnCount();
        for (let i = 0; i < count; i++) spawnEnemy();

        count = getRandomSpawnCount();
        for (let i = 0; i < count; i++) spawnFlyingEnemy();

        count = getRandomSpawnCount();
        for (let i = 0; i < count; i++) spawnSniperEnemy();
    }, spawnInterval);

    await new Promise(resolve => {
        setTimeout(() => {
            clearInterval(intervalId);
            resolve();
        }, totalDuration);
    });

    await cycleBossAttacks();
}

async function bossPhaseFiveAttackF() {
    displayMessage("Trial 6", 3);
    await sleep(3000);

    const totalDuration = 25000;
    const spawnInterval = 450;

    const intervalId = setInterval(() => {
        let count;

        count = getRandomSpawnCount();
        for (let i = 0; i < count; i++) spawnEnemy();

        count = getRandomSpawnCount();
        for (let i = 0; i < count; i++) spawnVirusDrone();

        count = getRandomSpawnCount();
        for (let i = 0; i < count; i++) spawnSplitterEnemy();
    }, spawnInterval);

    await new Promise(resolve => {
        setTimeout(() => {
            clearInterval(intervalId);
            resolve();
        }, totalDuration);
    });

    await cycleBossAttacks();
}

function EnemyBarrage() {
    const numberOfFlyingEnemies = 3; // Total number of flying enemies to summon
    const numberOfChargingEnemies = 5; // Number of charging enemies to spawn
    const flyingSpawnDelay = 3000; // Delay between each flying enemy spawn (in milliseconds)
    const chargingSpawnDelay = 4000; // Delay between each charging enemy spawn (in milliseconds)
    const totalDuration = 15000; // Total time for the flying enemy spawning process (in milliseconds)

    // Function to spawn multiple flying enemies
    const flyingEnemiesInterval = setInterval(() => {
        if (numberOfFlyingEnemies > 0) {
            SpawnSplitterEnemy(); // Call to spawn a single flying enemy
            numberOfFlyingEnemies--; // Decrement the count
        } else {
            clearInterval(flyingEnemiesInterval); // Stop spawning when done
        }
    }, flyingSpawnDelay); // Spawn every 2 seconds

    // Function to spawn charging enemies
    const chargingEnemiesInterval = setInterval(() => {
        if (numberOfChargingEnemies > 0) {
            spawnChargingEnemy(); // Call to spawn a charging enemy
            numberOfChargingEnemies--; // Decrement the count
        } else {
            clearInterval(chargingEnemiesInterval); // Stop spawning when done
        }
    }, chargingSpawnDelay); // Spawn every 3 seconds

    // Wait before proceeding to the next boss cycle
    setTimeout(() => {
        clearInterval(flyingEnemiesInterval); // Clear the spawn loops
        clearInterval(chargingEnemiesInterval);
        cycleBossAttacks(); // Proceed to the next boss attack
    }, totalDuration); // 10 seconds before moving to next attack
}

function bossPhaseThree() {
    const numberOfFlyingEnemies = 6; // Total number of flying enemies to summon
    const numberOfChargingEnemies = 10; // Number of charging enemies to spawn
    const flyingSpawnDelay = 3000; // Delay between each flying enemy spawn (in milliseconds)
    const chargingSpawnDelay = 4000; // Delay between each charging enemy spawn (in milliseconds)
    const totalDuration = 20000; // Total time for the flying enemy spawning process (in milliseconds)

    // Function to spawn multiple flying enemies
    const flyingEnemiesInterval = setInterval(() => {
        if (numberOfFlyingEnemies > 0) {
            spawnFlyingEnemy(); // Call to spawn a single flying enemy
            numberOfFlyingEnemies--; // Decrement the count
        } else {
            clearInterval(flyingEnemiesInterval); // Stop spawning when done
        }
    }, flyingSpawnDelay); // Spawn every 2 seconds

    // Function to spawn charging enemies
    const chargingEnemiesInterval = setInterval(() => {
        if (numberOfChargingEnemies > 0) {
            spawnChargingEnemy(); // Call to spawn a charging enemy
            numberOfChargingEnemies--; // Decrement the count
        } else {
            clearInterval(chargingEnemiesInterval); // Stop spawning when done
        }
    }, chargingSpawnDelay); // Spawn every 3 seconds

    // Wait before proceeding to the next boss cycle
    setTimeout(() => {
        clearInterval(flyingEnemiesInterval); // Clear the spawn loops
        clearInterval(chargingEnemiesInterval);
        cycleBossAttacks(); // Proceed to the next boss attack
    }, totalDuration); // 10 seconds before moving to next attack
}

function bossNewPower() {
    let shotsFired = 0;
    const maxShots = 15;
    const shotCooldown = 800; // 0.8 seconds between shots

    const shootInterval = setInterval(() => {
        if (shotsFired >= maxShots) {
            clearInterval(shootInterval);

            // Introduce a delay before invoking the next attack or phase
            setTimeout(() => {
                cycleBossAttacks(); // Call back the attack cycle function
            }, 2000); // 2 seconds for any cooling down or animation effect
            return; // Stop firing after maximum shots
        }

        // Calculate the boss's and player's positions
        const bossX = parseInt(boss.style.left) + boss.offsetWidth / 2; // Middle of the boss
        const bossY = parseInt(boss.style.bottom) + 30; // Just above the boss
        const playerX = parseInt(player.style.left) + player.offsetWidth / 2; // Middle of the player
        const playerY = parseInt(player.style.bottom); // Bottom of the player
        
        // Calculate the direction vector
        const dx = playerX - bossX;
        const dy = playerY - bossY;
        const distance = Math.sqrt(dx * dx + dy * dy);
        const velocity = 10; // Speed of the projectile

        // Create a projectile
        const projectile = document.createElement('div');
        projectile.classList.add('boss-projectile');
        projectile.style.width = '10px';
        projectile.style.height = '10px';
        projectile.style.backgroundColor = 'orange';
        projectile.style.position = 'absolute';
        projectile.style.left = `${bossX - 5}px`; // Center it
        projectile.style.bottom = `${bossY}px`; // Start just above the boss
        gameWorld.appendChild(projectile);

        let projectileInterval = setInterval(() => {
            // Move projectile towards the player
            const moveX = (dx / distance) * velocity; // Calculate x movement
            const moveY = (dy / distance) * velocity; // Calculate y movement
            projectile.style.left = (parseInt(projectile.style.left) + moveX) + 'px';
            projectile.style.bottom = (parseInt(projectile.style.bottom) + moveY) + 'px';

            // Check collision
            if (checkCollision(player, projectile)) {
                reduceLives(); // Reduce player lives on hit
                projectile.remove(); // Remove projectile on hit
                clearInterval(projectileInterval);
            }

            // Remove projectile if it goes off-screen
            if (parseInt(projectile.style.bottom) > gameContainer.offsetHeight || 
                parseInt(projectile.style.left) < 0 || 
                parseInt(projectile.style.left) > gameContainer.offsetWidth) {
                projectile.remove(); // Remove off-screen
                clearInterval(projectileInterval);
            }
        }, 50); // Update every 50ms

        shotsFired++;
    }, shotCooldown); // Fire every 0.8 seconds
}
 
 
 
 
            function displayBossHealth() {
                bossHealthBar.style.display = 'block';
                updateBossHealth();
            }
 
function updateBossHealth() {
    // Ensure the health bar width updates according to boss health
    const maxHealth = 150; // Define the maximum health for level 3
    const currentHealth = Math.max(0, Math.min(bossHealth, maxHealth)); // Ensure health stays within bounds

    // Calculate the percentage of current health relative to the maximum health
    const healthPercentage = (currentHealth / maxHealth) * 100;

    // Update the CSS width of the health bar to reflect the current health
    bossHealthBar.style.width = `${healthPercentage}%`;

    // Optional: Set a different color based on health status (for visual feedback)
    if (currentHealth > maxHealth * 0.5) {
        bossHealthBar.style.backgroundColor = 'green'; // Healthy
    } else if (currentHealth > maxHealth * 0.2) {
        bossHealthBar.style.backgroundColor = 'yellow'; // Caution
    } else {
        bossHealthBar.style.backgroundColor = 'red'; // Critical health
    }
}
 
            function spawnBossEnemies() {
                if (bossShielded) {
                    for (let i = 0; i < 2; i++) {
                        const enemy = createElement('enemy', enemies, parseInt(boss.style.left) + (i * 50));
                        enemy.style.bottom = `${Math.random() * 250}px`;
                    }
                }
            }
 
            function spawnBossBullets() {
                const bullet = createBullet();
                bullet.style.left = parseInt(boss.style.left) + 'px';
                bullet.style.bottom = parseInt(boss.style.bottom) + 30 + 'px';
                bullet.style.backgroundColor = 'orange';
                gameWorld.appendChild(bullet);
                bullets.push({ element: bullet, direction: -1 });
            }
 
function checkBossHit() {
    if (!boss || bossShielded) return; // Stop damaging if boss is shielded

    bullets.forEach((bullet, bulletIndex) => {
        if (checkCollision(bullet.element, boss)) {
            bossHealth -= 2; // Decrement boss health
            updateBossHealth();
            bullet.element.remove();
            bullets.splice(bulletIndex, 1);
            
            // Check if the boss is defeated
            if (bossHealth <= 0) {
                displayMessage("Boss defeated!");
                onBossDefeated(); // Trigger boss defeat logic
            }
        }
    });
}
 
 
 
function onBossDefeated() {
    bossHealthBar.style.display = 'none'; // Hide health bar upon defeat

    const gameMode = localStorage.getItem('gameMode');
    let messages = []; // Array to hold messages

    // Create messages based on the level
    if (level === 1) {
        messages = [
            "Player: Take THAT!.",
            "Boss: Noooo! You may have won, but I'll see you in the next level!",
            "Boss: Until next time.",
            "Boss: Prepare yourself for what's to come!"
        ];
    } else if (level === 2) {
        messages = [
            "Player: Heh to ez!.",
            "Boss: You think this is the end? I’ll return!",
            "Boss: With my new enemies, you will never win!",
            "Boss: Prepare for an even greater challenge in Level 3!",
            "Boss: You will need to be stronger to defeat me next time!",
        ];
} else if (level === 3) {
    messages = [
        "Boss: How could this happen?!",
        "Boss: Well... That was all the attacks I had... and you beated them.",
        "Boss: Well now worries because my brother knows about this now.",
        "Boss: He will make sure your dead.",
        "Player: What do you mean your brother is coming to get me?.",
        "Boss: The strongest one in our family known for wiping all advanturers.",
        "Player: How come he is the strongest.",
        "Boss: he is known for his annoying attacks and summoning things.",
        "Boss: He plays around to much with his players.",
        "Boss: Good luck because this might be your actual last fight...",
        "Player: Ok?...",
    ];
    } else if (level === 4) {
        messages = [
            "Boss: I wish not to speak with you get out.",
        ];
    } else if (level === 5) {
        messages = [
            "Trials ended",
            "Thank you for playing.",
            "That is the end of the game.",
        ];
}

// Function to display messages sequentially
function displaySequentialMessages(messages, index) {
    if (index < messages.length) {
        displayMessage(messages[index]); // Display current message
        
        // Set timeout for the next message
        setTimeout(() => {
            displaySequentialMessages(messages, index + 1); // Move to next message
        }, 4500); // 4.5 seconds delay
    } else {
        // After all messages in level 3, unlock Endless Mode
        if (level === 6) {
            localStorage.setItem('endlessModeUnlocked', 'true');
            displayMessage("Endless Mode And sandbox Unlocked!"); // Optional inform player
            showEndlessModeButton();
            setTimeout(() => {
                setupNextLevel(); // Proceed to the next level setup
            }, 3000);
        } else {
            setupNextLevel(); // Proceed to the next level setup
        }
    }
}



    // Start the message display
    displaySequentialMessages(messages, 0);
}

function setupNextLevel() {
    // Check if in Endless Mode or Story Mode to manage levels separately
    if (isEndlessMode) {
        // Increment level for Endless mode
        currentEndlessLevel++; 
        localStorage.setItem('endlessLevel', currentEndlessLevel); // Save updated level
        
        displayMessage(`You've advanced to Endless Level ${currentEndlessLevel}!`);
        
    } else {
        // Logic for Story Mode - increment story level
        storyModeLevel++;
        if (storyModeLevel > 5) {
            storyModeLevel = 1; // Reset back to Level 1 if beyond max
        }
        localStorage.setItem('storyLevel', storyModeLevel); // Save updated level
        
        displayMessage(`You've advanced to Story Level ${storyModeLevel}!`);
    }

    // Set up the boss door to advance to the next level
    const bossDoor = document.createElement('div'); // Create a new div for the boss door
    bossDoor.classList.add('boss-door'); // Add class for styling
    bossDoor.style.position = 'absolute'; // Positioning for the door
    bossDoor.style.left = '600px'; // Specify door's X position
    bossDoor.style.bottom = '0px'; // Specify door's Y position (ground level)
    bossDoor.style.width = '50px'; // Set width
    bossDoor.style.height = '100px'; // Set height
    bossDoor.style.backgroundColor = 'gold'; // Set background color (for visibility)
    bossDoor.style.border = '2px solid black'; // Optional: add a border
    bossDoor.style.boxShadow = '0 0 15px rgba(255, 215, 0, 1)'; // Glow effect

    // Append the boss door to the game world
    gameWorld.appendChild(bossDoor);

    // Inform the player they can interact with the door
    displayMessage("Press 'E' to proceed to the next level!");
    
    // Allow player to transition to the next level upon interacting
    document.addEventListener('keydown', function handleKeyDown(event) {
        if (event.key === 'E' || event.key === 'e') {
            displayMessage("Refreshing to Level " + level + "...");
            location.reload(); // Refresh the page to start the new level
            console.log("Page refreshed for Level " + level + ".");
            document.removeEventListener('keydown', handleKeyDown); // Remove the event listener to prevent repeated triggering
        }
    });
}

function clearAllElements() {
    // Clear all elements in the game (elements grouped into arrays for easier management)
    [obstacles, enemies, bullets.map(b => b.element), powerUps, platforms, bossDoors, coins].forEach(arr => {
        arr.forEach(el => el.remove());
        arr.length = 0; // Clear the array
    });
}

function SendBackToDoor() {
    setTimeout(() => {
        player.style.left = "50px";
        player.style.bottom = "0px";

        setTimeout(() => {
            activateBossPower();
            level = 2; // Reset to Level 1
            resetGame();
            startLevel(); // Restart the game
        }, 2000);
    }, 3000);
}
 
 
            function activateFriendDialogue() {
                interactMessage.style.display = 'none';
                displayMessage("Thank you for saving me!");
                setTimeout(() => {
                    displayMessage("I got a secret power for you.");
                    setTimeout(() => {
                        grantBossPowerUp();
                        sendbacktodoor();
                        friend.style.display = 'none';
                    }, 3000);
                }, 2000);
            }
 
let isCharging = false;
let chargeTime = 0;
 
function shootLaserBlast(chargeTime) {
    let laser = document.createElement('div');
    laser.classList.add('laser');
    laser.style.left = player.style.left;
    laser.style.bottom = player.style.bottom;
    laser.style.width = `${chargeTime * 10}px`;
    laser.style.height = "10px";
    laser.style.backgroundColor = "cyan";
    gameWorld.appendChild(laser);
 
    setTimeout(() => {
        laser.remove();
        enemies.forEach(enemy => {
            if (checkCollision(laser, enemy)) {
                enemy.remove();
            }
        });
    }, 100);
}
 
 
            function displayMessage(message) {
                powerUpMessage.textContent = message;
                powerUpMessage.style.display = 'block';
                setTimeout(() => {
                    powerUpMessage.style.display = 'none';
                }, 2000);
            }
 
            function checkScoreForLevelTransition() {
                   localStorage.setItem('playerLevel', level); // Save updated level in local stora
            }
 
            function spawnFlyingEnemy() {
                const flyingEnemy = createElement('flying-enemy', enemies, gameScrollPosition + gameContainer.offsetWidth);
                flyingEnemy.style.bottom = Math.random() * 150 + 50 + 'px';
            }
 
function moveFlyingEnemies() {
    enemies.forEach((enemy, index) => {
        if (enemy.classList.contains('flying-enemy')) {
            // Move the enemy up and down
            let enemyYPosition = parseInt(enemy.style.bottom) || 0; // Get current Y position or default to 0
            let direction = enemy.dataset.direction ? parseInt(enemy.dataset.direction) : 1; // Up or down direction

            // Update vertical position of the flying enemy
            enemyYPosition += direction * 1; // Move 1 pixel per frame 
            enemy.style.bottom = enemyYPosition + 'px';

            // Reverse direction if the flying enemy reaches a certain height
            if (enemyYPosition >= 150) { // Maximum height
                direction = -1; // Change to downward movement
            } else if (enemyYPosition <= 0) { // Minimum height (ground)
                direction = 1; // Change to upward movement
            }
            enemy.dataset.direction = direction; // Store the current direction for the next update

            // Move the enemy left
            enemy.style.left = (parseInt(enemy.style.left) - 2) + 'px';

            // Check shooting
            if (enemy.dataset.lastShotTime === undefined || Date.now() - enemy.dataset.lastShotTime > 10000) { // Every 10 seconds
                shootBulletAtPlayer(enemy); // Shoot at the player
                enemy.dataset.lastShotTime = Date.now(); // Update the last shot time
            }

            // Boundary checking and collision with the player
            if (parseInt(enemy.style.left) < 0) {
                removeElement(enemy, enemies, index, 30);
            } else if (checkCollision(player, enemy)) {
                reduceLives();
                removeElement(enemy, enemies, index, 0);
            }
        }
    });
}

// Function to shoot a bullet aimed at the player
function shootBulletAtPlayer(enemy) {
    const bullet = document.createElement('div');
    bullet.classList.add('bullet'); // Add your bullet class
    bullet.style.width = '10px';
    bullet.style.height = '5px';
    bullet.style.backgroundColor = 'orange'; // Bullet color
    bullet.style.position = 'absolute';
    
    // Position the bullet at the enemy's current position
    bullet.style.left = (parseInt(enemy.style.left) + 20) + 'px'; // Position it slightly in front of the enemy
    bullet.style.bottom = (parseInt(enemy.style.bottom) + 15) + 'px'; // Start just below the enemy
    gameWorld.appendChild(bullet); // Add bullet to the game world
    
    // Calculate angle towards the player
    const playerX = parseInt(player.style.left) + player.offsetWidth / 2; // Center of player
    const playerY = parseInt(player.style.bottom); // Bottom of player

    const dx = playerX - (parseInt(bullet.style.left) + bullet.offsetWidth / 2);
    const dy = playerY - (parseInt(bullet.style.bottom));
    const distance = Math.sqrt(dx * dx + dy * dy); 
    const velocity = 5; // Speed of the bullet

    // Bullet movement
    const moveBullet = setInterval(() => {
        const moveX = (dx / distance) * velocity; 
        const moveY = (dy / distance) * velocity;

        bullet.style.left = (parseInt(bullet.style.left) + moveX) + 'px';
        bullet.style.bottom = (parseInt(bullet.style.bottom) + moveY) + 'px';

        // Check if the bullet hits the player or goes off screen
        if (checkCollision(bullet, player)) {
            reduceLives(); // Damages the player
            bullet.remove(); // Remove bullet
            clearInterval(moveBullet); // Stop moving the bullet
        }

        if (parseInt(bullet.style.left) < 0 || parseInt(bullet.style.left) > gameWorld.offsetWidth || parseInt(bullet.style.bottom) < 0) {
            bullet.remove(); // Remove bullet if it goes off screen
            clearInterval(moveBullet); // Stop moving the bullet
        }
    }, 1000 / 60); // 60 FPS
}
 
            function spawnChargingEnemy() {
                const chargingEnemy = createElement('charging-enemy', enemies, gameScrollPosition + gameContainer.offsetWidth);
                chargingEnemy.style.bottom = '0px';
                chargingEnemy.setAttribute('data-charge', '0');
                chargingEnemy.classList.add('charging-prep'); // Fading in/out red glow effect
            }
 
 
            function createChargeTrail(x, y) {
                const trail = document.createElement('div');
                trail.classList.add('charge-trail');
                trail.style.left = x + 'px';
                trail.style.bottom = y + 'px';
                gameWorld.appendChild(trail);
 
                setTimeout(() => trail.remove(), 400); // Shorter effect for smoothness
            }
 
 
 
 
function moveChargingEnemies() {
    enemies.forEach((enemy, index) => {
        if (enemy.classList.contains('charging-enemy')) {
            let chargeTime = parseInt(enemy.getAttribute('data-charge'));
 
            if (chargeTime < 60) {
                // Charging phase (fading in/out glow)
                enemy.setAttribute('data-charge', chargeTime + 1);
            } else {
                // Fully Charged (Solid Red Outline + Charging Forward)
                enemy.classList.remove('charging-prep');
                enemy.classList.add('charging-active');
                enemy.style.left = (parseInt(enemy.style.left) - 6) + 'px';
 
                // Create a bright red trail
                createChargeTrail(parseInt(enemy.style.left), parseInt(enemy.style.bottom));
            }
 
            // Check collision with player
            if (checkCollision(player, enemy)) {
                createBurst(parseInt(enemy.style.left), parseInt(enemy.style.bottom)); // Impact explosion
                reduceLives();
                removeElement(enemy, enemies, index, 0);
            }
 
            // Remove if out of bounds
            if (parseInt(enemy.style.left) < gameScrollPosition - enemy.offsetWidth) {
                removeElement(enemy, enemies, index, 30);
            }
        }
    });
}
 
 
 
            function spawnStealthEnemy() {
                const stealthEnemy = createElement('stealth-enemy', enemies, gameScrollPosition + gameContainer.offsetWidth);
                stealthEnemy.setAttribute('data-stealth', '0');
                stealthEnemy.style.backgroundColor = '#555';
                stealthEnemy.style.opacity = '1';
            }
 
            function moveStealthEnemies() {
                enemies.forEach(en => {
                    if (en.classList.contains('stealth-enemy')) {
                        const stealth = parseInt(en.getAttribute('data-stealth'));
                        if (stealth > 50) {
                            en.style.opacity = en.style.opacity == '0' ? '1' : '0';
                            en.setAttribute('data-stealth', '0');
                        } else {
                            en.setAttribute('data-stealth', stealth + 1);
                        }
                    }
                });
            }

function moveSniperEnemies() {
    enemies.forEach((enemy, index) => {
        if (enemy.classList.contains('sniper-enemy')) {
            const enemyX = parseInt(enemy.style.left) + enemy.offsetWidth / 2; // Center position
            const enemyY = parseInt(enemy.style.bottom) + enemy.offsetHeight; // Height

            // Shooting mechanism
            if (!enemy.dataset.lastShotTime || Date.now() - enemy.dataset.lastShotTime > 3000) { // Every 3 seconds
                shootAtPlayer(enemy);
                enemy.dataset.lastShotTime = Date.now(); // Update for next shot
            }

            // Check distance to player
            const distanceToPlayer = Math.sqrt(Math.pow(enemyX - (parseInt(player.style.left) + player.offsetWidth / 2), 2) + 
                Math.pow(enemyY - parseInt(player.style.bottom), 2));
            
            if (distanceToPlayer < 300) { // Within 300 pixels visibility range
                enemy.style.opacity = '1'; // Fully visible
            } else {
                enemy.style.opacity = '0.5'; // Reduced opacity
            }
        }
    });
}

// Function for the sniper to shoot at the player
function shootAtPlayer(enemy) {
    const bullet = document.createElement('div');
    bullet.classList.add('bullet'); // Add your class for the bullet
    bullet.style.width = '10px';
    bullet.style.height = '5px';
    bullet.style.backgroundColor = 'red'; // Bullet color
    bullet.style.position = 'absolute';
    
    // Position the bullet at the sniper's location
    bullet.style.left = (parseInt(enemy.style.left) + 20) + 'px'; // Set slight offset
    bullet.style.bottom = (parseInt(enemy.style.bottom) + 15) + 'px'; // Set above the sniper
    gameWorld.appendChild(bullet); // Add bullet to the game world

    // Calculate angle towards the player
    const playerX = parseInt(player.style.left) + player.offsetWidth / 2; // Center of player
    const playerY = parseInt(player.style.bottom); // Bottom of player

    const dx = playerX - (parseInt(bullet.style.left) + bullet.offsetWidth / 2);
    const dy = playerY - (parseInt(bullet.style.bottom));
    const distance = Math.sqrt(dx * dx + dy * dy); 
    const velocity = 5; // Speed of the bullet

    // Bullet movement logic
    const moveBullet = setInterval(() => {
        const moveX = (dx / distance) * velocity; // Calculate x movement direction
        const moveY = (dy / distance) * velocity; // Calculate y movement direction

        bullet.style.left = (parseInt(bullet.style.left) + moveX) + 'px';
        bullet.style.bottom = (parseInt(bullet.style.bottom) + moveY) + 'px';

        // Check for bullet collision with player
        if (checkCollision(bullet, player)) {
            reduceLives(); // Damage player
            bullet.remove(); // Remove bullet
            clearInterval(moveBullet); // Stop bullet movement
        }

        // Remove bullet if it goes off screen
        if (parseInt(bullet.style.left) < 0 || parseInt(bullet.style.left) > gameWorld.offsetWidth || parseInt(bullet.style.bottom) < 0) {
            bullet.remove(); // Remove bullet if it goes off screen
            clearInterval(moveBullet); // Stop bullet movement
        }
    }, 1000 / 60); // 60 FPS
}
 
function spawnSplitterEnemy() {
    const leftPos = gameScrollPosition + gameContainer.offsetWidth;
    const splitter = createElement('split-enemy', enemies, leftPos);
    splitter.style.left = leftPos + 'px';
    splitter.style.bottom = '0px';
    splitter.classList.add('split');  // Important!
    splitter.style.width = '50px';    
    splitter.style.height = '50px';
}

function moveSplitterEnemies() {
    enemies.forEach((enemy, index) => {
        if (enemy.classList.contains('split-enemy')) {
            const speed = enemy.classList.contains('split') ? 1 : 3; // mini splitters move faster
            enemy.style.left = (parseInt(enemy.style.left) - speed) + 'px';

            if (parseInt(enemy.style.left) < gameScrollPosition - enemy.offsetWidth) {
                removeElement(enemy, enemies, index, 30);  // Give some score for killing
            } else if (checkCollision(player, enemy)) {
                reduceLives();
                removeElement(enemy, enemies, index, 0);
            }
        }
    });
}
 
function handleSplitterEnemyHit(enemy, enemyIndex) {
    console.log('Splitter hit triggered for enemy:', enemy);
    if (enemy.classList.contains('split')) {  // just to be sure
        const baseLeft = parseInt(enemy.style.left);
        const baseBottom = enemy.style.bottom;
        const miniSize = 20;          // Increased size from 15 to 20 px
        const gap = 10;               // Gap between minis (pixels)

        for (let i = 0; i < 2; i++) { // Spawn only 2 mini enemies
            // Calculate left position for each mini enemy to have gap between them
            const miniLeft = baseLeft + i * (miniSize + gap);
            const miniEnemy = createElement('split-enemy', enemies, miniLeft);
            miniEnemy.style.width = miniSize + 'px';
            miniEnemy.style.height = miniSize + 'px';
            miniEnemy.classList.remove('split');
            miniEnemy.style.bottom = baseBottom; // Appear at the same vertical pos
        }
    }
    removeElement(enemy, enemies, enemyIndex, 0);
}

  function loadAllCssClasses() {
    const classesSet = new Set();
    for (const sheet of document.styleSheets) {
      try {
        if (!sheet.cssRules) continue;
        for (const rule of sheet.cssRules) {
          if (!rule.selectorText) continue;
          const selectors = rule.selectorText.split(/\s*,\s*/);
          selectors.forEach(sel => {
            // Match individual classes .class-name or more complex selectors (.enemy, .sniper-enemy)
            const clsMatches = sel.match(/\.(\w[\w-\d]*)/g);
            if (clsMatches) clsMatches.forEach(c => classesSet.add(c.slice(1)));
          });
        }
      } catch(e) {
        // Ignore CORS stylesheets
      }
    }
    allCssClasses = Array.from(classesSet).sort();
    renderElementsListPage(allCssClasses);
  }
 
            function handleExplosiveEnemyHit(enemy, enemyIndex) {
                removeElement(enemy, enemies, enemyIndex, 0);
                enemies.forEach((otherEnemy, index) => {
                    if (calculateDistance(enemy, otherEnemy) < 50) {
                        removeElement(otherEnemy, enemies, index, 0);
                    }
                });
                createBurst(parseInt(enemy.style.left), parseInt(enemy.style.bottom));
                reduceLives();
            }
 
            function spawnSniperEnemy() {
                const sniper = createElement('sniper-enemy', enemies, gameScrollPosition + gameContainer.offsetWidth);
                sniper.style.bottom = '200px';
                const sniperInterval = setInterval(() => {
                    if (Math.random() < 0.05 && calculateDistance(player, sniper) < 300) {
                        const bullet = createBullet();
                        bullet.style.left = parseInt(sniper.style.left) + 'px';
                        bullet.style.bottom = parseInt(sniper.style.bottom) + 'px';
                        bullet.style.backgroundColor = 'red';
                        gameWorld.appendChild(bullet);
                        bullets.push({ element: bullet, direction: -1 });
                    }
                }, 1000);
 
                sniper.setAttribute('data-interval', sniperInterval);
            }
 

// Function to spawn the reflective enemy at the bottom
function spawnReflectiveEnemy() {
    // Create the reflective enemy element
    var reflectiveEnemy = createElement('reflective-enemy', enemies, gameScrollPosition + gameContainer.offsetWidth);

    // Set initial attributes
    reflectiveEnemy.setAttribute('data-health', '10'); // Set initial health or reflection strength
    reflectiveEnemy.classList.add('outlined'); // Add CSS class for glowing outline
    reflectiveEnemy.dataset.reflectiveHits = 0; // Initialize reflection hits tracking

    // Position the reflective enemy at the bottom of the game world
    reflectiveEnemy.style.bottom = '0px'; // Set to 0 for the bottom position

    // Set up shooting capability
    reflectiveEnemy.dataset.lastShotTime = Date.now(); // Track when the last shot was fired

    // Append the reflective enemy to the game world
    gameWorld.appendChild(reflectiveEnemy);
}

// Function to handle shooting bullets at the player
function shootAtPlayer2(reflectiveEnemy) {
    const bullet = document.createElement('div');
    bullet.classList.add('enemy-bullet'); // Style class for the bullet
    bullet.style.width = '10px';
    bullet.style.height = '5px';
    bullet.style.backgroundColor = 'red'; // Enemy bullet color
    bullet.style.position = 'absolute';

    // Position the bullet at the enemy's location
    bullet.style.left = `${parseInt(reflectiveEnemy.style.left) + 20}px`; // Center the bullet
    bullet.style.bottom = `${parseInt(reflectiveEnemy.style.bottom) + 15}px`; // Above the enemy
    gameWorld.appendChild(bullet); // Add bullet to the game world

    // Calculate the player’s position
    const playerX = parseInt(player.style.left) + player.offsetWidth / 2; // Center of player
    const playerY = parseInt(player.style.bottom); // Bottom of player

    // Calculate direction towards the player
    const dx = playerX - (parseInt(bullet.style.left) + bullet.offsetWidth / 2);
    const dy = playerY - parseInt(bullet.style.bottom);
    const distance = Math.sqrt(dx * dx + dy * dy);
    const velocity = 5; // Speed of the bullet

    // Move the bullet towards the player
    const moveBulletInterval = setInterval(() => {
        const moveX = (dx / distance) * velocity; // Calculate x movement
        const moveY = (dy / distance) * velocity; // Calculate y movement

        bullet.style.left = (parseInt(bullet.style.left) + moveX) + 'px';
        bullet.style.bottom = (parseInt(bullet.style.bottom) + moveY) + 'px';

        // Check for collision with player
        if (checkCollision(player, bullet)) {
            reduceLives(); // Damage player
            bullet.remove(); // Remove bullet
            clearInterval(moveBulletInterval); // Stop movement
        }

        // Remove bullet if it goes off screen
        if (parseInt(bullet.style.left) < 0 || parseInt(bullet.style.left) > gameWorld.offsetWidth || parseInt(bullet.style.bottom) < 0) {
            bullet.remove(); // Remove bullet if it goes off screen
            clearInterval(moveBulletInterval); // Stop movement
        }
    }, 1000 / 60); // Move at 60 FPS
}

// Update reflective enemy behavior to shoot at player on hit
function handleBulletCollisionWithReflectiveEnemy(reflectiveEnemy, bullet) {
    // Check if the bullet collides with the reflective enemy
    if (checkCollision(reflectiveEnemy, bullet)) {
        bullet.remove(); // Remove bullet on collision
        reflectiveEnemy.dataset.reflectiveHits++; // Track the number of hits

        // Call the shoot function after a certain interval
        if (Date.now() - reflectiveEnemy.dataset.lastShotTime >= 1) { // Cooldown for 2 seconds between shots
            shootAtPlayer2(reflectiveEnemy);
            reflectiveEnemy.dataset.lastShotTime = Date.now(); // Reset the shot time
        }
    }
}
 
            function spawnNewInteractiveEnemies() {
                const randomFeature = Math.random();
                if (randomFeature < 0.2) {
                    spawnTeleporterEnemy();
                } else if (randomFeature < 0.6) {
                    spawnVelocityEnemy();
                } else if (randomFeature < 0.8) {
                    spawnStickyEnemy();
                } else {
                    spawnReflectiveEnemy();
                }
            }
 
            function moveNewEnemies() {
                moveTeleporterEnemies();
                moveVelocityEnemies();
                moveStickyEnemies();
            }
 
            // New enemies with creative features
            function spawnTeleporterEnemy() {
                const teleporterEnemy = createElement('teleporter-enemy', enemies, gameScrollPosition + gameContainer.offsetWidth);
                teleporterEnemy.style.backgroundColor = '#8A2BE2'; 
                teleporterEnemy.style.bottom = '0px';
                teleporterEnemy.setAttribute('data-teleport', '0');
            }
 
            function moveTeleporterEnemies() {
                enemies.forEach(en => {
                    if (en.classList.contains('teleporter-enemy')) {
                        const teleport = parseInt(en.getAttribute('data-teleport'));
                        if (teleport > 100) {
                            en.style.left = Math.random() * (gameWorld.offsetWidth - en.offsetWidth) + 'px';
                            en.setAttribute('data-teleport', '0');
                        } else {
                            en.setAttribute('data-teleport', teleport + 1);
                        }
                    }
                });
            }

function moveReflectiveEnemies() {
    var enemiesToRemove = []; // Array to track enemies to be removed

    enemies.forEach(function(en, index) {
        if (en.classList.contains('reflective-enemy')) {
            // Move the reflective enemy to the left
            en.style.left = (parseInt(en.style.left) - 1) + 'px';

            // Check for collision with bullets
            bullets.forEach(function(bullet, bulletIndex) {
                // If the bullet collides with the reflective enemy
                if (checkCollision(en, bullet.element)) {
                    // Reflect the bullet's direction
                    bullet.direction *= -1; 

                    // Adjust bullet position slightly to avoid getting stuck
                    bullet.element.style.left = (parseInt(bullet.element.style.left) + (bullet.direction * 5)) + 'px';

                    // Increment the reflective hits count
                    en.dataset.reflectiveHits++;

                    // Optional: handle when you want to remove the enemy after a number of hits, if desired
                    if (parseInt(en.dataset.reflectiveHits) >= 10) {
                        enemiesToRemove.push(index); // Mark for removal
                    }

                    // Remove the bullet
                    bullet.element.remove();
                    bullets.splice(bulletIndex, 1); // Remove bullet from the bullets array
                }
            });

            // Check for collision with the player
            if (checkCollision(player, en)) {
                reduceLives(); // Reduce lives if player hits the reflective enemy
                enemiesToRemove.push(index); // Mark enemy for removal
            }

            // Remove if off-screen
            if (parseInt(en.style.left) < -en.offsetWidth) {
                enemiesToRemove.push(index); // Mark for removal
            }
        }
    });

    // Remove enemies marked for removal
    enemiesToRemove.reverse().forEach(function(index) {
        removeElement(enemies[index], enemies, index, 0);
    });
}
 
            function spawnVelocityEnemy() {
                const velocityEnemy = createElement('velocity-enemy', enemies, gameScrollPosition + gameContainer.offsetWidth);
                velocityEnemy.style.backgroundColor = '#FF4500'; 
                velocityEnemy.style.bottom = Math.random() * 150 + 'px';
                velocityEnemy.setAttribute('data-speed', '2');
            }
 
            function moveVelocityEnemies() {
                enemies.forEach(en => {
                    if (en.classList.contains('velocity-enemy')) {
                        const speed = parseInt(en.getAttribute('data-speed'));
                        en.style.left = (parseInt(en.style.left) - speed) + 'px';
                        en.style.bottom = (parseInt(en.style.bottom) + (Math.random() - 0.5) * 10) + 'px';
                        if (parseInt(en.style.left) < gameScrollPosition - en.offsetWidth) {
                            removeElement(en, enemies, 0, 30);
                        } else if (checkCollision(player, en)) {
                            reduceLives();
                            removeElement(en, enemies, 0, 0);
                        }
                    }
                });
            }



window.addEventListener('DOMContentLoaded', () => {
  const sandboxOverlay = document.getElementById('sandbox-overlay');
  const sandboxClose = document.getElementById('sandbox-close');

  sandboxClose.onclick = () => {
    sandboxOverlay.style.display = 'none';
  };

  const tabs = Array.from(document.querySelectorAll('#sandbox-tabs button'));
  const tabContents = Array.from(document.querySelectorAll('.tab-content'));

  tabs.forEach((btn, index) => {
    btn.addEventListener('click', () => {
      tabs.forEach(t => {
        t.classList.remove('active');
        t.setAttribute('aria-selected', 'false');
        t.tabIndex = -1;
      });
      tabContents.forEach(c => c.hidden = true);
      btn.classList.add('active');
      btn.setAttribute('aria-selected', 'true');
      btn.tabIndex = 0;
      tabContents[index].hidden = false;
    });
  });

  // Initialize first tab as active
  if (tabs.length > 0 && tabContents.length > 0) {
    tabs[0].classList.add('active');
    tabs[0].setAttribute('aria-selected', 'true');
    tabs[0].tabIndex = 0;
    tabContents[0].hidden = false;
  }
});

function spawnVirusDrone() {
    const leftPos = gameScrollPosition + gameContainer.offsetWidth;
    const virus = document.createElement('div');
    virus.classList.add('virus-drone');
    virus.style.bottom = '380px'; // top of screen (400px height container minus 20 px)
    virus.style.left = leftPos + 'px';
    virus.dataset.speed = 8;
    virus.dataset.activeEnemy = ''; // enemy it’s currently infecting

    gameWorld.appendChild(virus);
    viruses.push(virus); // store in separate array to manage separately
}
 
            function spawnStickyEnemy() {
                const stickyEnemy = createElement('sticky-enemy', enemies, gameScrollPosition + gameContainer.offsetWidth);
                stickyEnemy.style.backgroundColor = '#FFD700'; 
                stickyEnemy.style.bottom = '0px';
            }
 
            function moveStickyEnemies() {
                enemies.forEach(en => {
                    if (en.classList.contains('sticky-enemy')) {
                        en.style.left = (parseInt(en.style.left) - 1) + 'px';
                        if (checkCollision(player, en)) {
                            player.style.backgroundColor = '#FFD700';
                            setTimeout(() => player.style.backgroundColor = '#4CAF50', 2000);
                            removeElement(en, enemies, 0, 0);
                        }
                    }
                });
            }
 
 
    </script>
</body>
</html>