我试图让命中测试/重叠测试在下面的代码中工作,该代码在画布上的随机位置创建200个圆圈。我试图将圆圈的位置存储在一个数组中,然后每次在for循环中创建另一个圆圈时检查该数组,如果随机创建的x和y太接近已经创建的圆圈,它应该继续获得一个新的圆圈随机x和y,直到它不太接近已经创建的圆圈。
我不能在while循环中使用它。
任何帮助请...
由于
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", canvasDraw);
function canvasDraw () {
var c = document.getElementById("canvas");
var w = window.innerWidth;
var h = window.innerHeight;
c.width = w;
c.height = h;
var ctx = c.getContext("2d");
ctx.clearRect(0,0,c.width, c.height);
var abc = 0;
var colours = new Array ("rgb(0,100,0)", "rgb(51,102,255)");
var positions = new Array();
function hitTest(x, y) {
for(var p in positions) {
pp = p.split(",");
pp[0] = parseInt(pp[0]);
pp[1] = parseInt(pp[1]);
if(((x > (pp[0] - 24)) && (x < (pp[0] + 24))) && ((y > (pp[1] - 24)) && (y < (pp[1] + 24)))) {
return true;
}
}
return false;
}
//Loop 200 times for 200 circles
for (i=0; i<200; i++) {
var x = Math.floor(Math.random()*c.width);
var y = Math.floor(Math.random()*c.height);
while(hitTest(x, y) == true){
var x = Math.floor(Math.random()*c.width);
var y = Math.floor(Math.random()*c.height);
}
var pos = x.toString() + "," + y.toString();
positions.push(pos);
var radius = 10;
var r = radius.toString();
var b = colours[Math.floor(Math.random()*colours.length)];
circle(ctx,x,y, radius, b);
}
}
function circle (ctx, x, y, radius, b) {
ctx.fillStyle = b;
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();
}
</script>
答案 0 :(得分:3)
开始前的一些事情:
new Array()
创建数组。使用[]
; for...in
迭代数组:使用带有计数器的标准for
。这是一个很好的做法; 好的,让我们看看代码。
if(((x > (pp[0] - 24)) && (x < (pp[0] + 24))) && ((y > (pp[1] - 24)) && (y < (pp[1] + 24))))
老实说,这是什么?我称之为一个胡思乱想,不起眼的片段。回想一下你在学校学到的东西:
var dx = pp[0] - x, dy = pp[1] - y;
if (dx * dx + dy * dy < 400) return true;
是不是更清楚了?
让我们看看整个功能:
function canvasDraw () {
var c = document.getElementById("canvas");
var w = window.innerWidth;
var h = window.innerHeight;
c.width = w;
c.height = h;
var ctx = c.getContext("2d");
ctx.clearRect(0,0,c.width, c.height);
// Lolwut?
// var abc = 0;
var colours = ["rgb(0,100,0)", "rgb(51,102,255)"];
var positions = [];
function hitTest(x, y) {
for (var j = 0; j < positions.length; j++) {
var pp = positions[j];
var dx = pp[0] - x, dy = pp[1] - y;
if (dx * dx + dy * dy < 400) return true;
}
return false;
}
// You declare the radius once and for all
var radius = 10;
// Declare the local scoped variables. You forgot i
var x, y, i;
for (i=0; i<200; i++) {
// How about a do...while instead of a while?
do {
var x = Math.floor(Math.random()*c.width);
var y = Math.floor(Math.random()*c.height);
// Testing with === is faster, always do it if you know the type
// I'll let it here, but if the type is boolean, you can avoid testing
// at all, as in while (hitTest(x, y));
} while (hitTest(x, y) === true);
positions.push([x, y]);
// This instruction is useless
// var r = radius.toString();
var b = colours[Math.floor(Math.random()*colours.length)];
circle(ctx,x,y, radius, b);
}
}
但是, BEWARE ,根据您的画布大小,可能没有其他圈子的空间,因此它可能会以无限循环结束。尝试在40x40的盒子中放入200个半径为10的圆圈......
应该进行另一项测试, 可能很复杂。