Возможно, вы захотите проверить Часто задаваемые вопросы по гравитации GameDev.net для получения некоторой базовой информации.
Поскольку вы создаете игру, а не модельер физики с высокой точностью, чем мы можем избежать интеграций Эйлера . Если ваша потребность в точности возрастает, наиболее популярный метод интеграции, который я вижу, это интеграция Рунге-Кутта (RK4) . Скорее всего, они вам не понадобятся для простой игры, но они определенно используются в более сложных физических симуляциях и трехмерных играх. Недостаток использования RK4 - немного увеличенная сложность и немного медленнее. Это очень точно, но пока давайте придерживаться хорошего оле Эйлера.
Я задал похожий вопрос: « Как применить гравитацию к моей игре с прыгающим мячом », и получил несколько хороших ответов. Первое, что вы должны сделать, это выбрать произвольную гравитационную постоянную для вашей игры. В моем приложении с прыгающим мячом я использую гравитационную постоянную по умолчанию, равную 2000 пикселей / с. Вы захотите поиграть с этой гравитационной постоянной, чтобы получить желаемый эффект для вашей конкретной игры.
Далее, вы хотите убедиться, что вы рендерируете свою игру и обновляете игровые объекты независимо друг от друга. Это сделано для того, чтобы предотвратить быстрое перемещение объектов в игре на быстрых компьютерах и замедление на медленных компьютерах. Вы хотите, чтобы физика и скорость перемещения ваших объектов не зависели от скорости компьютера. Хорошая статья на эту тему: Физика игры: исправьте время! .
Так как мы это сделаем? Вы отслеживаете, сколько времени прошло с момента последнего вызова метода Update. Я создал 2 темы, хотя в этом нет необходимости. У меня есть ветка обновления игры и рендеринга. Поток обновления управляет обновлением позиций игровых объектов. Поток обновления знает, когда он был вызван ранее, текущее время и отсчитывает, сколько времени прошло с момента вызова метода обновления.
Чтобы применить гравитацию, мы просто добавим к скорости Y нашего объекта нашу гравитационную постоянную, умноженную на истекшее время.
private long previousTime = System.currentTimeMillis();
private long currentTime = previousTime;
public void updateGame()
{
currentTime = System.currentTimeMillis();
float elapsedSeconds = (currentTime - previousTime) / 1000f;
foreach(GameObject gameObject in gameObjects)
{
// Apply gravity to velocity vector
gameObject.velocity.y += (gravityConstant * elapsedSeconds);
// Move objects x/y position based off it's velocity vector
gameObject.position.x += (gameObject.velocity.x * elapsedSeconds);
gameObject.position.y += (gameObject.velocity.y * elapsedSeconds);
}
checkCollisions();
previousTime = currentTime;
}
Это будет двигать все ваши объекты на основе их векторов скорости и применять гравитацию к ним на основе вашей гравитационной постоянной. Лучше всего он делает это независимо от скорости компьютера!
Чтобы ответить на ваш другой вопрос, да, у объектов будет постоянно "сила" гравитации на их y-векторе. Так что он будет постоянно сталкиваться с полом. Однако, одну вещь, которую вы хотите сделать, это использовать значение Epsilon , чтобы в конечном итоге довести скорость вашего gameObject до нуля. Затем, во время обнаружения столкновений, как часть процесса обрезки, вы обычно можете пропустить проверку, сталкивается ли неподвижный объект с чем-либо (но не наоборот!).
Что мне нравится делать со столкновениями, так это то, что когда я нахожу объекты, сталкивающиеся друг с другом (проникающие друг в друга), я раздвигаю их на части по их минимальному расстоянию перемещения (MTD), которое разделяет их. Этот шаг является ключевым, в противном случае вы получите часто встречающуюся ошибку в играх с объектами, «застрявшими» вместе, движущимися с треском. Как только они разделены, я вычисляю мою реакцию на столкновение.
Используя этот метод, он будет хорошо работать в описанном вами сценарии восходящей платформы. Платформа будет продолжать расти, gameObject будет разделять себя, используя MTD между собой и платформой, и естественно будет расти вместе с ней.
Если вам нужна помощь по реагированию на столкновение, я бы посоветовал посмотреть: