学校项目:同学和我自己编程“Agar.io”(练习)。做得好,测试不同的东西,然后我们得到一个我们无法弄清楚的问题。当用各种浏览器打开时,看似“随机”的JavaScript没有完全执行。除了偶尔随机不执行页面加载,每次刷新页面时,JavaScript都会像以前一样打破。它仅在重新打开页面之前完全关闭浏览器后才有效。 1:为什么现在发生这种情况而不是之前? 2:我们如何解决这个问题?下面带注释的源代码,谢谢,-Tom
var pixelconversion = 100 * Math.PI; //conversion from made-up "mass" (really area), to area in pixels, which will be converted to a radius
var circleX = 400;
var circleY = 250;
var mouseX = 400;
var mouseY = 250;
var mass = 30;
var radius = 20; //just to make it global
function start() {
drawCircles();
var interval = setInterval(mainloop, 50);
}
function mainloop() {
math();
var can = document.getElementById("canvas");
var ctx = can.getContext("2d");
ctx.clearRect(0, 0, 801, 501); //clears the canvas
drawCircles();
sleep(100); //more efficient than having the set interval at 150 instead
}
function getCoordinates(e) { //gets the cursors coordinates
mouseX = e.clientX;
mouseY = e.clientY;
}
function math() {
var movement = mass / 4; //arbitrary "4", will be replaced with: 1/mass * someConversion
radius = Math.sqrt((mass * pixelconversion) / Math.PI); //from area in "mass" to area in pixels, to radius in pixels
var difY = Math.abs(mouseY - circleY) //finds the difference of each
var difX = Math.abs(mouseX - circleX) //for "A" and "B" of the triangle
var c = Math.sqrt(Math.pow(difX, 2) + Math.pow(difY, 2)); //pythagareon theorem to find diagonal distance from mouse to circle
var scale = movement / c; //use scale to find "A" and "B" of smaller triangle
if (mouseX > circleX) { //if and else statements are for "movement" in the right direction, (towards the mouse)
circleX = circleX + difX * scale; //aditional if statements will be added to (next comment)
} else {
circleX = circleX - difX * scale; //stop the circle from going back and forth past the cursor
}
if (mouseY > circleY) {
circleY = circleY + difY * scale; //the differce * scale is vital; (fourth comment up)
} else {
circleY = circleY - difY * scale;
}
}
function drawCircles() {
var can = document.getElementById("canvas");
var ctx = can.getContext("2d");
ctx.beginPath();
ctx.arc(circleX, circleY, radius, 0, 2 * Math.PI); //draws the circle
ctx.closePath();
ctx.lineWidth = 5; //just for style
ctx.fillStyle = 'green';
ctx.fill();
ctx.strokeStyle = 'darkgreen'; //just for style
ctx.stroke();
}
function sleep(milliseconds) { //"homemade" "sleep" "command"
var start = new Date().getTime();
for (var i = 0; i < 1; i++) {
if ((new Date().getTime() - start) > milliseconds) {
break;
}
}
}
<body onload="start()">
<canvas id="canvas" height="501" width="801" onmousemove="getCoordinates(event)"></canvas>
</body>
答案 0 :(得分:1)
这一行
var scale = movement / c; //use scale to find "A" and "B" of smaller triangle
c可以为零 - 这使得规模NaN破坏了一切
试试这个
var scale = c ? movement / c : 0;
我还添加了一个片段,演示了requestAnimationFrame与bodgy sleep函数的平滑程度
var pixelconversion = 100 * Math.PI; //conversion from made-up "mass" (really area), to area in pixels, which will be converted to a radius
var circleX = 400;
var circleY = 250;
var mouseX = 400;
var mouseY = 250;
var mass = 30;
var radius = 20; //just to make it global
function start() {
document.getElementById("canvas").addEventListener('mousemove', getCoordinates);
mainloop();
}
function mainloop() {
math();
drawCircles();
requestAnimationFrame(mainloop);
}
function getCoordinates(e) { //gets the cursors coordinates
mouseX = e.clientX;
mouseY = e.clientY;
}
function math() {
var movement = mass / 4; //arbitrary "4", will be replaced with: 1/mass * someConversion
radius = Math.sqrt((mass * pixelconversion) / Math.PI); //from area in "mass" to area in pixels, to radius in pixels
var difY = Math.abs(mouseY - circleY) //finds the difference of each
var difX = Math.abs(mouseX - circleX) //for "A" and "B" of the triangle
var c = Math.sqrt(Math.pow(difX, 2) + Math.pow(difY, 2)); //pythagareon theorem to find diagonal distance from mouse to circle
var scale = c ? movement / c : 0; //use scale to find "A" and "B" of smaller triangle
if (mouseX > circleX) { //if and else statements are for "movement" in the right direction, (towards the mouse)
circleX = circleX + difX * scale; //aditional if statements will be added to (next comment)
} else {
circleX = circleX - difX * scale; //stop the circle from going back and forth past the cursor
}
if (mouseY > circleY) {
circleY = circleY + difY * scale; //the differce * scale is vital; (fourth comment up)
} else {
circleY = circleY - difY * scale;
}
}
function drawCircles() {
var can = document.getElementById("canvas");
var ctx = can.getContext("2d");
ctx.clearRect(0, 0, 801, 501); //clears the canvas
ctx.beginPath();
ctx.arc(circleX, circleY, radius, 0, 2 * Math.PI); //draws the circle
ctx.closePath();
ctx.lineWidth = 5; //just for style
ctx.fillStyle = 'green';
ctx.fill();
ctx.strokeStyle = 'darkgreen'; //just for style
ctx.stroke();
}
window.addEventListener('load', start);
<canvas id="canvas" height="501" width="801"></canvas>
我会留给你,弄清楚为什么这个圈子就像一个看日本卡通的孩子一样跳舞
根据评论中的要求:
Window.requestAnimationFrame()
方法告诉浏览器您希望执行动画并请求浏览器调用指定的函数以在下次重绘之前更新动画。该方法将重绘之前调用的回调作为参数。只要您准备好在屏幕上更新动画,就应该调用此方法。这将请求在浏览器执行下一次重绘之前调用您的动画函数。回调次数通常为每秒60次,但根据W3C建议,通常会与大多数Web浏览器中的显示刷新率相匹配。在后台选项卡或隐藏s中运行时,回调率可降低到较低的速率,以提高性能和电池寿命。
回调方法传递一个参数
DOMHighResTimeStamp
,它指示requestAnimationFrame排队的回调开始触发的当前时间。因此,即使在计算每个先前回调的工作负载期间已经过了时间,单个帧中的多个回调也会接收相同的时间戳。此时间戳是十进制数,以毫秒为单位,但最小精度为1ms(1000μs)。来源:https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame