当前位置:首页 > 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物理引擎:

<!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θ} $$

其中θ是投篮角度,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;
}

添加用户交互控制

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

js实现投篮

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实现倒计时

使用 setInterval 实现倒计时 通过 setInterval 定时器每秒更新剩余时间,适用于简单倒计时场景。 function countdown(seconds, callbac…

js实现复制到剪贴板

js实现复制到剪贴板

使用document.execCommand方法(传统方式,已废弃但部分浏览器仍支持) 该方法适用于旧版浏览器,但已被标记为废弃。执行前需确保文本已被选中: function copyToClipb…

js轮播图实现原理

js轮播图实现原理

轮播图的基本原理 轮播图通过动态切换显示的内容(图片、文本等)实现视觉上的滑动效果。核心原理是利用CSS和JavaScript控制元素的显示与隐藏,或通过变换位置实现滑动动画。 实现方法一:CSS…

js实现报表

js实现报表

使用JavaScript实现报表 在JavaScript中实现报表功能可以通过多种方式完成,常见的方法包括使用原生JavaScript、第三方库(如Chart.js、D3.js)或结合后端数据渲染。以…

js实现百叶窗

js实现百叶窗

使用CSS和JavaScript实现百叶窗效果 通过CSS动画和JavaScript事件监听可以实现百叶窗效果。核心思路是将内容区域分割为多个条状元素,通过控制它们的展开/折叠状态来模拟百叶窗。…

js实现吸色

js实现吸色

使用Canvas实现吸色功能 通过Canvas的getImageData方法获取像素颜色数据。创建一个Canvas元素,将目标图像绘制到Canvas上,通过鼠标事件获取坐标对应的颜色值。 const…