gpt4 book ai didi

javascript - javascript中的重叠/ HitTest

转载 作者:可可西里 更新时间:2023-11-01 13:15:28 25 4
gpt4 key购买 nike

我试图让 HitTest /重叠测试在下面的代码中工作,它在 Canvas 上的随机位置创建 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>

最佳答案

开始之前的一些事情:

  1. 不要使用 new Array() 创建数组,除非您指定了初始长度。使用[];
  2. 不要使用for...in 遍历数组:使用带有计数器的标准for。这是更好的做法;
  3. 将数字转换成字符串再转换回数字既无用又昂贵。使用一个小数组来存储这两个值;
  4. 不要使用“魔数(Magic Number)”,即具有精确值但难以立即识别的数字。使用命名的“常量”或在每个常量旁边添加注释以说明它们的含义,以供将来维护。

好的,让我们看看代码。

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);

}
}

请注意,不过,根据您的 Canvas 大小,可能没有更多空间容纳另一个圆圈,因此它可能会以无限循环结束。尝试将 200 个半径为 10 的圆圈放入一个 40x40 的盒子中......应该进行另一项测试,可能会很复杂。

关于javascript - javascript中的重叠/ HitTest ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10888494/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com