You shouldn't add or remove object from an array as you iterate over it using the forEach()
function.
From MDN:
The range of elements processed by forEach()
is set before the first invocation of callback
. Elements that are appended to the array after the call to forEach()
begins will not be visited by callback
. If the values of existing elements of the array are changed, the value passed to callback
will be the value at the time forEach()
visits them; elements that are deleted before being visited are not visited. If elements that are already visited are removed (e.g. using shift()
) during the iteration, later elements will be skipped
In other words, think harder about what this if
statement is doing:
if (i.opacity == 0) {
balls.shift();
}
Here, you check whether i
(the current ball) has an opacity of zero, and if so, you then remove the first ball. This is almost certainly not what you want to do.
Googling "javascript modify array during forEach" will return a ton of results. Hint: you might consider splitting this up into two steps: one that loops over the array and adds new balls, and another step that loops over the array and removes the balls you want to delete. Basic for
loops will get you pretty far here.