当前位置:首页 > JavaScript

js实现投篮

2026-02-01 17:26:26JavaScript

使用Canvas绘制投篮动画

创建一个HTML文件并添加Canvas元素,通过JavaScript绘制篮球和篮筐的动画效果。以下是一个简单的投篮动画实现:

<!DOCTYPE html>
<html>
<head>
    <title>投篮动画</title>
    <style>
        canvas {
            border: 1px solid black;
        }
    </style>
</head>
<body>
    <canvas id="basketballCanvas" width="800" height="500"></canvas>
    <script>
        const canvas = document.getElementById('basketballCanvas');
        const ctx = canvas.getContext('2d');

        // 篮球属性
        let ball = {
            x: 100,
            y: 400,
            radius: 20,
            color: 'orange',
            speedX: 5,
            speedY: -15,
            gravity: 0.5
        };

        // 篮筐属性
        const hoop = {
            x: 600,
            y: 200,
            width: 80,
            height: 5
        };

        function drawBall() {
            ctx.beginPath();
            ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
            ctx.fillStyle = ball.color;
            ctx.fill();
            ctx.closePath();

            // 篮球纹理
            ctx.beginPath();
            ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI, false);
            ctx.strokeStyle = 'black';
            ctx.lineWidth = 2;
            ctx.stroke();
            ctx.closePath();
        }

        function drawHoop() {
            ctx.fillStyle = 'red';
            ctx.fillRect(hoop.x, hoop.y, hoop.width, hoop.height);

            // 篮筐支撑
            ctx.fillRect(hoop.x + hoop.width - 5, hoop.y, 5, 30);
        }

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

            // 更新篮球位置
            ball.x += ball.speedX;
            ball.y += ball.speedY;
            ball.speedY += ball.gravity;

            // 边界检测
            if (ball.y + ball.radius > canvas.height) {
                ball.y = canvas.height - ball.radius;
                ball.speedY *= -0.7; // 反弹
            }

            // 篮筐碰撞检测
            if (ball.x + ball.radius > hoop.x && 
                ball.x - ball.radius < hoop.x + hoop.width &&
                ball.y + ball.radius > hoop.y && 
                ball.y - ball.radius < hoop.y + hoop.height) {
                ball.speedY *= -0.5;
            }

            drawHoop();
            drawBall();

            requestAnimationFrame(update);
        }

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

使用物理引擎实现更真实的投篮

对于更真实的物理效果,可以使用Matter.js物理引擎:

js实现投篮

<!DOCTYPE html>
<html>
<head>
    <title>物理投篮</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.18.0/matter.min.js"></script>
    <style>
        canvas {
            border: 1px solid black;
        }
    </style>
</head>
<body>
    <canvas id="physicsCanvas"></canvas>
    <button id="shoot">投篮</button>
    <script>
        const Engine = Matter.Engine,
              Render = Matter.Render,
              World = Matter.World,
              Bodies = Matter.Bodies;

        const engine = Engine.create();
        const render = Render.create({
            canvas: document.getElementById('physicsCanvas'),
            engine: engine,
            options: {
                width: 800,
                height: 500,
                wireframes: false
            }
        });

        // 创建地面
        const ground = Bodies.rectangle(400, 490, 810, 20, { isStatic: true });

        // 创建篮筐
        const hoop = Bodies.rectangle(600, 200, 80, 10, { isStatic: true });
        const backboard = Bodies.rectangle(680, 215, 10, 50, { isStatic: true });

        // 篮球
        const ball = Bodies.circle(100, 400, 20, {
            restitution: 0.8,
            render: {
                fillStyle: 'orange',
                strokeStyle: 'black',
                lineWidth: 2
            }
        });

        World.add(engine.world, [ground, hoop, backboard, ball]);

        Engine.run(engine);
        Render.run(render);

        document.getElementById('shoot').addEventListener('click', function() {
            Matter.Body.setPosition(ball, { x: 100, y: 400 });
            Matter.Body.setVelocity(ball, { x: 15, y: -20 });
            Matter.Body.setAngularVelocity(ball, 0.1);
        });
    </script>
</body>
</html>

添加投篮抛物线计算

投篮时需要考虑抛物线轨迹,可以使用以下公式计算投篮角度和力度:

$$ y = x \tanθ - \frac{gx^2}{2v^2 \cos^2θ} $$

js实现投篮

其中θ是投篮角度,v是初始速度,g是重力加速度。

function calculateTrajectory(angle, power) {
    const g = 0.5; // 重力
    const angleRad = angle * Math.PI / 180; // 角度转弧度
    const v = power; // 初始速度

    let points = [];
    for (let x = 0; x < 800; x += 10) {
        const y = x * Math.tan(angleRad) - (g * x * x) / (2 * v * v * Math.cos(angleRad) * Math.cos(angleRad));
        points.push({ x: ball.x + x, y: ball.y - y });
    }
    return points;
}

添加用户交互控制

让用户可以通过鼠标或触摸屏控制投篮力度和角度:

let isDragging = false;
let startPos = { x: 0, y: 0 };

canvas.addEventListener('mousedown', (e) => {
    const rect = canvas.getBoundingClientRect();
    startPos = {
        x: e.clientX - rect.left,
        y: e.clientY - rect.top
    };
    isDragging = true;
});

canvas.addEventListener('mouseup', (e) => {
    if (!isDragging) return;

    const rect = canvas.getBoundingClientRect();
    const endPos = {
        x: e.clientX - rect.left,
        y: e.clientY - rect.top
    };

    // 计算力度和角度
    const dx = startPos.x - endPos.x;
    const dy = startPos.y - endPos.y;
    const power = Math.min(Math.sqrt(dx * dx + dy * dy) / 10, 30);
    const angle = Math.atan2(dy, dx);

    // 设置篮球速度
    ball.speedX = power * Math.cos(angle);
    ball.speedY = power * Math.sin(angle);

    isDragging = false;
});

标签: js
分享给朋友:

相关文章

js实现跳转

js实现跳转

使用 window.location 跳转 通过修改 window.location.href 或直接使用 window.location 实现页面跳转,适用于普通跳转或带参数的 URL。 //…

js实现跳转

js实现跳转

使用 window.location 跳转 通过修改 window.location.href 实现页面跳转,这是最常用的方法。 window.location.href = 'https://…

js实现日历

js实现日历

实现日历的基本思路 使用JavaScript实现日历的核心是动态生成日期表格,并处理月份切换逻辑。需要计算当前月的天数、起始星期几,并动态渲染到页面上。 获取当前日期信息 通过Date对象获取当前…

js实现选项卡

js实现选项卡

实现选项卡的基本思路 选项卡通常由一组标签和对应的内容面板组成。点击标签时,显示对应的内容面板,隐藏其他面板。实现这一效果需要结合HTML结构、CSS样式和JavaScript交互逻辑。 HTML…

js实现列表

js实现列表

使用 JavaScript 实现列表 JavaScript 提供了多种方式来实现列表功能,包括数组操作、DOM 元素动态生成等。以下是几种常见的实现方法: 使用数组存储列表数据 数组是 JavaS…

js实现换肤

js实现换肤

使用CSS变量实现换肤 通过CSS变量可以轻松实现主题切换功能。CSS变量在根元素中定义,通过JavaScript动态修改这些变量值。 :root { --primary-color: #34…