Javascript Canvas/JS:通过与倾斜坡度的碰撞计算对象的新速度向量?

Javascript Canvas/JS:通过与倾斜坡度的碰撞计算对象的新速度向量?,javascript,canvas,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

好的,我正在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);
顺便说一句,我不是在计算鳍状肢的速度。我只是想知道如何改变球的速度向量,相对于线的斜率。谢谢

反射向量 作为反射向量的基本反弹很简单

给一行

const line = {  // numbers are arbitrary
   p1 : { x : 0, y : 0 },
   p2 : { x : 0, y : 0 }
}
还有一个球

const ball = {
   pos : { x : 0, y: 0},
   radius : 0,
   delta : { x : 0, y : 0},  // movement as vector
}
首先将行转换为更易于管理的形式

 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;
还将球三角化

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;
现在反射使用向量

// 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;
反射向量只需要归一化,然后乘以球的速度减去击球时的能量损失

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;
演示 不是100%的我得到了正确的数学,我认为最好用一个演示来检查。我忘了这有多复杂

演示显示了移动的线条,但移动不会转移到球上

var W,H;//画布宽度和高度
//获取画布上下文
const ctx=canvas.getContext(“2d”);
恒重力=0.19;
函数vec(x,y){返回{x,y}
常量行={
p1:{x:0,y:0},
p2:{x:0,y:0},
vnorm:{x:0,y:0},//归一化向量
vec:{x:0,y:0},//作为向量的行
蓝:0,
更新(){
this.vec.x=this.p2.x-this.p1.x;
this.vec.y=this.p2.y-this.p1.y;
this.len=Math.sqrt(this.vec.x*this.vec.x+this.vec.y*this.vec.y);
this.vnorm.x=this.vec.x/this.len;
this.vnorm.y=this.vec.y/this.len;
},
画(){
ctx.beginPath();
ctx.moveTo(this.p1.x,this.p1.y);
ctx.lineTo(this.p2.x,this.p2.y);
ctx.stroke();
},
testBall(ball){//必须在进行此调用之前更新行
//线是单边的,球只能从右边接近
//查找直线半径到直线的距离
var x=this.p1.x+this.vnorm.y*ball.radius;
var y=this.p1.y-this.vnorm.x*ball.radius;
x=球位置x-x;
y=球位置y-y;
//让克罗斯积看看球是否击中了线
var c=x*this.vec.y-y*this.vec.x;
如果(c.高度||
球。项目[i]。位置x<-50 | |球。项目[i]。位置x-50>W){
球.项目.拼接(i--,1);
}
}
回球;
},
画(){
var i;
对于(i=0;i{
mouse.x=e.pageX;
mouse.y=e.pageY;
})
函数主循环(时间){
//根据需要调整大小
如果(canvas.width!==innerWidth | | canvas.height!==innerHeight){//如果窗口大小已更改,请调整画布大小
W=画布宽度=内部宽度;
H=画布。高度=内部高度;
}
//透明帆布
setTransform(1,0,0,1,0,0);//设置默认转换
clearRect(0,0,W,H);//清除画布
如果(球.项目.长度<10){
添加(创建球(Math.random()*W,Math.random()*30,Math.random()*20+10));
}
时间/=5;
l1.p1.x=0;
l1.p2.x=W;
l2.p1.x=0;
l2.p2.x=W;
l1.p1.y=数学sin(时间/1000)*H*0.4+H*0.6;
l1.p2.y=数学cos(时间/1000)*H*0.4+H*0.6;
l2.p1.y=数学sin(时间/500)*H*0.4+H*0.6;
l2.p2.y=数学cos(时间/500)*H*0.4+H*0.6;
line.update().draw();
balls.update().draw();
//获取下一个动画循环
requestAnimationFrame(主循环);
}
requestAnimationFrame(主循环)
画布{
位置:绝对位置;
顶部:0px;
左:0px;
z指数:-10;
}