我正在画布上绘制 100 个不同大小的圆圈,它们不能重叠。这些圆圈也将从右到左动画(当它们离开屏幕时循环回到画布的右边缘),并且它们也会有一些垂直的“bob”,它们也不能与任何其他圆圈重叠。
以下是我目前正在尝试的,这似乎锁定了浏览器。我遍历圆圈集合并执行一个detectOverlap()
函数,将圆圈集合传递给它。
然后该detectOverlap()
函数循环遍历圆圈,执行以下检查:
detectOverlap: function (bubblesArr) {
while (true) {
var hit = 0;
for (var i=0; i<bubblesArr.length; i++) {
var circle = bubblesArr[i];
var dx = this._x - circle._x;
var dy = this._y - circle._y;
var rr = this._radius + circle._radius;
if (dx * dx + dy * dy < rr * rr) {
hit++;
}
}
if (hit == 0) {
break; // didn't overlap, break out of while loop
}
// if we didn't break then there was an overlap somewhere. calc again.
this._x = Math.round(Math.random() * this.stage.getWidth());
this._y = Math.round(Math.random() * this.stage.getHeight());
}
},
如果hit == 0
,则循环中断,我们假设没有重叠。否则,我们随机计算一个新的 X/Y 位置并重新开始该过程。
这似乎效率低下。这样做的任何性能提示?
画布类(入口点):这个类是“舞台”,它构建气泡对象,然后将它们添加到画布中。
var $container;
var listData;
var bubbles = [];
function init(l, c) {
$container = c;
listData = l;
// this just draws the canvas. full-width + 500px tall.
var stage = new Konva.Stage({
container: $container.selector,
width: window.innerWidth,
height: 500
});
// this creates the drawing layer where the bubbles will live
layer = new Konva.Layer();
// create an instance of the Bubble class for each element in the list.
for (var i=0; i<listData.length; i++) {
bubbles[i] = new celebApp.Bubble.Bubble(listData[i], stage);
}
/** TODO:::: FIGURE OUT COLLISION DETECTION */
for (var i=0; i<bubbles.length; i++) {
bubbles[i].detectOverlap(bubbles);
}
// create the Konva representation for our generated objects
for (var i=0; i<bubbles.length; i++) {
var b = bubbles[i];
layer.add(new Konva.Circle({
x: b._x,
y: b._y,
radius: b._radius,
fill: b._fill,
stroke: b._stroke,
strokeWidth: b._strokeWidth,
}));
}
// add the layer to the stage
stage.add(layer);
}
气泡类: 这是代表绘制到屏幕上的数据的类。我们需要确保这些对象没有一个相互重叠。
var Bubble = function (listData, stage) {
this.stage = stage;
this._x = Math.round(Math.random() * stage.getWidth()),
this._y = Math.round(Math.random() * stage.getHeight()),
this._radius = Math.round(Math.random() * 80);
this._fill = 'red';
this._stroke = 'black';
this._strokeWidth = 4;
this._speed = 3;
};
Bubble.prototype = {
detectOverlap: function (bubblesArr) {
while (true) {
var hit = 0;
for (var i=0; i<bubblesArr.length; i++) {
var circle = bubblesArr[i];
var dx = this._x - circle._x;
var dy = this._y - circle._y;
var rr = this._radius + circle._radius;
if (dx * dx + dy * dy < rr * rr) {
hit++;
}
}
if (hit == 0) {
break; // didn't overlap
}
this._x = Math.round(Math.random() * this.stage.getWidth());
this._y = Math.round(Math.random() * this.stage.getHeight());
}
},
};
编辑:刚刚根据@MarcB 的评论尝试了这个——但是,浏览器似乎仍然被锁定。是否造成了性能瓶颈,但 100 个项目都在运行自己的while()
循环?
for (var i=0; i<bubblesArr.length; i++) {
var circle = bubblesArr[i];
var combinedRadius = Math.abs(circle._radius + this._radius);
var distance = Math.abs(this._x - circle._x);
if (distance <= combinedRadius) {
hit++;
}
}