Javascript 当球与矩形碰撞时,如何更改角度?

Javascript 当球与矩形碰撞时,如何更改角度?,javascript,math,collision-detection,trigonometry,angle,Javascript,Math,Collision Detection,Trigonometry,Angle,如果一个圆碰到一个矩形需要反弹,我需要计算它的新方向 这就是我所拥有的 function tick() { var dx = Math.cos(ball.direction * (Math.PI / 180))*ball_md.speed; var dy = Math.sin(ball.direction * (Math.PI / 180))*ball_md.speed; ball.x += dx; ball.y -= dy

如果一个圆碰到一个矩形需要反弹,我需要计算它的新方向

这就是我所拥有的

    function tick() {
        var dx = Math.cos(ball.direction * (Math.PI / 180))*ball_md.speed;
        var dy = Math.sin(ball.direction * (Math.PI / 180))*ball_md.speed;
        ball.x += dx;
        ball.y -= dy;
        drawGame(); // refresh board

        //console.log(ball);

        paddles.some(function(paddle) {
            var circle={x:ball.x+ball_md.radius, y:ball.y+ball_md.radius, r:ball_md.radius};
            var rect={x:paddle.x, y:paddle.y, w:game_md.paddle.width, h:game_md.paddle.height};
            var hit = RectCircleColliding(circle, rect);

            if (hit) {
                if (Math.floor(ball.y) + ball_md.radius*2 <= paddle.y || Math.ceil(ball.y) >= paddle.y + game_md.paddle.height) { // hit on top or below paddle
                    ball.direction = 360 - ball.direction; 
                } else { // hit left or right side
                    ball.direction = 180 - ball.direction;  
                }
                return true;
            }
        });

        if (ball.y < 0 || ball.y+ball_md.radius*2 >= game_md.height) { // hit top or bottom wall
            ball.direction = 360 - ball.direction; 
        }
        if (ball.x < 0 || ball.x+ball_md.radius*2 >= game_md.width) { // hit left or right wall
            ball.direction = 180 - ball.direction;   
        }
    }
函数tick(){
var dx=数学cos(球方向*(数学PI/180))*球速度;
var dy=数学sin(球方向*(数学PI/180))*球速度;
ball.x+=dx;
ball.y-=dy;
drawGame();//刷新棋盘
//控制台。原木(球);
桨。一些(功能(桨){
var circle={x:ball.x+ball_md.radius,y:ball.y+ball_md.radius,r:ball_md.radius};
var rect={x:paile.x,y:paile.y,w:game_md.paile.width,h:game_md.paile.height};
var hit=矩形圆形集合(圆形,矩形);
如果(命中){
如果(数学地板(ball.y)+ball_md.radius*2=桨.y+游戏桨.高度){//在桨顶部或下方击球
ball.direction=360-ball.direction;
}否则{//点击左侧或右侧
ball.direction=180-ball.direction;
}
返回true;
}
});
如果(ball.y<0 | | ball.y+ball|md.radius*2>=游戏高度){//击中顶部或底部墙壁
ball.direction=360-ball.direction;
}
如果(ball.x<0 | | | ball.x+ball|md.radius*2>=游戏宽度){//击中左墙或右墙
ball.direction=180-ball.direction;
}
}
但它似乎并不总是奏效。有人知道为什么吗

当它失败的时候。在这种情况下,它在桨叶表面的锯齿形速度非常快


演示:

您需要单独处理拐角碰撞。当球击中角点时,球的速度不会垂直于水平轴或垂直轴改变,而是沿着连接球中心和角点的线改变。我加了一张图,让它更清楚一点。如果碰撞是完全弹性的(没有能量损失),则
v_normal
组件将被其负值
-v_normal
替换。如果碰撞是完全塑性的(最大能量损失),则退出速度仅为切向。希望这有帮助


我会记录每一次反弹,看看是否有一个模式,当它不起作用时。
但它似乎并不总是起作用。
它目前在做什么,应该做什么?当它碰到拐角时会失败。添加你的积分器代码。如果你没有将球移回碰撞位置,并从该点与反射方向重新积分,球可能会来回摆动,不断反转其方向,因为它实际上从未脱离墙/桨。奇怪的是,人们经常使用速度的极坐标表示,当基于向量的方法避免不断地处理360度的奇点时(并使用
sin/cos
)。