Heya! I’m making a 2D platformer and I already have the collision working well. Sadly, there isn’t enough communication between objects that are colliding with each other that will allow anything specific to happen when a collision occurs. Lemme describe what currently happens.
I have two interfaces. The Collider interface enforces collisions on game entitites implementing the Moveable interface. Entities implementing the Moveable interface store information regarding its velocities and previous positions so that a Collider may do it’s job.
When a Collider enforces a collision on a Moveable, the Collider does whatever it needs to do to enforce its collision (positioning the Moveable and setting its velocities to whatever), then it invokes one of the following methods that the Moveable interface specifies: hitLeft(), hitRight(), hitTop(), hitBottom(). So far, this merely alerts a Moveable that a particular side has been hit. It’s useful when I want an animation to play when a side has been hit, but it doesn’t provide enough information.
Currently, when my Player entity (which implements Moveable) is touching the ground, if |velocityX| > 0, then the running animation starts. What if the platform that the Player is on is moving, though? The Player’s vx will be greater than 0, so the animation for running will play even though the Player SHOULD be standing still on the moving platform. I want to go about fixing this by allowing there to be a bit more communication between the Collider and the Player when a collision occurs, but I don’t want to bloat the Moveable and the Collider interfaces too much.
My first thought was to have the methods hitLeft(), hitRight(), etc… Require a multitude of parameters such as…
public void hitLeft(float relativeVx)
{
// Codeity code…
}
The parameter ‘relativeVx’ would be a velocity x that the Player’s run animation would be centered around (instead of having the animation depend on Player’s vx being greater than 0).
BUT WAIT! THERE’S MORE!
What if after I’ve finally refactored my code, I decide that I also want sound to be attached to collisions? Now I need to add more parameters to the enforceCollision method, then refactor my code once more!
Then I though of something… What if I sent in an object representing the collision that happens? It would allow me to add a multitude of arguments and store it in one object like so:
public void hitLeft(CollisionEvent e)
{
// Montage of code…
}
Huh, reminds me of swing…
Each time that I invoke this method, of course, I will be reusing the CollisionEvent object instead of creating a new one. This will work because the CollisionEvent object will be muteable. The Moveable taking in the CollisionEvent from the Collider will be able to pick and choose which elements of the event to consider, and which to ignore. The Event could have variables pointing to sounds, the Collider enforcing the collision, visual effects that may be generated because of the collision (sparks, dust particles), info about the Collider’s trajectory, etc… Since I’m not instantiating a new CollisionEvent object each time this happens, I don’t have to feel bad about making the garbage collector discard a bunch of short-lived objects, because I’m not.
My only regret is that, one way or another, there is a little bit of bloat that comes about from this process. The CollisionEvent object may not need a sound attached to it, or the relativeVx variable could be useless because the Collider never moves.
I’m not quite sure if this is the best way to handle this situation, so I’d like to hear what other people have to say!