Basketball Shot Game

by kidastudio

HTML

<h2>Basketball Shot Game</h2>

  <div class="controls">
    Angle:
    <input type="range" id="angleRange" min="20" max="80" value="45" oninput="angleInput.value=this.value">
    <input type="number" id="angleInput" min="20" max="80" value="45" oninput="angleRange.value=this.value">
    &nbsp; Power:
    <input type="range" id="powerRange" min="10" max="40" value="25" oninput="powerInput.value=this.value">
    <input type="number" id="powerInput" min="10" max="40" value="25" oninput="powerRange.value=this.value">
    <button onclick="shoot()">Shoot</button>
  </div>

  <canvas id="gameCanvas" width="800" height="400"></canvas>

  <!-- Hidden basketball image -->
  <img id="ballImage" src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Basketball.png" width="20" style="display: none;">

CSS

canvas {
      border: 1px solid black;
      background: #f0f0f0;
      display: block;
      margin-top: 10px;
    }
    .controls {
      margin-bottom: 10px;
    }
    input {
      width: 60px;
    }

JavaScript

const canvas = document.getElementById("gameCanvas");
    const ctx = canvas.getContext("2d");

    const angleInput = document.getElementById("angleInput");
    const angleRange = document.getElementById("angleRange");
    const powerInput = document.getElementById("powerInput");
    const powerRange = document.getElementById("powerRange");

    const ballImg = document.getElementById("ballImage");

    const hoop = { x: 650, y: 250, r: 20 };
    const gravity = 9.8;

    function shoot() {
      const angleDeg = parseFloat(angleInput.value);
      const power = parseFloat(powerInput.value);

      const angle = angleDeg * Math.PI / 180;
      const speed = power * 5; // scale power to pixel/second speed

      const vx = speed * Math.cos(angle);
      const vy = -speed * Math.sin(angle); // negative because canvas Y is downward

      let x = 100;
      let y = 350;
      let t = 0;
      const dt = 0.05;
      const path = [];

      function update() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);

        // Draw hoop
        ctx.beginPath();
        ctx.arc(hoop.x, hoop.y, hoop.r, 0, 2 * Math.PI);
        ctx.strokeStyle = "red";
        ctx.lineWidth = 3;
        ctx.stroke();

        const xt = x + vx * t;
        const yt = y + vy * t + 0.5 * gravity * (t * t);

        path.push({ x: xt, y: yt });

        // Draw trail (dots)
        for (let i = 0; i < path.length - 1; i++) {
          const p = path[i];
          ctx.beginPath();
          ctx.arc(p.x, p.y, 2, 0, 2 * Math.PI);
          ctx.fillStyle = "orange";
          ctx.fill();
        }

        // Draw ball image at current position
        const p = path[path.length - 1];
        ctx.drawImage(ballImg, p.x - 10, p.y - 10, 20, 20);

        // Check if it scores
        const dx = xt - hoop.x;
        const dy = yt - hoop.y;
        const dist = Math.sqrt(dx * dx + dy * dy);
        if (dist < hoop.r) {
         ...