10 javascript canvas
我一直在创建一个agar.io的克隆,我不明白为什么这些圆圈在相互接触时会开始振动.以下是我的代码:
var
canvas,
ctx,
width = innerWidth,
height = innerHeight,
mouseX = 0,
mouseY = 0;
var
camera = {
x: 0,
y: 0,
update: function(obj) {
this.x = obj.x - width / 2;
this.y = obj.y - height / 2;
}
},
player = {
defaultMass: 54,
x: 0,
y: 0,
blobs: [],
update: function() {
for (var i = 0; i < this.blobs.length; i++) {
var x = mouseX + camera.x - this.blobs[i].x;
var y = mouseY + camera.y - this.blobs[i].y;
var length = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
var speed = 54 / this.blobs[i].mass;
this.blobs[i].velX = x / length * speed * Math.min(1, Math.pow(x / this.blobs[i].mass, 2));
this.blobs[i].velY = y / length * speed * Math.min(1, Math.pow(x / this.blobs[i].mass, 2));
this.blobs[i].x += this.blobs[i].velX;
this.blobs[i].y += this.blobs[i].velY;
for (var j = 0; j < this.blobs.length; j++) {
if (j != i && this.blobs[i] !== undefined) {
var blob1 = this.blobs[i];
var blob2 = this.blobs[j];
var dist = Math.sqrt(Math.pow(blob2.x - blob1.x, 2) + Math.pow(blob2.y - blob1.y, 2));
if (dist < blob1.mass + blob2.mass) {
if (this.blobs[i].x < this.blobs[j].x) {
this.blobs[i].x--;
} else if (this.blobs[i].x > this.blobs[j].x) {
this.blobs[i].x++;
}
if (this.blobs[i].y < this.blobs[j].y) {
this.blobs[i].y--;
} else if ((this.blobs[i].y > this.blobs[j].y)) {
this.blobs[i].y++;
}
}
}
}
}
this.x += (mouseX - width / 2) / (width / 2) * 1;
this.y += (mouseY - height / 2) / (height / 2) * 1
},
split: function(cell) {
cell.mass /= 2;
this.blobs.push({
x: cell.x,
y: cell.y,
mass: cell.mass
});
},
draw: function() {
for (var i = 0; i < this.blobs.length; i++) {
ctx.fillStyle = "red";
ctx.beginPath();
ctx.arc(-camera.x + this.blobs[i].x, -camera.y + this.blobs[i].y, this.blobs[i].mass, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
}
}
};
function handleMouseMove(e) {
mouseX = e.clientX;
mouseY = e.clientY;
}
function setup() {
canvas = document.getElementById("game");
ctx = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
addEventListener("mousemove", handleMouseMove);
player.blobs.push({
x: 0,
y: 0,
mass: player.defaultMass
});
player.blobs.push({
x: 100,
y: 100,
mass: player.defaultMass / 2
});
player.blobs.push({
x: 100,
y: 100,
mass: player.defaultMass * 2
});
var loop = function() {
update();
draw();
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
}
function update() {
camera.update(player.blobs[0]);
player.update();
}
function draw() {
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, width, height);
player.draw();
}
setup();Run Code Online (Sandbox Code Playgroud)
body {
margin: 0;
padding: 0;
}Run Code Online (Sandbox Code Playgroud)
<canvas id="game">kindly update your browser.</canvas>Run Code Online (Sandbox Code Playgroud)
您的分隔代码不正确。使用它们之间的向量来获取新的位置。
要确定两个圆是否相交,请找出从一个圆到下一个圆的向量的长度
两个圆圈。
var cir1 = {x : 100, y : 100, r : 120}; // r is the radius
var cir2 = {x : 250, y : 280, r : 150}; // r is the radius
Run Code Online (Sandbox Code Playgroud)
向量从cir2到cir1
var vx = cir2.x - cir1.x;
var vy = cir2.y - cir1.y;
Run Code Online (Sandbox Code Playgroud)
向量的长度
var len = Math.sqrt(x * x + y * y);
// or use the ES6 Math.hypot function
/* var len = Math.hypot(x,y); */
Run Code Online (Sandbox Code Playgroud)
如果半径之和大于圆之间矢量的长度,则圆重叠
if(cir1.r + cir2.r > len){ // circles overlap
Run Code Online (Sandbox Code Playgroud)
如果它们重叠,您需要将其中一个远离另一个。有很多方法可以做到这一点,最简单的方法是沿着它们之间的线移动一个圆圈。
首先通过除以向量的(向量)长度来标准化向量从cir1到 的值。cir2
vx \= len;
vy \= len;
Run Code Online (Sandbox Code Playgroud)
请注意,长度可以为零。如果发生这种情况,您将进行NaN进一步的计算。如果您怀疑您可能会在与另一个圆相同的位置得到一个圆,那么处理零的最简单方法是稍微移动一个圆。
// replace the two lines above with
if(len === 0){ // circles are on top of each other
vx = 1; // move the circle (abstracted into the vector)
}else{
vx \= len; // normalise the vector
vy \= len;
}
Run Code Online (Sandbox Code Playgroud)
vx现在您有了 1 个单位长的归一化向量,您可以通过将两个标量乘以所需的长度(vy在本例中为两个圆半径之和)来使其成为所需的任何长度。
var mx = vx * (cir1.r + cir2.r); // move distance
var my = vy * (cir1.r + cir2.r);
Run Code Online (Sandbox Code Playgroud)
。仅使用以下方法之一。
现在,您可以将其中一个圆圈放置在正确的距离处,以便它们刚好接触
// move cir1
cir1.x = cir2.x - mx;
cir1.y = cir2.y - my;
Run Code Online (Sandbox Code Playgroud)
或者移动第二个圆圈
cir2.x = cir1.x + mx;
cir2.y = cir1.y + my;
Run Code Online (Sandbox Code Playgroud)
或者移动两个圆,但你必须首先找到两个圆之间的比例中心
var pLen = cir1.r / (cir1.r + cir2.r); // find the ratio of the radii
var cx = cir1.x + pLen * vx * len; // find the proportional center between
var cy = cir1.y + pLen * vy * len; // the two circles
Run Code Online (Sandbox Code Playgroud)
然后将两个圆从该点移开其半径
cir1.x = cx - vx * cir1.r; // move circle 1 away from the shared center
cir1.y = cy - vy * cir1.r;
cir2.x = cx + vx * cir2.r; // move circle 2 away from the shared center
cir2.y = cy + vy * cir2.r;
Run Code Online (Sandbox Code Playgroud)
带有 mods 的 OP 代码片段的副本,通过将第一个圆圈移blob1离第二个圆圈blob2并假设它们永远不会位于同一位置(不除以零)来解决问题
var cir1 = {x : 100, y : 100, r : 120}; // r is the radius
var cir2 = {x : 250, y : 280, r : 150}; // r is the radius
Run Code Online (Sandbox Code Playgroud)
var vx = cir2.x - cir1.x;
var vy = cir2.y - cir1.y;
Run Code Online (Sandbox Code Playgroud)
var len = Math.sqrt(x * x + y * y);
// or use the ES6 Math.hypot function
/* var len = Math.hypot(x,y); */
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
108 次 |
| 最近记录: |