title: How to properly remove a ball from an HTML-5 canvas when the player hovers on it?
body: <p>I've developed a small game that requires the player to "eat" only the green balls in an HTML5-canvas in order to succeed.</p>
  
  <p>I've come to the part where when you hover on the ball, it gets eaten. But some REALLY weird behavior arises. Instead of only one ball getting eaten, A WHOLE LOT OF THEM JUST SUDDENLY DISAPPEAR.</p>
  
  <p>Here's my code:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-css lang-css prettyprint-override"><code>body {
      overflow: hidden;
      background: rgba(82, 80, 78, 0.75)
  }
  
  #gameCanvas {
      border: 0.25em solid black;
      background-color: rgba(255,235,205,0.5);
      margin-top: 1.25vh;
  }
  
  * {
      margin: 0;
      padding: 0;
      border: 0;
      outline: 0;
      font-size: 100%;
      vertical-align: baseline;
      background: transparent;
  }
  
  #flexContainer {
      margin-top: 0.5em;
      font-family: Verdana;
      font-size: 2.5em;
      display: flex;
      justify-content: space-around;
  }
  
  #flexContainer span{
      background: rgba(255, 180, 0, 0.50);
      transition-duration: 0.5s;
      padding: 0.1em;
      border-radius:0.25em;
  }
  
  #flexContainer span:hover {
      background: rgba(255, 180, 0, 0.8);
      transition-duration: 0.5s;
      border-radius: 1em;
      cursor:pointer;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt;
  
  &lt;html lang="en" xmlns="http://www.w3.org/1999/xhtml"&gt;
  &lt;head&gt;
      &lt;link type="text/css" rel="stylesheet" href="EatTheBall.css" /&gt;
      &lt;meta charset="utf-8" /&gt;
      &lt;title&gt;EatTheBall!&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
      &lt;div id="flexContainer"&gt;
          &lt;span id="49" onclick="changeNumBalls();"&gt;Level 1&lt;/span&gt;
          &lt;span id="30" onclick="changeNumBalls();"&gt;Level 2&lt;/span&gt;
          &lt;span id="20" onclick="changeNumBalls();"&gt;Level 3&lt;/span&gt;
          &lt;span id="10" onclick="changeNumBalls();"&gt;Level 4&lt;/span&gt;
          &lt;span id="0" onclick="changeNumBalls();"&gt;Level 5&lt;/span&gt;
      &lt;/div&gt;
      &lt;canvas id="gameCanvas"&gt;&lt;/canvas&gt;
      &lt;!--Start of JavaScript code--&gt;
      &lt;script&gt;
          var XPos = 0;
          var YPos = 0;
  
          var n = 40;
  
          var gameCanvas = document.body.querySelector("#gameCanvas");
          var ctx = gameCanvas.getContext("2d");
  
          var colorArray = ["red", "orange", "yellow", "green", "blue", "indigo", "violet"];
          var balls = [];
  
          window.onload = function initial() {
              gameCanvas.height = 0.9 * window.innerHeight;
              gameCanvas.width = 0.995 * window.innerWidth;
  
              window.addEventListener("resize", function (evt) {
                  gameCanvas.height = 0.9 * window.innerHeight;
                  gameCanvas.width = 0.995 * window.innerWidth;
                  gameCanvas.style.marginTop = (1.25 * window*innerHeight) +"vh";
              })
              movePlayer();
              MainLoop(); 
              addBalls();
          }
  
          function MainLoop() {
              ctx.clearRect(0, 0, gameCanvas.width, gameCanvas.height);
    
              drawBalls(balls);
              animateBalls(balls);
  
              requestAnimationFrame(MainLoop);
          }
  
          function addBalls() {
              while (n &lt; 50) {
                  n++;
                  var b = {
                      x: window.innerWidth / 2,
                      y: window.innerHeight / 2,
                      radius: Math.random() * 30 + 15,
                      speedX: -7.5 + Math.random() * 15,
                      speedY: -7.5 + Math.random() * 15,
                      color : colorArray[Math.round(Math.random() * 6)]
                  }
                  balls.push(b);
              }
          }
          function drawBalls(ballArray) {
              ballArray.forEach(function (b) {
                  drawOneBall(b);
              });
              drawPlayer();
          }
          function animateBalls(ballArray) {
              ballArray.forEach(function (b) {
                  b.x += b.speedX;
                  b.y += b.speedY;
                  testCollisionBallWithWalls(b);
              });   
          }
          function drawOneBall(b) {
              ctx.save();
              ctx.beginPath();
              ctx.arc(b.x, b.y, b.radius, 0, Math.PI * 2);
              ctx.fillStyle = b.color;
              ctx.fill();
              ctx.restore();
          }
          function testCollisionBallWithWalls(b) {
              if ((b.x + b.radius &gt; gameCanvas.width) || (b.x - b.radius &lt; 0)) {
                  b.speedX = -b.speedX;
              };
              if ((b.y + b.radius &gt; gameCanvas.height) || (b.y - b.radius &lt; 0)) {
                  b.speedY = -b.speedY;
              };
              if (XPos &gt; b.x - b.radius &amp;&amp; XPos &lt; b.x + b.radius &amp;&amp; YPos &gt; b.y - b.radius &amp;&amp; YPos &lt; b.y + b.radius) {
                  balls.splice(b, 1);
              }
              if (XPos &lt; b.x - b.radius &amp;&amp; XPos &gt; b.x + b.radius &amp;&amp; YPos &lt; b.y - b.radius &amp;&amp; YPos &gt; b.y + b.radius) {
                  balls.splice(b, 1);
              }
          }
          function changeNumBalls() {
              n = event.currentTarget.id;
              balls = [];
              addBalls();
              drawBalls(balls);
              animateBalls(balls);
          }
          function drawPlayer() {
              ctx.save();
              ctx.fillStyle = "red";
              ctx.fillRect(XPos, YPos, 30, 30);
              ctx.restore();
          }
          function movePlayer() {
              gameCanvas.addEventListener("mousemove", function (evt) {
                  XPos = evt.clientX - 15;
                  YPos = evt.clientY - 100;
              })
          }
      &lt;/script&gt;
  &lt;/body&gt;
  &lt;/html&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>CODE EXPLANATION TIME!</p>
  
  <p>The idea is that I declare a variable named "balls" at the beginning, and I assign a value of an empty array to it. Then the balls are created by using a while loop. The while loop keeps adding new object literals, which describe the properties of the ball (aka. the position of the center of the ball, the length of the radius, etc.), to the empty array. Next I call 2 functions, one to actually draw the balls using the properties in each object literal that has been added to the array. The other one is used to animate the balls. I've used the <em>forEach()</em> method with both of the functions.</p>
  
  <p>As for the player, I created a fillRect() in the canvas. I set the x1 and y1 properties* to the position of the cursor using a <em>canvas.addEventListener('mouseover', ...)</em>
  <hr>
  *fillRect(x1, y1, x2, y2)
  <hr>
  Next up is the tricky part...</p>
  
  <h1>COLLISION DETECTION!</h1>
  
  <p>Whenever the player moves into one of the balls, the ball should automatically disappear using the <em>array.splice()</em> method. HOWEVER, that does not happen. Instead of only one ball disappearing, as mentioned beforehand, more than one disappear.</p>
  
  <p>I've actually got insight onto how exactly is the problem produced. When the ball collides with the player, if instead of using an <em>array.splice()</em>, you just display a random message in the console (console.log(random shit)), the message will not be only displayed once, <em>it will get displayed multiple times</em>.
  <hr>
  If my explanation wasn't clear enough, then please inspect the code by yourself and try to understand it. I will be <strong>GREATLY</strong> thankful, thanks in advance.</p>