Ну думаю можно и аналитически это дело решить.
Только тебе не хватает еще упругости шарика, т.к. от упругости зависит степень отскакивания.
Проверить на столкновение, легко:
collided = distance < (radiusA + radiusB );
Далее берем степень смещения:
overlap = distance - (radiusA + radiusB );
И угол смещения между шариками:
ballVector = normalize(posA - posB );
Теперь нам нужно узнать фактор массы относительно общему столкновению для каждого шарика:
massAFactor = massA / (massA + massB );
massBFactor = massB / (massA + massB );
И теперь можем решить коллизию:
posA += ballVector * massBFactor * overlap;
posB += -ballVector * massAFactor * overlap;
На данный момент они уже не коллизятся. Данный код - аппроксимация. На деле тебе нужно смещать обратно шарики исходя из их скорости полета, чтобы честно узнать позиции при которых было столкновение. Я в данном случае просто применил их массы, чтобы создать эфект тяжести при толкании.
Далее у тебя есть вектор направления шариков, и скорость. Сперва реализуй решение нового направления и сохраняя скорость. При этом тут уже нужно использовать формулу отрожение луча от сферы. Степень отражения будет зависит от упругости обоих тел.
Скорость отражения будет уже зависеть от разницы масс обоих тел.
Начинай с простого, без массы и без упругости, затем аналитически добавляй правила в вычисления.
Вот хорошие доки по чтению:
http://paulbourke.net/geometry/circlesphere/
Ну и в конце концов, никто не отменяет отличное наличие физ движков, которые это все для тебя уже решили, и юзать их и не заморачиваться - обычно вариант который позволит фокусироваться на игре, а не технологии.