Javascript 使一个圆重叠时不被另一个圆排斥?

Javascript 使一个圆重叠时不被另一个圆排斥?,javascript,canvas,physics,collision,Javascript,Canvas,Physics,Collision,我已经写了一个代码,其中有两个圆圈跟随鼠标。我成功地进行了碰撞检测,目前效果很好,但我无法使圆圈保持在一起而不被排斥 我曾经尝试过使用一个布尔值,当它们重叠时设置为true,然后我检查该布尔值是否为true,然后我再次将加速度乘以-1,但它不起作用,因为它们只是“合并” 我也尝试过将另一个圆的半径添加到它的位置,但它只是一个“传送”。这不是学校作业,这是个人项目:)) 编辑:预期的行为不会被另一个圆排斥,而是保持在一起,围绕该圆移动并前进到鼠标位置而不会被排斥。就像在游戏agar.io中一样,当

我已经写了一个代码,其中有两个圆圈跟随鼠标。我成功地进行了碰撞检测,目前效果很好,但我无法使圆圈保持在一起而不被排斥

我曾经尝试过使用一个布尔值,当它们重叠时设置为true,然后我检查该布尔值是否为true,然后我再次将加速度乘以-1,但它不起作用,因为它们只是“合并”

我也尝试过将另一个圆的半径添加到它的位置,但它只是一个“传送”。这不是学校作业,这是个人项目:))

编辑:预期的行为不会被另一个圆排斥,而是保持在一起,围绕该圆移动并前进到鼠标位置而不会被排斥。就像在游戏agar.io中一样,当细胞移动和碰撞时分裂细胞时,它们不会相互排斥,但会平滑地相互移动

//设置所有
const canvas=document.getElementById(“cv”);
const ctx=canvas.getContext(“2d”);
canvas.width=内部宽度;
canvas.height=内部高度;
//数学变量和实用程序
常数PI=Math.PI;
常数2_PI=PI*2;
常数半π=π/2;
常数随机=(n1,n2=0)=>{
返回Math.random()*(n2-n1)+n1;
};
常数距离=(n1、n2、n3、n4)=>{
设dX=n1-n3;
设dY=n2-n4;
返回Math.sqrt(dX*dX+dY*dY);
};
设圆=[];//存储两个圆的数组
让鼠标={
x:0,,
y:0
}; // 鼠标对象
//创建circle类
功能圈(px、py、r、ctx){
this.x=px;//x位置
this.y=py;//y位置
this.r=r;//半径
this.ctx=ctx;//画布上下文
this.acc=0.005;//硬编码加速度值
//画圈函数
this.show=函数(){
this.ctx.beginPath();
this.ctx.fillStyle=“#fff”;
this.ctx.arc(this.x,this.y,this.r,0,TWO_PI,false);
这个.ctx.fill();
};
this.update=函数(x,y){
//鼠标的X和Y坐标与圆的//X和Y坐标之间的距离
设距离={
x:x-这个.x,
y:y-这个,y
};
//上述距离公式
设d=距离(x,y,this.x,this.y);
如果(d>1){
this.x+=dist.x*this.acc;
this.y+=dist.y*this.acc;
}
};
//圆碰撞
this.collides=函数(其他){
设d1=距离(此.x,此.y,其他.x,其他.y);
如(d1){
//只生成两个圆
for(设i=0;i<2;i++){
圆。推(新圆(随机(canvas.width/2)、随机(canvas.height/2)、50、ctx));
}
};
genCircles();
//显示和更新圆
常量showCircles=()=>{
for(设i=0;i{
鼠标x=e.x;
小鼠y=e.y;
},对);
//在圆上迭代以检查碰撞
对于(设j=0;j{
requestAnimationFrame(更新);
clearRect(0,0,canvas.width,canvas.height);
ctx.fillStyle=“#000”;
ctx.fillRect(0,0,canvas.width,canvas.height);
演艺圈();
};
更新();
html正文{
保证金:0;
填充:0;
溢出:隐藏;
显示:块;
}

这还远远不够完美,但我想到的是:你可以更新“中心”基于碰撞圆的每个圆的
x
y
。对于每个碰撞圆,
x
y
成为这些圆的两个中心值之间的中点。这些值未设置为
this.x
this.y
,否则它们会异常跳转。取而代之的是这个新的“相对值”
x
y
仅在确定每次绘制的行进距离时计算和使用。底部的代码片段并不完全正确,因为它最终不是在右侧的
x,y
,而是让您知道它应该做什么。其他人可以随意在我这里的t中构建继承人自己的答案或对我的编辑

//设置所有
const canvas=document.getElementById(“cv”);
const ctx=canvas.getContext(“2d”);
canvas.width=内部宽度;
canvas.height=内部高度;
//数学变量和实用程序
常数PI=Math.PI;
常数2_PI=PI*2;
常数半π=π/2;
常数随机=(n1,n2=0)=>{
返回Math.random()*(n2-n1)+n1;
};
常数距离=(n1、n2、n3、n4)=>{
设dX=n1-n3;
设dY=n2-n4;
返回Math.sqrt(dX*dX+dY*dY);
};
let circles=[];//存储两个圆的数组
让鼠标={
x:0,,
y:0
};//鼠标对象
//创建circle类
功能圈(px、py、r、ctx){
this.x=px;//x位置
this.y=py;//y位置
this.r=r;//半径
this.ctx=ctx;//画布上下文
this.acc=0.005;//硬编码加速度值
//画圈函数
this.show=函数(){
this.ctx.beginPath();
this.ctx.fillStyle=“#fff”;
this.ctx.arc(this.x,this.y,this.r,0,TWO_PI,false);
这个.ctx.fill();
};
this.update=函数(x,y){
//鼠标的X和Y坐标与圆的//X和Y坐标之间的距离
var-reletave={x:this.x,y:this.y};
圆。forEach((cir)=>{
如果(cir==此)返回;
如果(本次碰撞(cir)){
var floor={x:Math.floor(cir.x,reltave.x),y:Math.floor(cir.y,reltave.y)};
var dist={x:Math.abs(cir.x-reletave.x),y:Math.abs(cir.y-reletave.y)};
reletave.x=楼层x+距离x;
reletave.y=楼层y+距离y;
}
})
设距离={
x:x-relitave.x,