JavaScript对象的颜色动态变化?
作者:互联网
这是当两个球碰撞时将球的颜色更改为红色的代码.我快到了,但我似乎没有找到错误,因为一个球没有改变颜色.请帮帮我!
//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
解决方法:
球都在碰撞;碰撞的公式是正确的,即:
(dx * dx) + (dy * dy) <= sum of the circles' radii
问题在于,由于JavaScript的单线程特性,有时屏幕不会更新以反映新的颜色,而if的else部分会重置颜色.
例如,当ball [0]与ball [1]碰撞时,可以在if中将ball [0]的颜色设置为红色,这是可以的.但是,例如,如果在内部循环的下一次迭代中(j = 2)ball [0]不与ball [2]碰撞,它将把ball [0]的颜色重置为原始颜色,并且只有在循环结束后才再次显示屏幕(同样,由于JavaScript的单线程特性),在这种情况下您永远看不到红色.
因此,您有两个选择. 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.
标签:euclidean-distance,collision-detection,css,javascript,jquery 来源: https://codeday.me/bug/20191127/2076146.html