Давайте немного переделаем:
Во-первых, при программировании графической анимации вы должны разделить логику объектов и операции рисования.
Операции рисования должны выполняться через равные промежутки времени на основена частоте обновления экрана (чтобы не рисовать иногда дважды кадр, а иногда вообще не рисовать).
Для этого точного случая в Web API доступен удобный метод requestAnimationFrame (callback) ,Он поставит наш обратный вызов в очередь на срабатывание непосредственно перед следующей частотой обновления экрана.
Таким образом, мы можем использовать его в качестве ядра нашего цикла анимации, который всегда будет запускаться с той же скоростью, что и наш экран (обычно 60FPS).
Когда у вас есть анимированные объекты на вашей сцене, самая простая структура данных в js - это Объекты.Вместо того, чтобы хранить множество переменных везде, вы упаковываете их в свой собственный объект.
Когда у вас есть несколько таких объектов, вы держите их все вместе (например, в массиве).
Теперь в нашей анимацииВ цикле мы сначала обновим положение наших объектов, а затем нарисуем их.
Именно в части обновления мы будем контролировать скорость наших объектов, и только после того, как мы обновим все объекты, мы проверим, сталкиваются ли они.
(function() {
var ctx = document.getElementById("canvas").getContext("2d"),
max_speed = Math.PI / 12,
objects = [{
center_x: 160,
center_y: 120,
speed: Math.random() % max_speed,
angle: 0,
color: '#000'
},
{
center_x: 330,
center_y: 280,
speed: -(Math.random() % max_speed),
angle: 0,
color: "#80ced6"
}
],
radius = 20,
outerRad = 120,
totalcounter = 0,
collide = true;
anim(); // begin our main anim loop
function anim() {
update(); // our objects update logic
draw(); // now we draw
collisiondetection(); // DOM update
requestAnimationFrame(anim); // start again @next-frame
}
function update() {
// here we only change the object's properties
// nothing graphical should come here
objects.forEach(function(object) {
var angle = object.angle;
object.x = Math.cos(angle) * outerRad + object.center_x;
object.y = Math.sin(angle) * outerRad + object.center_y;
object.angle += object.speed;
});
}
function draw() {
// here is only the graphical part
// no logic should come here
ctx.clearRect(0, 0, 550, 400);
objects.forEach(function(object) {
ctx.fillStyle = object.color;
ctx.beginPath();
ctx.arc(object.x, object.y, radius, 0, Math.PI * 2);
ctx.fill();
});
}
function collisiondetection() {
var o1 = objects[0],
o2 = objects[1];
var distance = Math.sqrt((o1.x - o2.x) * (o1.x - o2.x) + (o1.y - o2.y) * (o1.y - o2.y));
if (distance < radius * 2) {
if (collide == false) {
totalcounter = totalcounter + 1;
document.getElementById("cTotal").innerHTML = "Total collisions:" + totalcounter;
collide = true;
}
} else {
collide = false;
}
}
// and now if you want to update randomly these object's speed, you can do from anywhere
document.onclick = function() {
objects[0].speed = Math.random() % max_speed;
objects[1].speed = -(Math.random() % max_speed);
};
})();
<canvas id="canvas" width="550" height="400" style="background:#eee;"></canvas>
<p id="cTotal">Total collisions: </p>