这是两个球碰撞时将球的颜色改为红色的代码。我几乎就在那里,但我似乎没有找到错,因为一个球没有改变颜色。请帮帮我们!
//generate a random number within a range
function randomXToY(minVal,maxVal,floatVal)
{
var randVal = minVal+(Math.random()*(maxVal-minVal));
return typeof floatVal=='undefined'?Math.round(randVal):randVal.toFixed(floatVal);
}
// The Ball class
Ball = (function() {
// constructor
function Ball(x,y,radius,color){
this.center = {x:x, y:y};
this.radius = radius;
this.color = color;
this.dx = 2;
this.dy = 2;
this.boundaryHeight = $('#ground').height();
this.boundaryWidth = $('#ground').width();
this.dom = $('<p class="circle"></p>').appendTo('#ground');
// the rectange div a circle
this.dom.width(radius*2);
this.dom.height(radius*2);
this.dom.css({'border-radius':radius,background:color});
this.placeAtCenter(x,y);
}
// Place the ball at center x, y
Ball.prototype.placeAtCenter = function(x,y){
this.dom.css({top: Math.round(y- this.radius), left: Math.round(x - this.radius)});
this.center.x = Math.round(x);
this.center.y = Math.round(y);
};
Ball.prototype.setColor = function(color) {
if(color) {
this.dom.css('background',color);
} else {
this.dom.css('background',this.color);
}
};
// move and bounce the ball
Ball.prototype.move = function(){
var diameter = this.radius * 2;
var radius = this.radius;
if (this.center.x - radius < 0 || this.center.x + radius > this.boundaryWidth ) {
this.dx = -this.dx;
}
if (this.center.y - radius < 0 || this.center.y + radius > this.boundaryHeight ) {
this.dy = -this.dy;
}
this.placeAtCenter(this.center.x + this.dx ,this.center.y +this.dy);
};
return Ball;
})();
var number_of_balls = 5;
var balls = [];
var x;
var y;
$('document').ready(function(){
for (i = 0; i < number_of_balls; i++) {
var boundaryHeight = $('#ground').height();
var boundaryWidth = $('#ground').width();
y = randomXToY(30,boundaryHeight - 50);
x = randomXToY(30,boundaryWidth - 50);
var radius = randomXToY(15,30);
balls.push(new Ball(x,y,radius, '#'+Math.floor(Math.random()*16777215).toString(16)));
}
loop();
check();
});
check = function(){
for (var i = 0; i < balls.length; i++){
for(var j=0;j<balls.length;j++){
if (i!=j) {
if (Math.pow(balls[j].center.x - balls[i].center.x, 2) + Math.pow(balls[j].center.y - balls[i].center.y, 2) <= Math.pow(balls[i].radius + balls[j].radius, 2)) {
console.log(true);
balls[j].setColor('red');
balls[i].setColor('red');
} else {
balls[j].setColor(balls[j].color);
}
}
}}
setTimeout(check,8);
};
loop = function(){
for (var i = 0; i < balls.length; i++){
balls[i].move();
}
setTimeout(loop, 8);
};
这是jsbin:http://jsbin.com/imofat/790/edit
答案 0 :(得分:3)
球都在碰撞;碰撞的公式是正确的,即:
(dx * dx) + (dy * dy) <= sum of the circles' radii
问题在于,由于JavaScript的单线程特性以及else
重置颜色的if
部分,有时屏幕不会更新以反映新颜色。
例如,当ball[0]
与ball[1]
发生碰撞时,您将ball[0]
的颜色设置为red
中的if
,这是确定即可。但是,如果ball[0]
在内部循环的下一次迭代(ball[2]
)中与j=2
发生冲突,例如,它将 重置 ball[0]
的颜色恢复为原始颜色,并且因为屏幕只会在后呈现 循环结束(再次,由于JavaScript的单线程特性),在这种情况下你永远不会看到red
颜色。
所以,你有两个选择。 1)发生碰撞时 break
内部循环(如果您不需要互相测试)碰撞); 2)标记哪些球已经碰撞,并且仅使用Array
重置之前从未在循环中碰撞过的人的颜色,例如:
var collisions = [];
for (var i = 0; i < balls.length; i++) {
for (var j = 0; j < balls.length; j++) {
if (i!=j) {
if (Math.pow(balls[j].center.x - balls[i].center.x, 2) + Math.pow(balls[j].center.y - balls[i].center.y, 2) <= Math.pow(balls[i].radius + balls[j].radius, 2)) {
collisions[i] = true;
balls[i].setColor('red');
} else {
if (!collisions[i]) {
balls[i].setColor(balls[i].color);
}
}
}
}
}
此外,第二个循环可以简化为从i + 1
而不是0
开始。这样,您不仅可以减少碰撞测试的次数,还可以删除i != j
测试。
<强> DEMO 强>
答案 1 :(得分:0)
如果你想在碰撞发生后让红色持续存在,你需要设置球的颜色:
Ball.prototype.setColor = function(color) {
if(color) {
this.color = color; // The ball's color is now this value.
this.dom.css('background',color);
} else {
this.dom.css('background',this.color); // so when this is called, the ball will be that color going forward.
}
};