rework studio collisions

Add a studio unit test (will probably add more in the future).  A bunch of these changes were to support that.

Cleaned up how collisions work.  Instead of using a bitmask, use a hash.  One of the problems with the bitmask is that we now have enough sprites that we were treating sprite 16 and the first edge as equivalent for the purposes of collisions.  I don't think there was any direct user bad, since we dont have that many sprites at once in non-K1, and I don't think we have edge collisions in K1.  However, I still think my solution is a lot easier to read.

It also turned out that the only sprites using the Sprite class were projectiles.  I changed this, but I think there's likely still more opportunity to make things cleaner in this respect.
could be `this.clearCollisions()` just to single-point-of-truth it