0

I want to change the color of the balls to red when they collide. I tried using my function check() to change the color of the balls when they collide using balls[i].color but how do I know the positions of the balls to compare when they collide?

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(x==y){
      balls[i].color='#ff0000';
       alert("y");         
 }
    else{
    }
    }}

   setTimeout(check,8);  
};

loop = function(){
  for (var i = 0; i < balls.length; i++){
    balls[i].move();
  }

  setTimeout(loop, 8);    
};

http://jsbin.com/imofat/743/edit

João Silva
  • 89,303
  • 29
  • 152
  • 158
Aditya
  • 4,453
  • 3
  • 28
  • 39
  • This question is poorly constructed and lacks the scope to give useful information to future readers. Consider editing your question to be more elaborate and more precise. Posting the code in question on the question page is a good way to do this. – recursion.ninja Sep 01 '12 at 20:42
  • 1
    Post relevant ([SSCCE](http://sscce.org/)) code *here*, and explain clearly what you've tried already and what went wrong. – David Thomas Sep 01 '12 at 20:43
  • @Aditya in your `check()` function consider passing the array of ball objects `balls[]` to the function and then checking if any of the balls have overlapping radii (plural of radius). – recursion.ninja Sep 01 '12 at 21:06

3 Answers3

5

Calculate the Eucledian distance between the centers of each ball. Then, when this distance is smaller or equal to the sum of their radiuses, there's a collision:

enter image description here

check = function() {
  for (var i = 0; i < balls.length; i++) {
    for(var j = 0; j < balls.length; j++) {
      if (i != j) { // ignore self-collision
        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)) {
          balls[j].setColor('red');
        } else {
          balls[j].setColor(balls[j].color);
       } 
    }
 }}

Here's a DEMO.

João Silva
  • 89,303
  • 29
  • 152
  • 158
  • Thanks a lot, This is great , but the color is being retained, the color should be changing to red when only they collide! – Aditya Sep 01 '12 at 21:07
  • @Aditya: That's simple, add an `else` part to reset the color. Check my updated answer. Also, you probably should add a timeout before resetting the color, otherwise you may not notice the color change. – João Silva Sep 01 '12 at 21:07
  • Hey, i checked the running of the code, and i just found out that there's one ball always that's not changing color on collision with another ball?? http://jsbin.com/imofat/790/edit – Aditya Sep 04 '12 at 18:45
0

Edit:

for colliding with other balls, it will require more work.. check this post: Ball to Ball Collision


just setColor when the direction changes, assuming "collide" means "hit the wall":

// 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;
    this.setColor( 'red' );
  }
  if (this.center.y - radius < 0 || this.center.y  + radius > this.boundaryHeight ) {
    this.dy = -this.dy;
    this.setColor( 'red' );
  }
  this.placeAtCenter(this.center.x + this.dx ,this.center.y +this.dy);
};  
Community
  • 1
  • 1
Austin Greco
  • 32,997
  • 6
  • 55
  • 59
0

I added an actual ball collision check inside the check method:

check = function(){
  var dx, dy;
  var x1, x2, y1, y2, r1, r2;
  for (var i = 0; i < balls.length; i++){
      x1 = balls[i].center.x;y1=balls[i].center.y;r1=balls[i].radius;
      for(var j=0;j<balls.length;j++){
          if (i===j) {continue;} // collision with self

          x2 = balls[j].center.x;y2=balls[j].center.y;r2=balls[j].radius;


          if( Math.sqrt((x1-x2)*(x1-x2) +  (y1-y2)*(y1-y2)) <=(r1+r2)  ){ // check collision
              balls[i].setColor('#ff0000');
          }
          else{
          }
      }
  }

  setTimeout(check,8);  
};
batzkoo
  • 1,275
  • 1
  • 10
  • 10
  • This is great , but the color is being retained, the color should be changing to red when only they collide! – Aditya Sep 01 '12 at 21:06