Ord.io Logo
Ord.io
Inscription

76,629,683

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Boss Battle</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <style>
    body {
      margin: 0;
      overflow: hidden;
      font-family: 'Courier New', monospace;
      background-color: black;
    }

    canvas {
      display: block;
      margin: 0 auto;
    }

    #start-screen,
    #end-screen {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      background-color: rgba(0, 0, 0, 0.8);
      color: white;
      text-align: center;
    }

    #start-button {
      font-size: 24px;
      padding: 10px 20px;
      margin-top: 20px;
      cursor: pointer;
    }

    #time {
      font-size: 5vw;
      color: red;
    }

    #message {
      font-size: 2vw;
      margin-top: 20px;
      max-width: 80%;
    }

    @media (max-width: 600px) {
      #time {
        font-size: 10vw;
      }

      #message {
        font-size: 4vw;
      }
    }

    #mobile-controls {
      display: none;
      position: fixed;
      bottom: 20px;
      left: 20px;
      right: 20px;
      z-index: 1000;
    }

    #joystick-area {
      width: 150px;
      height: 150px;
      background: rgba(255, 255, 255, 0.2);
      border-radius: 50%;
      position: absolute;
      left: 20px;
      bottom: 20px;
    }

    #joystick {
      width: 50px;
      height: 50px;
      background: rgba(255, 255, 255, 0.5);
      border-radius: 50%;
      position: absolute;
      left: 50px;
      top: 50px;
    }

    #shoot-button {
      position: absolute;
      right: 20px;
      bottom: 20px;
      width: 80px;
      height: 80px;
      background: rgba(255, 0, 0, 0.5);
      border-radius: 50%;
    }
  </style>
</head>

<body>
  <canvas id="gameCanvas" width="800" height="600"></canvas>
  <div id="start-screen">
    <h1>FINAL PRE MINT BOSS BATTLE</h1>
    <p>DO YOU HAVE WHAT IT TAKES TO DEFEAT THE BOSS AND EARN YOURSELF A CONTRACT?</p>
    <button id="start-button">Start Game</button>
  </div>
  <div id="end-screen" style="display: none;">
    <div id="time"></div>
    <div id="message">Post your results on X tagging @agooddoctorbtc to potentially sell your soul.</div>
  </div>
  <audio id="background-music" loop>
    <source src="/content/918a68b26b77f3b6f1a286c35bd1b1c1370fc5ad92d43f15416db8ae6ea2330ci0" type="audio/mp3">
  </audio>
  <div id="mobile-controls">
    <div id="joystick-area">
      <div id="joystick"></div>
    </div>
    <div id="shoot-button"></div>
  </div>
  <script>
    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');

    const keys = {};
    let player;
    let boss;
    let bullets = [];
    let bossBullets = [];
    let bossMoveTimer = 0;
    let gameEnded = false;
    let startTime;
    let gameLoop;

    const playerImage = new Image();
    playerImage.src = '/content/7f58430bab3cf61c9712f6530de341c1c9d9ddef49824105acc8fb60867c5522i0';

    const bossImage = new Image();
    bossImage.src = '/content/d8bf7a28c8d39283eeded0696f58fbe76d405994862bdb996f7d6ef4bc297a80i0';

    const playerBulletImage = new Image();
    playerBulletImage.src = '/content/7c8ffe9220a15ba3f1fd6a146c13d93bc24a37da92d57a7ff29e7b77e02037cfi2';

    const bossBulletImage = new Image();
    bossBulletImage.src = '/content/7c8ffe9220a15ba3f1fd6a146c13d93bc24a37da92d57a7ff29e7b77e02037cfi1';

    document.addEventListener('keydown', function(e) {
      keys[e.key] = true;
    });

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

    const startScreen = document.getElementById('start-screen');
    const startButton = document.getElementById('start-button');
    const endScreen = document.getElementById('end-screen');
    const backgroundMusic = document.getElementById('background-music');

    startButton.addEventListener('click', function() {
      startScreen.style.display = 'none';
      startTime = Date.now();
      init();
      backgroundMusic.play();
    });

    function resizeCanvas() {
      const aspectRatio = canvas.width / canvas.height;
      const windowAspectRatio = window.innerWidth / window.innerHeight;
      let width, height;

      if (windowAspectRatio > aspectRatio) {
        height = window.innerHeight;
        width = height * aspectRatio;
      } else {
        width = window.innerWidth;
        height = width / aspectRatio;
      }

      canvas.style.width = width + 'px';
      canvas.style.height = height + 'px';
    }

    window.addEventListener('load', resizeCanvas);
    window.addEventListener('resize', resizeCanvas);

    class Player {
      constructor() {
        this.x = canvas.width / 2 - 20;
        this.y = canvas.height - 70;
        this.width = 40;
        this.height = 40;
        this.speed = 2;
        this.shootTimer = 0;
        this.lives = 3;
        this.invincibleTimer = 0;
      }

      move() {
        if (joystickActive) {
          this.x += this.speed * joystickPos.x;
          this.y += this.speed * joystickPos.y;

          this.x = Math.max(0, Math.min(canvas.width - this.width, this.x));
          this.y = Math.max(canvas.height * 0.25, Math.min(canvas.height - this.height, this.y));
        } else {
          // Existing keyboard controls
          if (keys['ArrowLeft'] && this.x > 0) {
            this.x -= this.speed;
          }
          if (keys['ArrowRight'] && this.x + this.width < canvas.width) {
            this.x += this.speed;
          }
          if (keys['ArrowUp'] && this.y > canvas.height * 0.45) {
            this.y -= this.speed;
          }
          if (keys['ArrowDown'] && this.y + this.height < canvas.height) {
            this.y += this.speed;
          }
        }
      }

      shoot() {
        if (keys[' '] || shootActive) {
          if (this.shootTimer <= 0) {
            bullets.push(new Bullet(this.x + this.width / 2, this.y));
            this.shootTimer = 15;
          }
        }
        if (this.shootTimer > 0) {
          this.shootTimer--;
        }
      }

      update() {
        if (this.invincibleTimer > 0) {
          this.invincibleTimer--;
        }
      }

      draw() {
        if (this.invincibleTimer > 0) {
          if (Math.floor(this.invincibleTimer / 5) % 2 === 0) {
            ctx.drawImage(playerImage, this.x, this.y, this.width, this.height);
          }
        } else {
          ctx.drawImage(playerImage, this.x, this.y, this.width, this.height);
        }
      }
    }

    class Bullet {
      constructor(x, y) {
        this.x = x - 2.5;
        this.y = y;
        this.width = 5;
        this.height = 10;
        this.speed = 7;
      }

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

      draw() {
        ctx.drawImage(playerBulletImage, this.x, this.y, this.width, this.height);
      }
    }

    class SpiralBullet {
      constructor(x, y) {
        this.x = x;
        this.y = y;
        this.radius = 5;
        this.angle = 0;
        this.speed = 3;
        this.downwardSpeed = 1.5;
        this.color = 'purple';
      }

      update() {
        this.angle += 0.15;
        this.x += Math.cos(this.angle) * this.speed;
        this.y += Math.sin(this.angle) * this.speed + this.downwardSpeed;
      }

      draw() {
        ctx.save();
        ctx.shadowBlur = 10;
        ctx.shadowColor = this.color;
        ctx.globalCompositeOperation = 'lighter';
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
        ctx.fillStyle = this.color;
        ctx.fill();
        ctx.closePath();
        ctx.restore();
      }

      getBoundingBox() {
        return {
          x: this.x - this.radius,
          y: this.y - this.radius,
          width: this.radius * 2,
          height: this.radius * 2
        };
      }
    }

    class Boss {
      constructor() {
        this.x = canvas.width / 4 - 100;
        this.y = 50;
        this.width = 100;
        this.height = 100;
        this.health = 100;
        this.maxHealth = 100;
        this.flashTimer = 0;
        this.moveSpeed = 3;
        this.specialAttackTimer = 0;
      }

      move() {
        bossMoveTimer++;
        this.x += Math.sin(bossMoveTimer / 60) * this.moveSpeed;
      }

      shoot() {
        if (bossMoveTimer % 60 === 0) {
          bossBullets.push(new BossBullet(this.x + this.width / 2, this.y + this.height, 0, 7)); // Increased speed from 5 to 7
        }
        if (bossMoveTimer % 120 === 0) {
          for (let angle = -1; angle <= 1; angle += 0.5) {
            const hue = (angle + 1) * 60;
            bossBullets.push(new BossBullet(this.x + this.width / 2, this.y + this.height, angle, 5, hue)); // Increased speed from 3 to 5
          }
        }
        if (bossMoveTimer % 240 === 0) {
          bossBullets.push(new SpiralBullet(this.x + this.width / 2, this.y + this.height));
        }

        this.specialAttackTimer++;
        if (this.specialAttackTimer >= 600) {
          if (Math.random() < 0.2) {
            bossBullets.push(new SpecialBullet(this.x + this.width / 2, this.y + this.height));
            this.specialAttackTimer = 0;
          }
        }
      }

      draw() {
        if (this.flashTimer > 0) {
          ctx.globalAlpha = 0.5 + Math.sin(this.flashTimer * 0.5) * 0.5;
          this.flashTimer--;
        }
        ctx.drawImage(bossImage, this.x, this.y, this.width, this.height);
        ctx.globalAlpha = 1;
      }
    }

    class BossBullet {
      constructor(x, y, angle, speed, hue = 0) {
        this.x = x - 2.5;
        this.y = y;
        this.width = 5;
        this.height = 10;
        this.speed = speed;
        this.angle = angle;
        this.hue = hue;
      }

      update() {
        this.x += this.angle * this.speed;
        this.y += this.speed;
      }

      draw() {
        ctx.save();
        ctx.filter = `hue-rotate(${this.hue}deg)`;
        ctx.drawImage(bossBulletImage, this.x, this.y, this.width, this.height);
        ctx.restore();
      }
    }

    let stars = [];
    const NUM_STARS = 100;

    class Star {
      constructor() {
        this.x = Math.random() * canvas.width;
        this.y = Math.random() * canvas.height;
        this.size = Math.random() * 2;
        this.opacity = Math.random();
        this.fadeSpeed = 0.005 + Math.random() * 0.01;
      }

      update() {
        this.opacity += this.fadeSpeed;
        if (this.opacity > 1 || this.opacity < 0) {
          this.fadeSpeed = -this.fadeSpeed;
        }
      }

      draw() {
        ctx.fillStyle = `rgba(255, 255, 255, ${this.opacity})`;
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
        ctx.fill();
      }
    }

    function init() {
      player = new Player();
      boss = new Boss();
      gameEnded = false;
      bullets = [];
      bossBullets = [];
      bossMoveTimer = 0;
      resizeCanvas();
      gameLoop = requestAnimationFrame(update);

      stars = [];
      for (let i = 0; i < NUM_STARS; i++) {
        stars.push(new Star());
      }
    }

    function update() {
      if (!gameEnded) {
        updateGame();
        draw();
        gameLoop = requestAnimationFrame(update);
      }
    }

    function updateGame() {
      player.update();
      player.move();
      player.shoot();
      boss.move();
      boss.shoot();

      bullets.forEach((bullet, index) => {
        bullet.update();
        if (bullet.y + bullet.height < 0) {
          bullets.splice(index, 1);
        }
        if (rectCollision(bullet, boss)) {
          bullets.splice(index, 1);
          boss.health -= 1;
          boss.flashTimer = 10;
          if (boss.health <= 0) {
            gameOver(true);
          }
        }
      });

      bossBullets.forEach((bullet, index) => {
        bullet.update();
        if (bullet.y > canvas.height || bullet.x < 0 || bullet.x > canvas.width) {
          bossBullets.splice(index, 1);
        }
      });

      checkCollision(player, bossBullets);
    }

    function draw() {
      ctx.fillStyle = 'black';
      ctx.fillRect(0, 0, canvas.width, canvas.height);

      stars.forEach(star => {
        star.update();
        star.draw();
      });

      player.draw();
      boss.draw();

      ctx.fillStyle = 'green';
      const healthBarWidth = 200;
      ctx.fillRect(20, 20, (boss.health / boss.maxHealth) * healthBarWidth, 20);
      ctx.strokeStyle = 'white';
      ctx.strokeRect(20, 20, healthBarWidth, 20);

      ctx.fillStyle = 'white';
      ctx.font = '20px Arial';
      ctx.textAlign = 'right';
      ctx.fillText('Lives: ' + player.lives, canvas.width - 20, 40);

      bullets.forEach(bullet => bullet.draw());
      bossBullets.forEach(bullet => {
        if (bullet instanceof SpecialBullet) {
          bullet.draw();
        } else {
          bullet.draw();
        }
      });
    }

    function rectCollision(a, b) {
      return (
        a.x < b.x + b.width &&
        a.x + a.width > b.x &&
        a.y < b.y + b.height &&
        a.y + a.height > b.y
      );
    }

    function checkCollision(player, bullets) {
      if (player.invincibleTimer > 0) {
        return;
      }
      for (let i = 0; i < bullets.length; i++) {
        const bullet = bullets[i];
        let bulletBox;
        if (bullet instanceof SpiralBullet) {
          bulletBox = bullet.getBoundingBox();
        } else {
          bulletBox = bullet;
        }
        if (rectCollision(player, bulletBox)) {
          bullets.splice(i, 1);
          player.lives--;
          player.invincibleTimer = 60;
          if (player.lives <= 0) {
            gameOver(false);
          }
          break;
        }
      }
    }

    function gameOver(won) {
      gameEnded = true;
      cancelAnimationFrame(gameLoop);
      const endTime = Date.now();
      const timeElapsed = ((endTime - startTime) / 1000).toFixed(2);

      if (won) {
        endScreen.style.display = 'flex';
        document.getElementById('time').textContent = timeElapsed;
      } else {
        showLoseScreen();
      }

      backgroundMusic.pause();
      backgroundMusic.currentTime = 0;
    }

    function resetGame() {
      startScreen.style.display = 'flex';
      endScreen.style.display = 'none';
    }

    function handleRestart() {
      document.removeEventListener('keydown', handleRestart);
      init();
    }

    function isMobile() {
      return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
    }

    if (isMobile()) {
      document.getElementById('mobile-controls').style.display = 'block';
    }

    const joystickArea = document.getElementById('joystick-area');
    const joystick = document.getElementById('joystick');
    const shootButton = document.getElementById('shoot-button');

    let joystickActive = false;
    let shootActive = false;
    let joystickPos = {
      x: 0,
      y: 0
    };

    function handleJoystickStart(e) {
      joystickActive = true;
      updateJoystickPosition(e);
    }

    function handleJoystickMove(e) {
      if (joystickActive) {
        updateJoystickPosition(e);
      }
    }

    function handleJoystickEnd() {
      joystickActive = false;
      joystick.style.transform = 'translate(0px, 0px)';
      joystickPos = {
        x: 0,
        y: 0
      };
    }

    function updateJoystickPosition(e) {
      const rect = joystickArea.getBoundingClientRect();
      const centerX = rect.width / 2;
      const centerY = rect.height / 2;

      let x, y;
      if (e.touches) {
        x = e.touches[0].clientX - rect.left;
        y = e.touches[0].clientY - rect.top;
      } else {
        x = e.clientX - rect.left;
        y = e.clientY - rect.top;
      }

      const dx = x - centerX;
      const dy = y - centerY;
      const distance = Math.min(rect.width / 2, Math.sqrt(dx * dx + dy * dy));
      const angle = Math.atan2(dy, dx);

      const joystickX = Math.cos(angle) * distance;
      const joystickY = Math.sin(angle) * distance;

      joystick.style.transform = `translate(${joystickX}px, ${joystickY}px)`;
      joystickPos = {
        x: joystickX / (rect.width / 2),
        y: joystickY / (rect.height / 2)
      };
    }

    joystickArea.addEventListener('touchstart', handleJoystickStart);
    joystickArea.addEventListener('touchmove', handleJoystickMove);
    joystickArea.addEventListener('touchend', handleJoystickEnd);

    shootButton.addEventListener('touchstart', () => {
      shootActive = true;
    });
    shootButton.addEventListener('touchend', () => {
      shootActive = false;
    });

    function showLoseScreen() {
      const loseScreen = document.createElement('div');
      loseScreen.id = 'lose-screen';
      loseScreen.style.cssText = `
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                display: flex;
                flex-direction: column;
                justify-content: center;
                align-items: center;
                background-color: rgba(0, 0, 0, 0.8);
                color: white;
                text-align: center;
            `;
      loseScreen.innerHTML = `
                <h2>You died. Try again?</h2>
                <button id="retry-button" style="font-size: 24px; padding: 10px 20px; margin-top: 20px; cursor: pointer;">Start Game</button>
            `;
      document.body.appendChild(loseScreen);

      document.getElementById('retry-button').addEventListener('click', function() {
        document.body.removeChild(loseScreen);
        init();
        backgroundMusic.play();
      });
    }

    const backgroundImage = new Image();
    backgroundImage.src = '/content/f39d29543c4038130c35f49506a9dd6fa9750d93c54cd6b2b68c40522f1c8f85i0';

    function draw() {
      ctx.drawImage(backgroundImage, 0, 0, canvas.width, canvas.height);

      stars.forEach(star => {
        star.update();
        star.draw();
      });

      player.draw();
      boss.draw();

      ctx.fillStyle = 'green';
      const healthBarWidth = 200;
      ctx.fillRect(20, 20, (boss.health / boss.maxHealth) * healthBarWidth, 20);
      ctx.strokeStyle = 'white';
      ctx.strokeRect(20, 20, healthBarWidth, 20);

      ctx.fillStyle = 'white';
      ctx.font = '20px Arial';
      ctx.textAlign = 'right';
      ctx.fillText('Lives: ' + player.lives, canvas.width - 20, 40);

      bullets.forEach(bullet => bullet.draw());
      bossBullets.forEach(bullet => {
        if (bullet instanceof SpecialBullet) {
          bullet.draw();
        } else {
          bullet.draw();
        }
      });
    }

    const specialBulletImage = new Image();
    specialBulletImage.src = '/content/f39d29543c4038130c35f49506a9dd6fa9750d93c54cd6b2b68c40522f1c8f85i2';

    class SpecialBullet {
      constructor(x, y) {
        this.x = x - 15;
        this.y = y;
        this.width = 30;
        this.height = 30;
        this.speed = 4;
        this.horizontalSpeed = (Math.random() - 0.5) * 4;
      }

      update() {
        this.y += this.speed;
        this.x += this.horizontalSpeed;
      }

      draw() {
        ctx.drawImage(specialBulletImage, this.x, this.y, this.width, this.height);
      }
    }
  </script>
</body>

</html>
Owner Image

AGOODDOCTOR

165 days ago

who will be lucky and sell their soul on this last adventure?
Owner Image

bc1p6...9xkee

164 days ago

54 secondsI 44.18 score @linzijie198
Owner Image

@Artyomnft

161 days ago

New personal record! 56,19 @Artyomnft
Owner Image

bc1pt...7pl5v

164 days ago

@OrdiBytes 394.88 seconds!
Owner Image

Ordi4all

164 days ago

very tough but able to manage twitter: @nowayblock Score 230 Time taken: 89 sec

applejack_soup

164 days ago

1 min 47 seconds score 1237.97 @applejack_soup

Miros1av

164 days ago

@Miros1a8 33,28 seconds
Owner Image

katsu

164 days ago

Twitter Handle: katsu8888_ Score: 1485.19
Image

Sedoyisugley

164 days ago

@Sedoy_NFT 41.63

HILLSON 👽

164 days ago

kfgg finished🚀🚀🚀 1103, score
Owner Image

bc1pz...mymsu

164 days ago

twitter @iamlivliv score 135.53
Owner Image

bc1pg...cm0za

154 days ago

Lets gooo! Greetings, UniversalDutchies

BTCHUNTER

159 days ago

@BTCHUNTER228 336.21

Bitcoin The Gen

160 days ago

@BitcoinTheGen 350.52
Owner Image

bc1pp...0v9rz

161 days ago

how
Owner Image

bad bunny

161 days ago

Hi, I'm from Bitboy.games and we are looking to onboard more games on our platform to engage our users while also generating more traction for artists. I tried reaching out on twitter. If you are interested, please message me on telegram @cryptoinsights0
Owner Image

bc1p3...sefy8

161 days ago

twitter: @Chan_is_free 1198.68
Owner Image

bc1p5...kj33k

161 days ago

Hahaha 80+ seconds

simo13

161 days ago

i am ready to sell ny soul

Lunara

161 days ago

@LunaraStar 27.31
Owner Image

bc1p2...qwz0n

162 days ago

points: 46.31 time: 47 sec @Shva1ka
Owner Image

bc1pa...5qeq2

162 days ago

Now I hope this is the best result. 26,55 seconds. @Kat9malik
Owner Image

bc1p0...56t9p

162 days ago

748.17 secs @ayo_deji7
Owner Image

bc1pz...2sjdp

162 days ago

38,44 points 38 seconds, hm like people here @ChristyChibyJkt
Owner Image

bc1p5...4ax2v

162 days ago

35-36 sec, something like this :D 35.72 points @SajjaAien
  • ID

    28475...48ci0

  • Owned By
  • File Type

    HTMLtext/html;charset=utf-8

  • File Size

    23.262 KB

  • Created

    October 22, 2024, 8:31 AM UTC

    165 days ago

  • Creation Block
  • Creation Transaction
  • Creation Fee

    95,792sats

  • Tags

    No tags yet

Sat

  • Sat Number
  • Sat Name

    ycqhknwmha

  • Sat Creation Block
  • Sat Creation Year

    2024

  • Inscriptions
  • Cursed Inscriptions

    No cursed inscriptions yet

  • SATRIBUTES

    No Satributes