2D оборона башти - куля до ворога


14

Я намагаюся знайти гарне рішення для кулі, щоб вдарити ворога. Гра - 2D башта оборони, вежа повинна стріляти кулею та вражати ворога.

Я спробував це рішення - http://blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-1/

Згадане посилання для віднімання походження кулі та ворога (векторне віднімання). Я спробував це, але куля просто слідує навколо ворога.

float diffX = enemy.position.x - position.x;
float diffY = enemy.position.y - position.y;

velocity.x = diffX;
velocity.y = diffY;

position.add(velocity.x * deltaTime, velocity.y * deltaTime);

Я знайомий з векторами, але не впевнений, які кроки (векторні математичні операції) потрібно зробити, щоб це рішення працювало.


Відповіді:


11

Ваші міркування були ідеальними: використовуйте вектор для переміщення з мого положення до моєї цілі. Це призначення вектора ; ви просто забули швидкість !

Швидкість - вектор: швидкість і напрямок. Однак якщо ви забудете нормалізувати різницю вектора і помножити на нього швидкість кулі (скаляр), ви в основному говорите, що якщо ви близькі до цілі (вектор різниці невеликий), куля сповільнюється ; тоді як якщо ви далеко, швидкість кулі більша.

Це основна проблема: потрібно обчислити і напрямок, і величину вектора.


Дякуємо за допомогу. Я спробував використовувати скаляр після того, як я обчислив вектор різниці, він виглядає, що він спрацював, але виглядає не добре. Я спробував побачити, чи обчислюю різницю вектора, нормалізую, а потім скалярну швидкість. Зараз краще виглядає. Так, я думаю, мені потрібні ракети-навігатори в цій грі десь пізніше. Знову дякую.
Ташу

1
Чи не має цієї відповіді сенсу для когось іншого?
BlueRaja - Danny Pflughoeft

@Fxlll: Гаразд, я думаю, я бачу те, що ти намагаєшся сказати. На початку / в кінці відповіді багато пуху, і мене також збентежила ваша англійська (яка, я розумію, напевно, не винна) . Я надіслав пропозицію щодо редагування, щоб очистити цю відповідь.
BlueRaja - Danny Pflughoeft

@BlueRaja - Денні Пфлугхофт дякує за ваші зусилля!
FxIII

7

Якщо ціль рухається в постійному напрямку в рівномірному темпі, а ваш шлях кулі йде по прямій рівномірному темпі, ви можете використовувати квадратичне рівняння, щоб передбачити точне місце, де вони будуть перетинатися і націлити пістолет вашої вежі на це місце .

Оскільки є впевненість, що куля вдарить по знаку, і ви можете обчислити точний час, який знадобиться від стрільби до удару, не потрібно буде виявляти зіткнення, просто вистріліть пістолет, зачекайте розрахований часовий проміжок, зареєструйте удар.

Ось псевдокод для квадратичного рівняння:

Vector totarget =  target.position - tower.position;

float a = Vector.Dot(target.velocity, target.velocity) - (bullet.velocity * bullet.velocity);
float b = 2 * Vector.Dot(target.velocity, totarget);
float c = Vector.Dot(totarget, totarget);

float p = -b / (2 * a);
float q = (float)Math.Sqrt((b * b) - 4 * a * c) / (2 * a);

float t1 = p - q;
float t2 = p + q;
float t;

if (t1 > t2 && t2 > 0)
{
    t = t2;
}
else
{
    t = t1;
}

Vector aimSpot = target.position + target.velocity * t;
Vector bulletPath = aimSpot - tower.position;
float timeToImpact = bulletPath.Length() / bullet.speed;//speed must be in units per second

Дякую за псевдокод, я перевірю його, щоб побачити, як працює квадратичне рівняння у цій ситуації. Знову дякую.
Ташу

Проблема полягає в тому, що користувач може рухатися в бік кулі і безпосередньо перед ударом, він може піти від сліду кулі. Чи в цьому випадку це рішення було б досить хорошим?
Мартін.

Ні, як кваліфіковано в першому реченні. Це не для всіх ігор, але для гри, в якій цілі рухаються лише з постійною швидкістю. Постійна швидкість означає і напрямок, і швидкість. Наприклад, гра в грі у стилі Defense Grid може використовувати цей підхід.
Стів Н

3

Вам потрібно «передбачити» положення об’єктів до того моменту, коли куля досягне його. Ви можете зробити це, використовуючи об'єкти швидкість / швидкість (сподіваємось, що це постійна;)) і це спрямований вектор.

Я не впевнений, яка саме формула лежить у верхній частині моєї голови, але я думаю, що це щось подібне:

NewPosition = OldPosition + (Швидкість * DirectionVector);

Якщо у вас встановлений шлях, вам потрібно буде перерахувати, коли об’єкт змінює напрямок. Використовуйте цей NewPosition в якості вашого ворога.позиція вектора, і куля повинна вражати об'єкт без "ефекту наведення". Хомінг відбувається через те, що противник перемістився з моменту обчислення вихідного вектора, він може коли-небудь наздогнати, коли об’єкт рухається в одному напрямку досить довго.

Сподіваюся, це допомагає :)


3
Або ви можете обдурити і автоматично вдарити, тоді використовуйте рухомий спрайт як візуальний зворотній зв'язок. Або просто вистріляйте кулі зі швидкістю 50000 м / год.
Джонатан Коннелл

1

Ви можете уникнути використання квадратного кореня та потужності 2.

var distX:Float = target.x - x;
var distY:Float = target.y - y;
_velX = distX / timeTravel;
_velY = distY / timeTravel;

// Take out if you want a nice slow down as approaches effect.  
timeTravel -= 1.0; // make sure u have a positive timeTravel.
x += _velX;
y += _velY;

if (distX < 0)
    distX = -distX;

if (distY < 0)
    distY = -distY;

if (_velX < 0)
    _velX = -_velX;

if (_velY < 0)
    _velY = -_velY;

// Should both snap @ the same time.
if (distX < _velX)
x = target.x; // snap & see what happens.

if (distY < _velY)
y = target.y; // snap & see what happens.

// TODO: call your onHitTarget here ...
// Hopefully this shall provide 10x the performance 
// of using Math.sqrt and all the extra multiplications.

Це все написано з пам’яті. До речі, використовуйте елементи, які працюють - протестуйте це по черзі, якщо ви в цьому новачок. Поплавок - це число в AS3.

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