Я написал код, в котором за мышью следуют два круга. Мне удалось сделать обнаружение столкновений, на данный момент оно работает нормально, но я не могу заставить круги оставаться вместе, не отталкиваясь.
Я пытался использовать логическое значение, для которого установлено значение true, всякий раз, когда они перекрываются, а затем я проверял, истинно ли это логическое значение, и снова умножал ускорение на -1, но это просто не работает, поскольку они просто «сливаются».
Я также попытался добавить радиус другого круга к его положению, но он просто делает «телепорт». Это не школьная домашка, это личный проект :) )
РЕДАКТИРОВАТЬ: ожидаемое поведение состоит в том, чтобы не отталкиваться от другого круга, а оставаться вместе, перемещаться по кругу и продвигаться к позиции мыши, не будучи отталкиваемым. Так же, как и в игре agar.io, когда вы разделяете клетки, когда они двигаются и сталкиваются, они не отталкиваются, а плавно перемещаются друг вокруг друга.
// Setting all up
const canvas = document.getElementById("cv");
const ctx = canvas.getContext("2d");
canvas.width = innerWidth;
canvas.height = innerHeight;
// Math Variables and utilities
const PI = Math.PI;
const TWO_PI = PI * 2;
const HALF_PI = PI / 2;
const random = (n1, n2 = 0) => {
return Math.random() * (n2 - n1) + n1;
};
const distance = (n1, n2, n3, n4) => {
let dX = n1 - n3;
let dY = n2 - n4;
return Math.sqrt(dX * dX + dY * dY);
};
let circles = []; // Array that stores the two circles
let mouse = {
x: 0,
y: 0
}; // mouse object
// Creating the circle class
function Circle(px, py, r, ctx) {
this.x = px; // X Position
this.y = py; // Y Position
this.r = r; // Radius
this.ctx = ctx; // Canvas context
this.acc = 0.005; // HardCoded acceleration value
// Draw circle function
this.show = function() {
this.ctx.beginPath();
this.ctx.fillStyle = "#fff";
this.ctx.arc(this.x, this.y, this.r, 0, TWO_PI, false);
this.ctx.fill();
};
this.update = function(x, y) {
// Distance between the mouse's X and Y coords and circle's // X and Y coords
let dist = {
x: x - this.x,
y: y - this.y
};
// Distance formula stated above
let d = distance(x, y, this.x, this.y);
if (d > 1) {
this.x += dist.x * this.acc;
this.y += dist.y * this.acc;
}
};
// Circle collision
this.collides = function(other) {
let d1 = distance(this.x, this.y, other.x, other.y);
if (d1 <= other.r + this.r) {
//this.acc *= -1;
// Do stuff to make the circle that collides to round the other
// Without getting inside it
}
}
}
// Generating the circles
const genCircles = () => {
// Just generating two circles
for (let i = 0; i < 2; i++) {
circles.push(new Circle(random(canvas.width / 2), random(canvas.height / 2), 50, ctx));
}
};
genCircles();
// Displaying and updating the circles
const showCircles = () => {
for (let i = 0; i < circles.length; i++) {
// Mouse Event to update mouse's coords
canvas.addEventListener("mousemove", (e) => {
mouse.x = e.x;
mouse.y = e.y;
}, true);
// Iterating over the circles to check for collision
for (let j = 0; j < circles.length; j++) {
if (i !== j) {
circles[i].collides(circles[j])
}
}
// Doing the movement and the display functions
circles[i].update(mouse.x, mouse.y);
circles[i].show();
}
};
// Loop to make it run
const update = () => {
requestAnimationFrame(update);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#000";
ctx.fillRect(0, 0, canvas.width, canvas.height);
showCircles();
};
update();
html body {
margin: 0;
padding: 0;
overflow: hidden;
display: block;
}
<canvas id="cv"></canvas>
this.acc *= -1;
был добавлен, чтобы просто показать, что обнаружение столкновений работает (закомментируйте эту строку, чтобы лучше понять, что происходит); но что действительно нужно ОП, так это то, чтобы круги меняли траекторию. Их нужно по-прежнему притягивать к мышке, но при этом они не должны сталкиваться. Желаемым результатом, насколько я понимаю, было бы то, что круги по-прежнему будут двигаться к мыши и в то же время избегать друг друга. Я думаю, это потребует серьезной математики. По крайней мере помогает то, что они круги. - person Joseph Marikle   schedule 12.01.2018