Керована ракета з постійним часом


9

Я будую гру з гравцями та ракетами.

Я хочу вистрілити ракету з Р1 до Р2. Ракета завжди повинна тривати рівно п’ять секунд, щоб досягти Р2. Ракета також повинна відслідковувати Р2. Якщо Р2 рухається далі, ракета повинна прискорити швидкість, щоб задовольнити обмеження часу. Якщо Р2 рухається ліворуч, ракета повинна рухатись ліворуч (а також змінювати швидкість). Якщо Р2 рухається ближче до Р1, ракета повинна сповільнитися.

Чи можливо це? Який найкращий спосіб досягти цього?

Наразі у мене немає класу Vector2D (це насправді не гра, але аналогія працює добре), тому, якщо можливо, я хотів би отримати рішення, яке не потребує такого.

Правка: Насправді це теж не ракета. :)

Дякую!


1
(Мені дещо страшно, коли хтось запитує про наведення ракет, кваліфіковане "це насправді не гра", але ...) Чи є у вас обмеження у формі траєкторії ракети? Чи завжди він може вести пряму лінію між поточною позицією та гравцем 2? Чи має обмеження його радіус повороту чи прискорення? Чи потрібно уникати перешкод? Також ви згадуєте Vector2D - чи можна припустити, що вам це потрібно лише у 2D? Ви можете робити всю векторну математику компонентно, але незграбно писати порівняно з простим векторним математичним класом, тому я не дуже розумію перевагу проти цього.
DMGregory

Ви пропустили додаткову інформацію. Чи є обмеження? Чи рухаються ракети по лінії або нам слід дбати про напрямки, і скільки розмірів у підсумку?
liggiorgio

Шлях не повинен обмежуватися. Єдині правила: А) "Ракета" завжди повинна робити кроки до своєї цілі. Б) "Ракеті" завжди потрібно 5 секунд, щоб дістатися туди. Написання класу Vector2D - це не проблема. У мене просто немає однієї зручної роботи (а математика - не найкращий предмет). Якщо це полегшить, я можу додати його.
Пітер

Найпростіший спосіб зробити це - використовувати сплав гермітів і лерпувати параметричне значення.
Стівен Срун

Відповіді:


11

Правка заспокоює. :)

Гаразд, ось прямий цикл оновлення ...

Припускаючи, що ми вистріляємо ракету, яку ми ініціалізуємо remainingFlightTime = 5fтоді ...

void UpdateMissile(float deltaTime)
{
   remainingFlightTime -= deltaTime;

   // At the end of the trajectory, snap to target & explode.
   // The math will put us there anyway, but this saves
   // on fancy logic related to overshooting. ;)
   if(remainingFlightTime <= 0f)
   {
      myX = targetX;
      myY = targetY;
      MissileImpact();
      return;
   }

   // Compute straight-line velocity that will take us
   // to the target in exactly the time remaining.
   velocityX = (targetX - myX)/remainingFlightTime;
   velocityY = (targetY - myY)/remainingFlightTime;

   // Integrate the velocity into the position.
   myX += velocityX * deltaTime;
   myY += velocityY * deltaTime;
}

1
Цей метод не дозволяє «ракеті» обертатися навколо точки запуску, в середині польоту. +1
Джон

0

Чому б не лерпувати позицію та не оновлювати цільове призначення у міру зміни?

Можливо, вам доведеться подивитися, як працює лерпінг, але це виглядатиме приблизно так:

public position startMarker;
public float duration = 5.0f;
private float startTime;
void Launch() {
    startTime = Time.time;
}
void Update() {
    float distCovered = (Time.time - startTime) / duration;
    missile.position = Vector3.Lerp(startMarker.position, target.position, distCovered);
}

лерпуючи, ви в основному змінюєте положення об'єкта за певний проміжок часу, щоб ви могли сказати, що ви перебуваєте на 50% шляху від А до В, і об’єкт був би поміщений туди. Лерпінг прямий, тому ви завжди будете рухатися до цілі (як хочете в коментарях).


так добре, моє погано ... я здогадуюсь, що станеться, якщо ви спробуєте кодувати о 3 ранку. змінив відповідь, щоб виправити помилку
користувач3797758
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.