我有两个圆圈旋转,我希望圆圈在旋转一圈后随机改变速度,两个圆圈的速度或速度可能相同(否则会发生碰撞)。例如,在第一次运行时,两个圆都以10m / s的速度运动,到达旋转结束后它们将发生碰撞。假设旋转后,它将圆1更改为15m / s,将圆2更改为30m / s,这样他们就不会发生冲突。我想知道如何实现这一目标。这只是我要实现的目标的一个想法。如果每转一圈后随机分配速度,那会更好。
任何帮助将不胜感激。
代码:
(function() {
var ctx = document.getElementById("canvas").getContext("2d"),
x1 = 160,
y1 = 120,
x2 = 330,
y2 = 280,
radius = 20;
angle = 0,
velX = 0,
velY = 0,
thrust = 3,
rotation = 0;
function draw() {
velX = Math.cos(angle * Math.PI / 180) * thrust;
velY = Math.sin(angle * Math.PI / 180) * thrust;
x1 += velX;
y1 += velY;
angle += 1;
ctx.fillStyle = "#000";
ctx.clearRect(0, 0, 550, 400);
ctx.beginPath();
ctx.arc(x1, y1, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
draw2();
setTimeout(function() {
draw()
}, 30);
}
function draw2() {
velX = Math.cos(angle * Math.PI / 180) * thrust;
velY = Math.sin(angle * Math.PI / 180) * thrust;
x2 += -velX;
y2 += -velY;
angle += 1;
ctx.fillStyle = "#80ced6";
ctx.beginPath();
ctx.arc(x2, y2, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
collisiondetection();
}
var distance = 0;
var totalcounter = 0;
var collide = false;
function collisiondetection() {
distance = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
if (distance < radius * 2) {
if (collide == false) {
totalcounter = totalcounter + 1;
document.getElementById("cTotal").innerHTML = "Total collisions:" + totalcounter;
collide = true;
}
} else {
collide = false;
}
}
draw();
})();
<canvas id="canvas" width="550" height="400" style="background:#eee;"></canvas>
<span id="cTotal">Total collisions: </span>
答案 0 :(得分:1)
您可以做的是为speed
函数声明一个本地draw()
变量,然后将其传递给setTimeout()
回调,如下所示:
var speed = Math.floor(Math.random() * 11);
draw2();
setTimeout(function() {
draw()
}, speed);
代码Math.floor(Math.random() * 11)
将为您提供一个介于0
和10
之间的随机数,因此每次setTimeout
都会以不同的速度被调用。
演示:
window.onload = function() {
(function() {
var ctx = document.getElementById("canvas").getContext("2d"),
x1 = 160,
y1 = 120,
x2 = 330,
y2 = 280,
radius = 20;
angle = 0,
velX = 0,
velY = 0,
thrust = 3,
rotation = 0;
function draw() {
velX = Math.cos(angle * Math.PI / 180) * thrust;
velY = Math.sin(angle * Math.PI / 180) * thrust;
x1 += velX;
y1 += velY;
angle += 1;
ctx.fillStyle = "#000";
ctx.clearRect(0, 0, 550, 400);
ctx.beginPath();
ctx.arc(x1, y1, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
var speed = Math.floor(Math.random() * 11);
draw2();
setTimeout(function() {
draw()
}, speed);
}
function draw2() {
velX = Math.cos(angle * Math.PI / 180) * thrust;
velY = Math.sin(angle * Math.PI / 180) * thrust;
x2 += -velX;
y2 += -velY;
angle += 1;
ctx.fillStyle = "#80ced6";
ctx.beginPath();
ctx.arc(x2, y2, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
collisiondetection();
}
var distance = 0;
var totalcounter = 0;
var collide = false;
function collisiondetection() {
distance = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
if (distance < radius * 2) {
if (collide == false) {
totalcounter = totalcounter + 1;
document.getElementById("cTotal").innerHTML = "Total collisions:" + totalcounter;
collide = true;
}
} else {
collide = false;
}
}
draw();
})();
}
<canvas id="canvas" width="550" height="400" style="background:#eee;"></canvas>
<span id="cTotal">Total collisions: </span>
答案 1 :(得分:0)
您可以在timeGap
变为360,即旋转完成时更改angle
。因此,它将随着速度的改变而出现。
在draw()
函数内部:
if(angle % 360 == 0) {
timeGap = Math.random() * 20 + 5;
}
(function() {
var ctx = document.getElementById("canvas").getContext("2d"),
x1 = 160,
y1 = 120,
x2 = 330,
y2 = 280,
radius = 20,
angle1 = 0,
angle2 = 0,
velX = 0,
velY = 0,
thrust = 3,
rotation = 0,
timeGap1 = 10,
timeGap2 = 10,
diff = 20,
minTimeGap = 20;
function draw() {
velX = Math.cos(angle1 * Math.PI / 180) * thrust;
velY = Math.sin(angle1 * Math.PI / 180) * thrust;
x1 += velX;
y1 += velY;
angle1 += 2;
ctx.fillStyle = "#000";
ctx.beginPath();
ctx.arc(x1, y1, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
if(angle1 % 360 == 0) {
timeGap1 = Math.random() * diff + minTimeGap;
}
setTimeout(function() {
draw();
}, timeGap1);
}
function draw2() {
velX = Math.cos(angle2 * Math.PI / 180) * thrust;
velY = Math.sin(angle2 * Math.PI / 180) * thrust;
x2 += -velX;
y2 += -velY;
angle2 += 2;
ctx.fillStyle = "#007700";
ctx.beginPath();
ctx.arc(x2, y2, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
if(angle2 % 360 == 0) {
timeGap2 = Math.random() * diff + minTimeGap;
}
setTimeout(function() {
draw2();
}, timeGap2);
}
function clearCanvas() {
ctx.fillStyle = 'rgba(220,220,220,0.5)';
ctx.fillRect(0, 0, 550, 400);
collisiondetection();
setTimeout(function() {
clearCanvas();
}, timeGap2 + timeGap1);
}
var distance = 0;
var totalcounter = 0;
var collide = false;
function collisiondetection() {
distance = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
if (distance < radius * 2) {
if (collide == false) {
totalcounter = totalcounter + 1;
document.getElementById("cTotal").innerHTML = "Total collisions:" + totalcounter + "<br/>Speed1: " + timeGap1 + "<br/>Speed2: " + timeGap2;
collide = true;
}
} else {
collide = false;
}
}
draw();
draw2();
clearCanvas();
})();
<canvas id="canvas" width="550" height="400" style="background:#eee;"></canvas>
<span id="cTotal">Total collisions: </span>
答案 2 :(得分:-1)
(function() {
var ctx = document.getElementById("canvas").getContext("2d"),
x1 = 160,
y1 = 120,
x2 = 330,
y2 = 280,
radius = 20;
angle = 0,
velX = 0,
velY = 0,
thrust = 3,
rotation = 0,
maxSpeed = 100,
speed = Math.floor(Math.random() * 100) + 1;
function draw() {
velX = Math.cos(angle * Math.PI / 180) * thrust;
velY = Math.sin(angle * Math.PI / 180) * thrust;
x1 += velX;
y1 += velY;
angle += 1;
ctx.fillStyle = "#000";
ctx.clearRect(0, 0, 550, 400);
ctx.beginPath();
ctx.arc(x1, y1, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
draw2();
SpeedCount();
}
function draw2() {
velX = Math.cos(angle * Math.PI / 180) * thrust;
velY = Math.sin(angle * Math.PI / 180) * thrust;
x2 += -velX;
y2 += -velY;
angle += 1;
ctx.fillStyle = "#80ced6";
ctx.beginPath();
ctx.arc(x2, y2, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
collisiondetection();
}
function SpeedCount(){
(function(speed) {
setTimeout(function() {
draw()
}, speed);
})(speed);
}
var distance = 0;
var totalcounter = 0;
var collide = false;
function collisiondetection() {
distance = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
if (distance < radius * 2) {
if (collide == false) {
totalcounter = totalcounter + 1;
document.getElementById("cTotal").innerHTML = "Total collisions:" + totalcounter;
collide = true;
}
} else {
collide = false;
}
if((angle + 90) % 360 == 0){
speed = Math.floor(Math.random() * maxSpeed) + 1;
}
}
draw();
})();
<canvas id="canvas" width="550" height="400" style="background:#eee;"></canvas>
<span id="cTotal">Total collisions: </span>
尝试这个。
答案 3 :(得分:-1)
让我们稍作修改:
首先,在对图形动画进行编程时,应将对象逻辑和绘图操作分开。
绘制操作应该根据屏幕刷新率有规律地进行(以避免有时绘制两次,有时根本不绘制)。
对于这种确切情况,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>