Of course they’re easy to break. That’s not the same as coding to break them.
The idea from my buddy was just to jam a dead
flag into all the drawn objects, without them knowing, and then to use it. To do that willy-nilly leaves open the possibility that someone (me, in a forgetful moment) would put a dead
key in the object from the inside, and then either the outside usage or the inside, or both, would break.
In addition, this would be a violation of the “Law of Demeter”, which is an OO principle also sometimes called “Tell, don’t ask”, meaning that you should favor objects owning and dealing with their own state, over asking them questions and then doing things with them without their collaboration.
One alternative is to provide functions or methods up at the top to add objects to, or remove them from, the “universe”, and when it is time to consider collisions, send messages to (call methods on) the objects, allowing them to decide what to do. If they want to ignore collisions, as a Button might, they do so. If they think they’ve collided and died, they might request to be removed from the “universe”. Or they might do other things.
Either way, there is an interesting issue to be resolved: in principle, you’d like to consider A and B colliding only once, but there’s no really nice way to get all pairs of objects in a collection and process each pair only once. (And an associated concern is which comes first. Since the objects are in no particular order you might get a Ship and a Missile one time and a Missile and a Ship another time through the loop. Looping naively you absolutely will see Ship1 vs Missile1 and Missile1 vs Ship1, so you need to do something to treat that as only one collision.
The basic thing one does is to move responsibility to the object that “should” have that responsibility. The “universe” seems like the right place to consider pairs of objects, and the Ships and Missiles seem like the right guys to decide what to do when they’re in range of each other.
It’s an amusing problem.
As for the fact that all interfaces are easy to break, well, sure they are, but one programs to make that unlikely, according to my lights, although other people are more comfortable spinning out code and then debugging it. I have come to find any debugging at all to be a sign that I didn’t know what I was doing when I wrote the code.