7.4 Removing Objects

Of course you also want to remove objects from a container. Which is not that hard:

 
Memc<Vec2> dots; 
 
// ... add a lot of dots 
 
5dots.remove(0); // remove the first dot  

With the method remove and the index of the element as an argument, you delete an object in a container. Be careful though. Very often you will want to remove an element while iterating over a container. It is a common beginner mistake to alter an object after you’ve deleted it:

 
for(int i = 0; i < dots.elms(); i++) { 
  if(dots[i].y < -D.h()) { 
    dots.remove(i); 
  } 
5  dots[i].y -= Time.d(); 
}  

In the example above, all dots are moved down at every update. When a dot arrives at the bottom of the screen, it will be removed from the container. After removing a dot, it is not the current dot that is moved down, but the next one in the container. This is not a big problem, unless this was actually the last dot in the container. In which case you try to move down an object past the end of the container. The result will be a program crash, your computer might explode and probably a kitten will die somewhere.

To prevent this from happening it is a good rule to put the remove method as the last statement in the loop:

 
for(int i = 0; i < dots.elms(); i++) { 
  dots[i].y -= Time.d(); 
  if(dots[i].y < -D.h()) dots.remove(i); 
}  
5

Things start to be a bit more complicated when you combine more than one container. In the next example we have container for dots and a container for circles. The code tries to verify if a dot hits a circle. If this is the case, both the circle and the dot must be removed from their container. To do this, we have to check every dot against every circle.

 
for(int i = 0; i < dots.elms(); i++) { 
  for(int j = 0; j < circles.elms(); j++) { 
      if(Cuts(dots[i], circles[j])) { 
        dots.remove(i); 
5        circles.remove(j); 
        // At this point there is one less dot in the container, but 
        // the remaining circles will still be compared against the current dot. 
        // current dot. If we are at the last dot, it will no longer be valid. 
        // To prevent a crash, we add a break statement to go back to 
10        // the outer for loop: 
        break
    } 
  } 
}  
15

And if you’d like to clear all container elements at once:

 
dots.clear();