Search code examples
javaandroidgame-physicsgravity

Collision response with moving obstacles (2D)


I'm developing an Android game somewhat similar to Star Control.

In this game, planet gravity plays a huge role, and so the player's ship is affected by various planets. In this game, there are multiple planets which move (orbit).

My main issue at the moment is handing collision response. When the player hits a planet, i want the player to have a small "bounce". I used this: https://www.youtube.com/watch?v=ymgbDdO8hKI as a source to program this, and it works great for planets which don't move.

However, when the planet does move, the algorithm works great when the planet is moving away from the player, but if the player is in the planet's path (i.e., the planet is moving towards the player), the planet sort'v "eats" the player.

I know I need to compensate somehow for the planet's velocity. I've tried different variations, such as add the planet's vector to the overall resulting vector of the bounce, but nothing seems to give a good result... the planet always seems to eat up the player when the planet moves towards the player.

If you guys would like me to post code samples, let me know, although I'm looking for more of a "concept" solution, like the video linked above provides.

Thanks in advance!


Solution

  • For applying directly the concepts in that video, you can switch to a reference frame where the planet does not move at the time of the collision. For that, and considering just classical physics, you just need to change the velocity of the player subtracting the speed of the planet (2D vector subtraction). Then apply the formula in the video, and finally switch back to your original reference frame by adding the speed of the planet (2D addition).

    In a notation similar to the one in the video, being v_before the velocity of the player before bouncing, v_planet the velocity of the planet, n the normal of the planet surface where the collision occurs and C the restitution coefficient,

    v_before_2 = v_before - v_planet                       // change of reference frame
    v_after_2 = v_before_2 - (1 + C) * (v_before_2 . n) * n  // simple wall bouncing
    v_after = v_after_2 + v_planet                         // change to original reference frame