PDA

Просмотр полной версии : Стрельба по движущимся целям


AleXNoD GD
19.05.2008, 18:28
День добрый, уважаемые флэшеры.

Давно хочу сделать ИИ, который будет стрелять по игроку, рассчитывая его траекторию, то есть туда, где он ДОЛЖЕН появиться, если не изменит скорость или направление. В баллистике это называется упреждением. У кого есть мысли, как всё это перенести на AS?

Скажем, есть два объекта (b1 и b2). Одна из них - пуля (b1), другая - цель (b2). b2 летит с произвольной скоростью в произвольном направлении. А задача b1 - определить, где будет находиться b2 в тот момент, когда s1/v1 = s2/v2 (s - пройденное расстояние, v - скорость, соответственно s/v - время, которое должно быть одинаковым). Для наглядности приведу рисунок.

http://fundux.ru/uploads/ris.gif

Vertax
19.05.2008, 18:48
Движение перса и движение пули - это по сути вектора. Сложи их (вектора или прирощения по осям) и получишь требуемую точку.

AleXNoD GD
19.05.2008, 18:58
Для начала необходимо найти эти вектора) На рисунке конечный вариант, а изначально вектор (b1-ТС) неизвестен. Известны лишь скорости, местоположения объектов и направление b2.

Vertax
19.05.2008, 19:06
A = Вектор стрельбы: b1-b2 (известен)
B = Вектор ходьбы: b2-TC легко найти зная скорость
C (требуемый) = A + B

Psycho Tiger
19.05.2008, 19:27
Хм.. Физика, 8 класс:
X Final = Current _X + Xmov*time;
Y Final = Current _Y + Ymov*time;

AleXNoD GD
19.05.2008, 19:27
4:

Дык ТС неизвестна :D
Она дана чисто для примера, но её и надо вывести.
Для ясности:

http://fundux.ru/uploads/ris2.gif

Хм.. Физика, 8 класс:
X Final = Current _X + Xmov*time;
Y Final = Current _Y + Ymov*time;

Не знаю, откуда эти формулы, но они явно не подходят. Тут без тригонометрии нельзя.

Psycho Tiger
19.05.2008, 20:15
Как движение задано?
Если я правильно понял, то дан угол движения и скорость этого движения, тогда:
Xmov=cos(angle)*speed;
Ymov=sin(angle)*speed;

Далее,
X Final = Current _X + Xmov*time;
Y Final = Current _Y + Ymov*time;

Откуда формулы? Сейчас в голове вывел :)
Обьясню:
Сначала находим скорость по оси Х, это будет xMov - далее, если скорость не измениться - то через time секунд он будет в текущей позиции плюс эта скорость по оси Х умноженная на время.
Аналогично и для _Y

Vertax
19.05.2008, 22:45
//Пригодится
ANGLE2D = function (X1, Y1, X2, Y2){return 180 * Math.atan2((X2 - X1), (Y2 - Y1)) / Math.PI;}
LEN2D = function (X1, Y1, X2, Y2){return Math.sqrt(Math.pow(X1 - X2, 2) + Math.pow(Y1 - Y2, 2));}
COS = function (ANGLE) {return Math.cos(ANGLE * Math.PI / 180);}
SIN = function (ANGLE) {return Math.sin(ANGLE * Math.PI / 180);}

Object.prototype.copy = function ()
{
var nOBJ = {};
for (var i in this) nOBJ[i] = this[i];
return nOBJ;
}

//Делаем вектор
vector = function (X, Y, DX, DY)
{
var OBJ = {};
OBJ.x = X;
OBJ.y = Y;
OBJ.dx = DX;
OBJ.dy = DY;
OBJ.speed = Math.sqrt(DX * DX + DY * DY);
return OBJ;
}

var B1 = vector(100, 100, 5, 0); //Цель
var B2 = vector(400, 400, 40, 0); //Стрелок

SIMULATE = function (LVL, LEN)
{
if (LVL > 100) return false; //Если более 100 шагов, то болт
BTEMP1.x += BTEMP1.dx;
BTEMP1.y += BTEMP1.dy;
bANGLE = 90-ANGLE2D(BTEMP2.x, BTEMP2.y, BTEMP1.x, BTEMP1.y);
currLEN = LEN2D(BTEMP1.x, BTEMP1.y, BTEMP2.x, BTEMP2.y);
if (currLEN < BTEMP2.speed) return {len:LEN, lvl: LVL}; //Если растояние до цели меньше шага, то попали
//Если нужно более точно, то {len:LEN + currLEN
BTEMP2.x += COS(bANGLE) * BTEMP2.speed;
BTEMP2.y += SIN(bANGLE) * BTEMP2.speed;
return SIMULATE(LVL + 1, LEN + BTEMP2.speed);
}

//Создаю временные копии
var BTEMP1 = B1.copy();
var BTEMP2 = B2.copy();

if (T = SIMULATE(0, 0)) //Это не опечатка
{
COOF = LEN2D(B2.x, B2.y, BTEMP1.x, BTEMP1.y) / T.len;

//Искомые точки
TC = {};
TC.x = (BTEMP1.x - B1.x) * COOF + B1.x;
TC.y = (BTEMP1.y - B1.y) * COOF + B1.y;

//Для примера
_root.lineStyle(1, 0xFF0000);
_root.moveTo(B1.x, B1.y);
_root.lineTo(TC.x, TC.y);
_root.lineStyle(1, 0x0000FF);
_root.moveTo(B2.x, B2.y);
_root.lineTo(TC.x, TC.y);
}Думаю разберешся.

P.S. Поэксперементировал... ну флеш над дробями и издевается. В примере красный шар должен летать четко по зеленой линии.

goarcade
20.05.2008, 19:22
Psycho Tiger
Vertax
В условии сказано же: -"Известны лишь скорости, местоположения объектов и направление b2."
направление b1 неизвестно!

AleXNoD GD

точка TC это b2+V2*t, где t неизвестное число, а V вектор скорости b2.

t находится из уравнения такого вида

length((b2+V2*t)-b1) = v1*t
где v1 величина скорости b1

должно получится квадратное уравнение. Решаем, получаем t, ну и находим TC = b2+V2*t