Canvas / JS:通过倾斜倾斜碰撞计算物体的新速度矢量?

spe*_*cto 2 javascript canvas

好吧,所以我正在研究JS / Canvas上的弹球游戏,我想知道如何处理脚蹼和球之间的碰撞。

我可以使鳍状肢击球,但是对于如何通过变化的鳍状肢位置(角度)来改变球的速度方向感到困惑。这是我可以从脚蹼和球中使用的信息:

this.ballPosX = ballPosX;
this.ballPosY = ballPosY;
this.ballVelX = 0;
this.ballVelY = 0;

// thruster is a line shape with a variable end Y position
ctx.moveTo(125, 480);
ctx.lineTo(215, this.posY);
Run Code Online (Sandbox Code Playgroud)

我没有计算脚蹼的速度。我只想知道关于线的斜率如何更改球速度矢量指向矢。谢谢!

Bli*_*n67 5

反映的向量

作为反射向量的基本反弹很容易实现。

给定一行

const line = {  // numbers are arbitrary
   p1 : { x : 0, y : 0 },
   p2 : { x : 0, y : 0 }
}
Run Code Online (Sandbox Code Playgroud)

和一个球

const ball = {
   pos : { x : 0, y: 0},
   radius : 0,
   delta : { x : 0, y : 0},  // movement as vector
}
Run Code Online (Sandbox Code Playgroud)

首先将生产线转换为更易于管理的形式

 line.vec = {};  // get vector for the line
 line.vec.x = line.p2.x - line.p1.x;
 line.vec.y = line.p2.y - line.p1.y;
 // get line length
 line.len = Math.sqrt(line.vec.x * line.vec.x + line.vec.y * line.vec.y);
 // the normalised vector (1 unit long)
 line.vnorm = {};
 line.vnorm.x = line.vec.x / line.len;
 line.vnorm.y = line.vec.y / line.len;
Run Code Online (Sandbox Code Playgroud)

同时标准化球的三角洲

ball.speed = Math.sqrt(ball.delta.x * ball.delta.x + ball.delta.y * ball.delta.y);
ball.dnorm = {};
ball.dnorm.x = ball.delta.x / ball.speed;
ball.dnorm.y = ball.delta.y / ball.speed;
Run Code Online (Sandbox Code Playgroud)

现在反射使用向量

// ball velocity vector line normal dot product times 2
var dd = (ball.dnorm.x * line.vnorm.x + ball.dnorm.y * line.vnorm.y) * 2
ball.ref = {}; // the balls reflected delta
ball.ref.x = line.vnorm.x * dd - ball.dnorm.x;
ball.ref.y = line.vnorm.y * dd - ball.dnorm.y;
Run Code Online (Sandbox Code Playgroud)

只需将反射向量标准化,然后乘以球速减去击中线时的任何能量损失即可。

var len = Math.sqrt(ball.ref.x * ball.ref.x + ball.ref.y * ball.ref.y);
ball.delta.x = (ball.ref.x / len) * ball.speed; // I have kept the same speed.
ball.delta.y = (ball.ref.y / len) * ball.speed;
Run Code Online (Sandbox Code Playgroud)

演示版

不是100%,我的数学正确,我认为最好通过演示进行检查。我忘了这变得多么复杂。

演示显示了运动线,但运动并未传递到球上。

const line = {  // numbers are arbitrary
   p1 : { x : 0, y : 0 },
   p2 : { x : 0, y : 0 }
}
Run Code Online (Sandbox Code Playgroud)
const ball = {
   pos : { x : 0, y: 0},
   radius : 0,
   delta : { x : 0, y : 0},  // movement as vector
}
Run Code Online (Sandbox Code Playgroud)
 line.vec = {};  // get vector for the line
 line.vec.x = line.p2.x - line.p1.x;
 line.vec.y = line.p2.y - line.p1.y;
 // get line length
 line.len = Math.sqrt(line.vec.x * line.vec.x + line.vec.y * line.vec.y);
 // the normalised vector (1 unit long)
 line.vnorm = {};
 line.vnorm.x = line.vec.x / line.len;
 line.vnorm.y = line.vec.y / line.len;
Run Code Online (Sandbox Code Playgroud)