Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The balls are all colliding; the formula for the collision is correct, i.e.:</p> <pre><code>(dx * dx) + (dy * dy) &lt;= sum of the circles' radii </code></pre> <p>The problem, is that sometimes the screen is not updated to reflect the new color, due to the single-threaded nature of JavaScript, and the <code>else</code> part of the <code>if</code> that resets the color.</p> <p>For example, when <code>ball[0]</code> collides with <code>ball[1]</code>, you set <code>ball[0]</code>'s color to <code>red</code> in the <code>if</code>, which is <strong>OK</strong>. However, if <code>ball[0]</code> <strong><em>does not</em></strong> collide with <code>ball[2]</code> in the next iteration of the inner loop (<code>j=2</code>), for example, it will <strong><em>reset</em></strong> <code>ball[0]</code>'s color back to its original color, and since the screen will only be rendered <strong><em>after</em></strong> the loop is over (again, due to the single-threaded nature of JavaScript), you never see the <code>red</code> color in this situation.</p> <p>So, you have two options. <strong>1)</strong> Either <strong><a href="http://jsbin.com/imofat/829/edit" rel="nofollow"><code>break</code></a></strong> it out of the <em>inner</em> loop when a collision occurs (if you don't need to test every other collision); <strong>2)</strong> Mark which balls have already collided, and only reset the colors of those who have never collided before in the loop, using an <code>Array</code>, for example:</p> <pre><code>var collisions = []; for (var i = 0; i &lt; balls.length; i++) { for (var j = 0; j &lt; 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) &lt;= 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); } } } } } </code></pre> <p>Also, the second loop could be simplified to start from <code>i + 1</code> instead of <code>0</code>. This way, you not only reduce the number of collision tests, but also remove the <code>i != j</code> test.</p> <p><strong><a href="http://jsbin.com/imofat/820/edit" rel="nofollow">DEMO</a></strong>.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload