ВНИМАНИЕ! Наша конференция посвящена космической тематике и компьютерным играм. Политические вопросы и происходящие в мире события в данный момент на нашем сайте не обсуждаются!
|
» Самонаводящаяся ракета в космосе | страница 3 |
|
|
|
Канал Игры Мечты: «Самонаводящаяся ракета в космосе» |
|
|
Crimson
560 EGP
    Рейтинг канала: 4(83) Репутация: 130 Сообщения: 3041
Зарегистрирован: 03.09.2003
 |
|
Aerton : |
Crimson : |
P.P.S. Можешь записать ролик с примером того, что не так с самым первым алгоритмом?
|
velocity pursuit и proportional navigation линиями обозначены вектора скорости. Ускорения, к сожалению в ренедере уже недоступны - надо будет подумать, как их прокинуть из питона.
|
Да с векторами и так все ясно, еще от ускорения палки рисовать только сильнее все запутает. А вот каким багом покусало твои ракеты это хз. Навскидку такое впечатление что ракета пытается тупо достичь заданной ориентации за минимальное время. И при достаточно высокой угловой скорости от цели ей "легче" ускориться еще больше в ту сторону, чем затормозить и разгоняться обратно.
Только вот толку от этого ноль, т.к. она должна не просто достичь этой ориентации, а еще и прийти к ней с нулевой угловой скоростью. Но это шаманство по фотографии, надо самому писать parallel navigation, дебажить, и выяснять косяк ли это самого алгоритма или особенности твоей имплементации...
Почему я и просил запись алгоритма с самого первого ролика (http://www.youtube.com/watch?v=i-24MW095Yg). Есть сильное подозрение что его будет проще довести до ума, чем parallel navigation. Ракеты может и мажут, но по крайней мере не страдают откровенной дурью.
Aerton : |
3d.Maxuz : |
Т.е хорошие ракетчики в голове рассчитывают соотношения своего движения (скорости, ускорения и вектора), того же для цели и всё это применительно к ттх ракеты уже.
|
Хотел сначала ракетам сделать наведение, потом уже обучать пилотов.
|
Чесгря если ты еще и хочешь полностью автоматизированные массовые бои AI, с реальной физикой, то легче сразу повеситься Но вообще да, ковырять AI ракеты и пилота надо одновременно.
Aerton : |
Хм, т.е. получается куда больше зависит от верного прицела - как для неуправляемой ракеты, а система наведения только немного корректирует?
|
Для любой ракеты, единственный шанс поразить цель - за счет превосходящей скорости и маневренности догнать ее раньше чем та успеет толком среагировать. Потому что если цель начнет реагировать - в честных маневренных догонялках ракета точно проиграет да хотя бы за счет ограниченного топлива. Особенно в условиях невесомости в вакууме, где цель может вытворять любые финты ушами какие ей только вздумается. Так что фактически да, любая коррекция с точки зрения ракеты должна выглядеть как "немного" подправить.
добавлено спустя 5 минут:
А, сорри, velocity pursuit-то я и не заметил. Чесгря там такое впечатление что ИИ инициализируется еще какое-то время после начала разгона Будем подумать дальше...
Последний раз редактировалось: Crimson (00:38 29-03-2011), всего редактировалось 1 раз |
|
|
Crimson
560 EGP
    Рейтинг канала: 4(83) Репутация: 130 Сообщения: 3041
Зарегистрирован: 03.09.2003
 |
|
Не, гоню, velocity pursuit отрабатывает как и "должен".
Для parallel navigation еще не помешало бы видео "с точки зрения ракеты", в котором камера вращается вслед за ней (или за ее вектором скорости). И замедление самого видео... чисто чтобы понять откуда берется закручивание. Но чисто по логике, если логика самой системы наведения работает правильно то браться оно может только из постоянного ускорения ракеты. Которое усугубляет и так растущую угловую скорость при сближении. Хотя все равно непонятно почему они отворачивают. Возможно получается что-то похожее на ситуацию с Луной (при взгляде с Земли кажется что она обращается с востока на запад, но это потому Земля сама вращается).
Вообще логика такая. Если цель движется с постоянной скоростью, то в координатах x-y-время ее траектория будет выглядеть как прямая. Если ракета тоже движется с постоянной скоростью, но в любой момент может развернуться в любую сторону - в той же координатной системе можно построить "конус в будущее" из линий, по которым ракета может полететь. Нас, естественно, интересует точка пересечения конуса с линией цели.
В твоей ситуации все в принципе то же самое, только вместо нормального конуса там будет поверхность вращения, задаваемая двойным интегралом от ускорения. И два режима - если цель "скользит" по инерции, то ее траектория все так же прямая, если нет - опять-таки двойной интеграл от ускорения (только уже цели). Только вот фиг бы там знал, как эти пересечения считать аналитически (и можно ли вообще). А если аппроксимировать численными методами, да на каждую ракету в массовке - мало не покажется...
|
|
|
Crimson
560 EGP
    Рейтинг канала: 4(83) Репутация: 130 Сообщения: 3041
Зарегистрирован: 03.09.2003
 |
|
Parallel navigation кстати тоже отрабатывает "как должен". Т.к. выбирает точку, в которой ракета перехватит цель двигаясь с постоянной скоростью. Но после этого ракета, естественно, ускоряется - и если ее так и оставить, в "точку рандеву" она прилетит раньше цели. Соответственно, она выбирает точку дальше от цели, до которой ей дольше лететь. Но с учетом разгона она и туда прилетит слишком быстро. Вот и получается эффект ракеты, убегающей от цели
|
|
|
Aerton
70 EGP
 Рейтинг канала: 1(8) Репутация: 4 Сообщения: 67 Откуда: Новосибирск Зарегистрирован: 20.08.2004
 |
|
Crimson : |
Чесгря там такое впечатление что ИИ инициализируется еще какое-то время после начала разгона Совсем запутался... Будем подумать дальше...
|
Сначала 0.25сек летим по инерции, потом включается двигатель и AI.
Crimson : |
Для parallel navigation еще не помешало бы видео "с точки зрения ракеты", в котором камера вращается вслед за ней (или за ее вектором скорости).
|
Интересная мысль, - сделаем.
Crimson : |
Только вот фиг бы там знал, как эти пересечения считать аналитически (и можно ли вообще). А если аппроксимировать численными методами, да на каждую ракету в массовке - мало не покажется...
|
Угу не хотелось бы.
Crimson : |
velocity pursuit отрабатывает как и "должен".
|
Crimson : |
Proportional navigation кстати тоже отрабатывает "как должен"
|
Warstone : |
Гм... Давай сборку... У мну на работе бубунта, дома бубунта, на ноуте бубнта... Ну... вы поняли... Кубик мне нравится...
|
тут Поведение ракеты задаётся в script/missile.py
Код: |
def _ai_control_velocity_pursuit (self):
while self.target.hp > 0:
a = self.actor.body.angle_to(*self.target.actor.body.position)
self.turn (calc_torque(self, a))
core.sleep ()
def _ai_control_proportional_navigation (self):
N = 15.0
while self.target.hp > 0:
x, y = self.actor.body.position
vx, vy = self.actor.body.velocity
xT, yT = self.target.actor.body.position
xT -= x
yT -= y
vTx, vTy = self.target.actor.body.velocity
vTx -= vx
vTy -= vy
hs = xT * xT + yT * yT
dw = N * (vTy * xT - vTx * yT) / hs
#print 'T %+.3f;%+.3f vT %+.3f;%+.3f\ths %f dw %f:%f' % (xT, yT, vTx, vTy, hs, dw, dw * self.acto
self.turn (dw * self.actor.body.inertia)
core.sleep () |
core.sleep() - ждать конца "кадра".
self.turn() - просто придаёт момент телу (полсе проверки на max)
calc_torque() - вычисляет какой момент придать в этом кадре, чтобы в итоге повернуть тело на заданый угол и иметь нулевую угловую скорость - код script/ai/direction_control.py
Остальное, наверное, очевидно.
Движок всё время вклюучен (в другой, параллельно исполняемой функции_engine_control)
|
|
|
Aerton
70 EGP
 Рейтинг канала: 1(8) Репутация: 4 Сообщения: 67 Откуда: Новосибирск Зарегистрирован: 20.08.2004
 |
|
Модификация velocity pursuit - двигать/приближать мышкой, как в google maps, требует HTML5-браузер. видео с векторами
Если угол между вектором скорости ракеты и направлением на цель между 5 и 60 градусами, то раекта поворачивает не прямо на цель, а под углом (константа, 45-90 градусов), гася боковую скорость.
Немного лучше, но надо победить крутилки. Интересно, что промахнувшаяся ракета, идущая на второй заход попадает лучше, чем с первого раза.
|
|
|
Crimson
560 EGP
    Рейтинг канала: 4(83) Репутация: 130 Сообщения: 3041
Зарегистрирован: 03.09.2003
 |
|
Aerton : |
Crimson : |
velocity pursuit отрабатывает как и "должен".
|
Crimson : |
Proportional navigation кстати тоже отрабатывает "как должен"
|
|
Ну опечатался, сорри Пишу одно, думаю о другом
Aerton : |
двигать/приближать мышкой, как в google maps, требует HTML5-браузер.
|
Особенно замедление.
Aerton : |
Немного лучше, но надо победить крутилки. Интересно, что промахнувшаяся ракета, идущая на второй заход попадает лучше, чем с первого раза.
|
"Крутилки" это что? Они сейчас вертятся "как надо", т.к. пытаются удержать вектор скорости в направлении цели. Чтобы их "победить" надо менять весь алгоритм.
Насчет второго захода - имхо это скорее специфика твоего пилотирования.
Еще хочу сказать, что вообще для стратегии такая боевка это плохо. Тем более что битвой от начала до конца рулит ИИ. В стратегиях важна более-менее предсказуемость результата; зная, что у меня, и что у противника, я должен примерно догадываться как сложится бой. А когда решающее сражение сливаешь из-за хаотического тупняка ИИ - это обычно бесит
|
|
|
Aerton
70 EGP
 Рейтинг канала: 1(8) Репутация: 4 Сообщения: 67 Откуда: Новосибирск Зарегистрирован: 20.08.2004
 |
|
Crimson : |
Ну опечатался, сорри Гы-гы Пишу одно, думаю о другом Улыбка
|
Да не, я про то что всё вроде работает как надо, а получастя плохо.
Crimson : |
"Крутилки" это что? Они сейчас вертятся "как надо", т.к. пытаются удержать вектор скорости в направлении цели. Чтобы их "победить" надо менять весь алгоритм.
|
Ну, там иногда, особенно сразу после старта, ракета делает несколько кувырков. Надо наверное в этот момент переключать на обычный VP.
Crimson : |
Насчет второго захода - имхо это скорее специфика твоего пилотирования.
|
Подозреваю, что когда за штурвал сядет AI, всё может начать выглядеть по-другому. Эх, проблема курицы и яйца.
Crimson : |
Еще хочу сказать, что вообще для стратегии такая боевка это плохо. Тем более что битвой от начала до конца рулит ИИ. В стратегиях важна более-менее предсказуемость результата; зная, что у меня, и что у противника, я должен примерно догадываться как сложится бой. А когда решающее сражение сливаешь из-за хаотического тупняка ИИ - это обычно бесит Улыбка
|
С другой стороны будет такой же тупящий ИИ, так что это уравняет шансы Но вообще да, есть такой риск. Не знаю, будет ли это бесить игроков больше, чем линкор, слитый при атаке на колесницу в первой Civilization. А вообще, стратегическая часть хотя частично уже сделана, наверное быдет отложена в сторону на первых порах. В немалой степени из-за проблем балансирования да и сложность проекта уже вышла из-под контроля
|
|
|
Tybloman
85 EGP
 Рейтинг канала: 2(14) Репутация: 12 Сообщения: 184 Откуда: Санкт Петербург Зарегистрирован: 24.09.2007
 |
|
Эх, попробую чтоль тоже )
значит сделал на флэш,
www.miola3d.ru/tmp/space1.swf
пока КК статичные.
поворот ракеты мгновенный.
самонаведение - ракета смотрит на цель.
Как и ожидалось ракета выходит на орбиту цели. интересная кстате фишка на заметку. К вопросу как принуждать торговцев сбросить скорость
Значит мне видится пока так:
Нужно чтоб не ракета смотрела на цель, а её вектор скорости.
Для этого ии должен поворачивать ракету таким образом, чтобы вектор её скорости стремился смотреть на цель.
как именно, щас буду думать
добавлено спустя 27 минут:
Значит сделал тупо разницу между векторами направление на цель и вектором скорости ракеты. получилось интересно:
http://www.miola3d.ru/tmp/space2.swf
под конец она резко разворачивается на 180 градусов.
т.е. чисто компенсирует вектор скорости от отклонения.
По крайней мере оно уже летит в направлении строго на цель.
пилим дальше )
upd: понЯл. Если этот вектор разницы меньше чем ускорение ракеты, то надо её пропорционально к цели поворачивать (может и не корректно сравнивать скорость с ускорением, но смысл вы поняли)
добавлено спустя 17 минут:
Ну вот третий вариант.
Когда вектор разницы меньше чем ускорение ракеты, то она тупо направляется на цель.
http://www.miola3d.ru/tmp/space3.swf
топорно конечно, но теперь только прилизать, а так вроде работает
Последний раз редактировалось: Tybloman (18:57 31-03-2011), всего редактировалось 3 раз(а) |
|
|
Aerton
70 EGP
 Рейтинг канала: 1(8) Репутация: 4 Сообщения: 67 Откуда: Новосибирск Зарегистрирован: 20.08.2004
 |
|
Tybloman : |
Эх, попробую чтоль тоже )
|
Давай, интересно
А я вот пока поигрался с параметрами, и когда угол скорости сильно отклоняется от направления на цель, ракета просто гасит всю скорость и делает новый заход. Это конечно крайне неоптимально, но хоть поподать стало чаще.
добавлено спустя 6 минут:
Tybloman У тебя похоже какая-то помесь VP с PN? Можешь формулы из кода скопировать? У тебя смотрится хорошо, но интересно посмотреть, как оно будет работать, когда цель летает более интересными траекториями.
Последний раз редактировалось: Aerton (19:05 31-03-2011), всего редактировалось 1 раз |
|
|
Tybloman
85 EGP
 Рейтинг канала: 2(14) Репутация: 12 Сообщения: 184 Откуда: Санкт Петербург Зарегистрирован: 24.09.2007
 |
|
смотри после
////////////////////////
//MISSELS
Cкрытый текст (кликните здесь для просмотра)
package main{
//import flash.display.MovieClip;
import flash.events.*;
import flash.display.*;
import flash.net.*;
import fl.transitions.Tween;
import fl.transitions.easing.*;
import fl.transitions.TweenEvent;
import flash.filters.BlurFilter;
import flash.filters.BitmapFilterQuality;
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.external.ExternalInterface;
import flash.display.SimpleButton;
public class main extends MovieClip{
var MCL_MAIN_TOP:MovieClip;
var MCL_MAIN_BOTTOM:MovieClip;
var KK1:LO_Ship;
var KK2:LO_Ship;
var missels:Array;
var FPS:Number;
/////////////////////////////////////
public function main()
{
stage.addEventListener(Event.RESIZE, FResizeE);
stage.addEventListener(Event.ENTER_FRAME, EFrame);
stage.addEventListener(MouseEvent.MOUSE_MOVE, MMove);
stage.addEventListener(MouseEvent.MOUSE_UP, MUP);
stage.addEventListener(KeyboardEvent.KEY_DOWN, KeyDown);
FPS = 30;
MCL_MAIN_BOTTOM = new MovieClip;
addChild(MCL_MAIN_BOTTOM);
MCL_MAIN_TOP = new MovieClip;
addChild(MCL_MAIN_TOP);
// init game
KK1 = new LO_Ship;
KK1.x = 400;
KK1.y = 400;
MCL_MAIN_TOP.addChild(KK1);
KK2 = new LO_Ship;
KK2.x = Math.random()*800;
KK2.y = Math.random()*600;
KK2.rotation = 90;
MCL_MAIN_TOP.addChild(KK2);
missels = [];
var tM:Object = new Object;
tM.a = 0.2;
tM.Vx = 0;
tM.Vy = -6;
tM.MC = new LO_missle;
tM.MC.x = KK1.x+10;
tM.MC.y = KK1.y;
missels.push(tM);
MCL_MAIN_BOTTOM.addChild(tM.MC);
}
/////////////////////////////////////
function FResizeE(event:Event)
{
FResize()
}
function FResize()
{
};
function EFrame(event:Event)
{
KK2.x += 2;
if(KK2.x>800)
{
KK2.x = Math.random()*800;
KK2.y = Math.random()*600;
missels[0].Vx = 0;
missels[0].Vy = -6;
missels[0].MC.x = KK1.x+10;
missels[0].MC.y = KK1.y;
};
////////////////////////
//MISSELS
//Vector from missel to Target
var toTGT_V:Object = new Object;
toTGT_V.dx = KK2.x - missels[0].MC.x;
toTGT_V.dy = KK2.y - missels[0].MC.y;
toTGT_V.dXYmodul = Math.sqrt(toTGT_V.dx*toTGT_V.dx+toTGT_V.dy*toTGT_V.dy);
toTGT_V.dx = toTGT_V.dx/toTGT_V.dXYmodul;
toTGT_V.dy = toTGT_V.dy/toTGT_V.dXYmodul;
//Vector missel
var KK_V:Object = new Object;
KK_V.dx = missels[0].Vx;
KK_V.dy = missels[0].Vy;
KK_V.dM = Math.sqrt(KK_V.dx*KK_V.dx+KK_V.dy*KK_V.dy);
KK_V.dx = KK_V.dx/KK_V.dM;
KK_V.dy = KK_V.dy/KK_V.dM;
//
//de Vectors
var KK_corrV:Object = new Object;
KK_corrV.dx = toTGT_V.dx - KK_V.dx;
KK_corrV.dy = toTGT_V.dy - KK_V.dy;
KK_corrV.dM = Math.sqrt(KK_corrV.dx*KK_corrV.dx+KK_corrV.dy*KK_corrV.dy);
//trace(KK_corrV.dM+":"+missels[0].a);
if (KK_corrV.dM< missels[0].a){KK_corrV.dx = toTGT_V.dx; KK_corrV.dy = toTGT_V.dy; };
//toTGT_V.angl = Math.atan(toTGT_V.dy/toTGT_V.dx);
toTGT_V.angl = Math.atan(KK_corrV.dy/KK_corrV.dx);
if(KK_corrV.dx>0){toTGT_V.angl += Math.PI;trace(toTGT_V.angl )};
// dV
//rotation
missels[0].MC.rotation = (toTGT_V.angl*180/Math.PI)-90;
var rot:Number = (missels[0].MC.rotation-90)/180*Math.PI;
//move
missels[0].Vx += Math.cos(rot)*missels[0].a;
missels[0].Vy += Math.sin(rot)*missels[0].a;
missels[0].MC.x += missels[0].Vx;//Math.cos(rot)*missels[0].v;
missels[0].MC.y += missels[0].Vy;//Math.sin(rot)*missels[0].v;
};
function MMove(e:MouseEvent):void
{
};
function MUP(e:MouseEvent):void
{
};
function KeyDown(event:KeyboardEvent)
{
trace(event.keyCode);
}
}
}
|
а я щас лучше картинку нарисую
добавлено спустя 16 минут:
ДА!!! Все векторы единичной длинны!!! Картинка будет конечно же другой, но смысл остаётся тот же
вообще надо целиться с упреждением всё таки...
Последний раз редактировалось: Tybloman (20:01 31-03-2011), всего редактировалось 6 раз(а) |
|
|
Tybloman
85 EGP
 Рейтинг канала: 2(14) Репутация: 12 Сообщения: 184 Откуда: Санкт Петербург Зарегистрирован: 24.09.2007
 |
|
Теперь с ограничением поворота ракеты:
http://www.miola3d.ru/tmp/space4.swf
думаю еще добавить упреждение, и вполне себе должно быть.
|
|
|
Crimson
560 EGP
    Рейтинг канала: 4(83) Репутация: 130 Сообщения: 3041
Зарегистрирован: 03.09.2003
 |
|
Tybloman : |
Значит мне видится пока так:
Нужно чтоб не ракета смотрела на цель, а её вектор скорости.
Для этого ии должен поворачивать ракету таким образом, чтобы вектор её скорости стремился смотреть на цель.
|
Это по определению velocity pursuit (т.е. самое первое, что написал Аэртон). Проблема в том, что вектор скорости должен смотреть не на саму цель, а на туда где она окажется. Особенно "в космосе" (в атмосфере еще можно сесть на хвост и догнать, а вот в космосе цель может делать финты ушами пока у ракеты топливо не кончится).
Правда опять-таки, это к вопросу о параллельной разработке ИИ ракеты и "пилота". Т.к. в принципе если пилот не будет особо уклоняться, то и супернавороченый ИИ для ракеты писать как бы излишне.
Или тогда уже сразу пиши ИИ, который будет уклоняться, и тестируй на нем. Откладывать в долгий ящик бесполезно, рано или поздно этим все равно придется заняться (если конечно не забить на сам проект ).
|
|
|
Aerton
70 EGP
 Рейтинг канала: 1(8) Репутация: 4 Сообщения: 67 Откуда: Новосибирск Зарегистрирован: 20.08.2004
 |
|
Tybloman : |
if (KK_corrV.dM< missels[0].a){KK_corrV.dx = toTGT_V.dx; KK_corrV.dy = toTGT_V.dy; };
|
Вот эта вот казалось бы мелочь, на самом деле - самая важная часть, без неё такие же раскрутки, как были у меня.
Из-за этого не получается сделать ракету с постоянной тягой, как я упорно пытался сделать всё время. Но этим можно и пожертвовать.
Нормировать вектора кстати оказалось лишним, - видимо у тебя просто и так значения близки к еденице и разницу не заметно.
в действии
Теперь всё кажется таким элементарным, как можно было столько с этим провозиться...
А упереждение в принципе и не нужно, и так фиг оторвёшся от ракеты - только надеятся, что у неё горючка кончится.
Большое спасибо тебе, Tybloman.
добавлено спустя 6 минут:
Crimson : |
Это по определению velocity pursuit (т.е. самое первое, что написал Аэртон).
|
Угу, только из-за этой "мелочи" у меня шёл расколбас.
В принципе можно тягу не менять, если повернуть ракету на какой-то не полный угол, что я и пытался сделать в своей модификации VP. Но, сделал его константой, вместо того. Теперь я понимаю, надо было взять одну боковую составляющую как acceleration * cos(a), а вторую вычислить из неё и величины ускорения, тогда должно работать и без снижения тяги.
Последний раз редактировалось: Aerton (21:58 31-03-2011), всего редактировалось 2 раз(а) |
|
|
Tybloman
85 EGP
 Рейтинг канала: 2(14) Репутация: 12 Сообщения: 184 Откуда: Санкт Петербург Зарегистрирован: 24.09.2007
 |
|
Crimson : |
Это по определению velocity pursuit (т.е. самое первое, что написал Аэртон)
|
Ага, спасибо. Я не считал себя таким умным просто не стал вникать в слова такие страшные )
Aerton : |
Нормировать вектора кстати оказалось лишним, - видимо у тебя просто и так значения близки к еденице и разницу не заметно.
|
Я специально убирал нормирование. Получается, что ракета всегда смотрит на цель, и уходит на круговую орбиту...
Aerton : |
Tybloman :
if (KK_corrV.dM< missels[0].a){KK_corrV.dx = toTGT_V.dx; KK_corrV.dy = toTGT_V.dy; };
Вот эта вот казалось бы мелочь, на самом деле - самая важная часть, без неё такие же раскрутки, как были у меня.
|
Это резко смотреть на цель. Я теперь подправил на плавно:
if (KK_corrV.dM< missels[0].a)
{
var K:Number = 1-(missels[0].a - KK_corrV.dM)/missels[0].a;
//trace(K);
KK_corrV.dx = toTGT_V.dx + (KK_corrV.dx - toTGT_V.dx)*K;
KK_corrV.dy = toTGT_V.dy + (KK_corrV.dy - toTGT_V.dy)*K;
};
а вообще на всякий случай вот что получилось в конце
Cкрытый текст (кликните здесь для просмотра)
package main{
//import flash.display.MovieClip;
import flash.events.*;
import flash.display.*;
import flash.net.*;
import fl.transitions.Tween;
import fl.transitions.easing.*;
import fl.transitions.TweenEvent;
import flash.filters.BlurFilter;
import flash.filters.BitmapFilterQuality;
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.external.ExternalInterface;
import flash.display.SimpleButton;
public class main extends MovieClip{
var MCL_MAIN_TOP:MovieClip;
var MCL_MAIN_BOTTOM:MovieClip;
var KK1:LO_Ship;
var KK2:LO_Ship;
var missels:Array;
var FPS:Number;
/////////////////////////////////////
public function main()
{
stage.addEventListener(Event.RESIZE, FResizeE);
stage.addEventListener(Event.ENTER_FRAME, EFrame);
stage.addEventListener(MouseEvent.MOUSE_MOVE, MMove);
stage.addEventListener(MouseEvent.MOUSE_UP, MUP);
stage.addEventListener(KeyboardEvent.KEY_DOWN, KeyDown);
FPS = 30;
MCL_MAIN_BOTTOM = new MovieClip;
addChild(MCL_MAIN_BOTTOM);
MCL_MAIN_TOP = new MovieClip;
addChild(MCL_MAIN_TOP);
// init game
KK1 = new LO_Ship;
KK1.x = 400;
KK1.y = 500;
MCL_MAIN_TOP.addChild(KK1);
KK2 = new LO_Ship;
KK2.x = Math.random()*800;
KK2.y = Math.random()*600;
KK2.rotation = 90;
MCL_MAIN_TOP.addChild(KK2);
missels = [];
var tM:Object = new Object;
tM.a = 0.3;
tM.Vx = 0;
tM.Vy = -3;
tM.MC = new LO_missle;
tM.MC.x = KK1.x+10;
tM.MC.y = KK1.y;
missels.push(tM);
MCL_MAIN_BOTTOM.addChild(tM.MC);
}
/////////////////////////////////////
function FResizeE(event:Event)
{
FResize()
}
function FResize()
{
};
function EFrame(event:Event)
{
KK2.x += 2;
if(KK2.x>800)
{
KK2.x = Math.random()*800;
KK2.y = Math.random()*400;
//missels[0].Vx = 0;
//missels[0].Vy = -6;
//missels[0].MC.x = KK1.x+10;
//missels[0].MC.y = KK1.y;
};
if(missels[0].MC.x > 800 || missels[0].MC.x <0 || missels[0].MC.y > 600||missels[0].MC.y < 0)
{
/*missels[0].Vx = 0;
missels[0].Vy = -6;
missels[0].MC.x = KK1.x+10;
missels[0].MC.y = KK1.y;
missels[0].MC.rotation = 0;*/
};
var tdx:Number = KK2.x - missels[0].MC.x;
var tdy:Number = KK2.y - missels[0].MC.y;
var tdM:Number = Math.sqrt(tdx*tdx+tdy+tdy);
if(tdM < 20)
{
KK2.x = Math.random()*800;
KK2.y = Math.random()*600;
missels[0].Vx = 0;
missels[0].Vy = -6;
missels[0].MC.x = KK1.x+10;
missels[0].MC.y = KK1.y;
missels[0].MC.rotation = 0;
};
////////////////////////
//MISSELS
//uprezhdenie
//Vector from KK to Target
var toTGT_V:Object = new Object;
toTGT_V.dx = KK2.x - missels[0].MC.x;
toTGT_V.dy = KK2.y - missels[0].MC.y;
toTGT_V.dXYmodul = Math.sqrt(toTGT_V.dx*toTGT_V.dx+toTGT_V.dy*toTGT_V.dy);
toTGT_V.dx = toTGT_V.dx/toTGT_V.dXYmodul;
toTGT_V.dy = toTGT_V.dy/toTGT_V.dXYmodul;
//Vector KK
var KK_V:Object = new Object;
KK_V.dx = missels[0].Vx;
KK_V.dy = missels[0].Vy;
KK_V.dM = Math.sqrt(KK_V.dx*KK_V.dx+KK_V.dy*KK_V.dy);
KK_V.dx = KK_V.dx/KK_V.dM;
KK_V.dy = KK_V.dy/KK_V.dM;
//
//de Vectors
var KK_corrV:Object = new Object;
KK_corrV.dx = toTGT_V.dx - KK_V.dx;
KK_corrV.dy = toTGT_V.dy - KK_V.dy;
KK_corrV.dM = Math.sqrt(KK_corrV.dx*KK_corrV.dx+KK_corrV.dy*KK_corrV.dy);
if (KK_corrV.dM< missels[0].a)
{
var K:Number = 1-(missels[0].a - KK_corrV.dM)/missels[0].a;
//trace(K);
KK_corrV.dx = toTGT_V.dx + (KK_corrV.dx - toTGT_V.dx)*K;
KK_corrV.dy = toTGT_V.dy + (KK_corrV.dy - toTGT_V.dy)*K;
};
//trace(KK_corrV.dM+":"+missels[0].a);
//toTGT_V.angl = Math.atan(toTGT_V.dy/toTGT_V.dx);
toTGT_V.angl = Math.atan(KK_corrV.dy/KK_corrV.dx);
if(KK_corrV.dx>0){toTGT_V.angl += Math.PI};
// dV
//rotation
var rotationOLD:Number = missels[0].MC.rotation;
var rotationNEW:Number = (toTGT_V.angl*180/Math.PI)-90;
var rotationD:Number = rotationNEW - rotationOLD;
if(rotationD> 180){rotationNEW-=360; rotationD = rotationNEW - rotationOLD};
if(rotationD<-180){rotationNEW+=360; rotationD = rotationNEW - rotationOLD};
if(rotationD>10){rotationD = 10;}
if(rotationD<-10){rotationD = -10;}
missels[0].MC.fire.rotation = -rotationD*3;
missels[0].MC.rotation += rotationD;
var rot:Number = (missels[0].MC.rotation-90)/180*Math.PI;
//move
missels[0].Vx += Math.cos(rot)*missels[0].a;
missels[0].Vy += Math.sin(rot)*missels[0].a;
missels[0].MC.x += missels[0].Vx;//Math.cos(rot)*missels[0].v;
missels[0].MC.y += missels[0].Vy;//Math.sin(rot)*missels[0].v;
};
function MMove(e:MouseEvent):void
{
};
function MUP(e:MouseEvent):void
{
};
function KeyDown(event:KeyboardEvent)
{
trace(event.keyCode);
}
}
}
|
добавлено спустя 17 минут:
Aerton, только не могу понять.
У тебя вроде один кораблик стоит?
А ракеты вокруг него круги выписывают...
у меня по статичным целям сразу в лоб практически:
http://www.miola3d.ru/tmp/space5stoped.swf
У тя наверно похитрее алгоритм. они и разворачиваются до цели еще для торможения...
А второй метод, который не velocity pursuit
как он называется и что это такое? только как нить попроще?
Последний раз редактировалось: Tybloman (22:29 31-03-2011), всего редактировалось 1 раз |
|
|
Aerton
70 EGP
 Рейтинг канала: 1(8) Репутация: 4 Сообщения: 67 Откуда: Новосибирск Зарегистрирован: 20.08.2004
 |
|
Tybloman : |
Я специально убирал нормирование. Получается, что ракета всегда смотрит на цель, и уходит на круговую орбиту...
|
Странно - так обычно бывает, если нос ракеты всё время повёрнут строго на цель и дан полный вперёд.
Tybloman : |
Это резко смотреть на цель. Я теперь подправил на плавно:
|
Это не важно, - у меня в принципе нету резкого поворота.
Просто из головы как-то выпало, что вычисления будут дискретными и эта погрешность не уйдёт в ноль, как при расчёте на бумаге. А на компьютере она осцилирует вокруг нуля, пока цель не переместится достаточно сильно, чтобы изменившиеся условия нарушили цикл.
И в том или ином виде эта ошибка у меня присутствовала в каждой итерации.
добавлено спустя 4 минуты:
Tybloman : |
У тебя вроде один кораблик стоит?
А ракеты вокруг него круги выписывают...
у меня по статичным целям сразу в лоб практически:
|
У меня выше скорость и ниже манёвренность, вот их и заносит сильнее.
Tybloman : |
У тя наверно похитрее алгоритм. они и разворачиваются до цели еще для торможения...
|
Последняя запись - это по твоему посту сделано
Cкрытый текст (кликните здесь для просмотра)
Код: |
accel2 = f / self.actor.body.mass
accel2 *= accel2
while self.target.hp > 0:
x, y = self.actor.body.position
xT, yT = self.target.actor.body.position
xT -= x
yT -= y
vx, vy = self.actor.body.velocity
vTx, vTy = self.target.actor.body.velocity
vx -= vTx
vy -= vTy
xC = xT - vx
yC = yT - vy
a = math.atan2(-xC, yC)
C = xC * xC + yC * yC
if C < accel2:
C = C ** 0.5
a = self.actor.body.angle_to(*self.target.actor.body.position)
self.thrust (C * self.actor.body.mass)
else:
self.thrust (f)
self.turn (calc_torque(self, a))
core.sleep () |
|
Просто у нас значения параметров достаточно сильно отличается.
добавлено спустя 8 минут:
Tybloman : |
как он называется и что это такое? только как нить попроще? Гы-гы
|
Proprtional navigation? Я его понимаю на пальцах, и похоже, где-то ошибаюсь в расчётах, так что пожалуй лучше не буду давать свою неверную интерпретацию
Но суть в том, что мы вычисляем угловую скорость цели относительно ракеты, и поворачиваем ракету в ту же сторону, но в N раз быстрее.
Последний раз редактировалось: Aerton (22:58 31-03-2011), всего редактировалось 3 раз(а) |
|
|
Варсик
545 EGP
    Рейтинг канала: 4(81) Репутация: 117 Сообщения: 4041 Откуда: Москва Зарегистрирован: 22.12.2002
 |
|
Ну и теперь пора улучшать то что получилось...
1) Делаем отстрел ракет (допустим вперед) с повернутым вперед соплом. Что-бы ракета быстрее останавливалась и ориентировалась. Это если цель зело не по центру корабля.
2) Возможно стоит рассмотреть случай когда тяга уменьшается при развороте - это позволит сэкономить топливо и повысит дальность полета ракеты.
Эти фишки можно продавать как улучшения для ракет...
_________________ WARNING: By reading this post you accept that this post is genius. |
|
|
Crimson
560 EGP
    Рейтинг канала: 4(83) Репутация: 130 Сообщения: 3041
Зарегистрирован: 03.09.2003
 |
|
Warstone : |
Делаем отстрел ракет (допустим вперед) с повернутым вперед соплом. Что-бы ракета быстрее останавливалась и ориентировалась. Это если цель зело не по центру корабля.
|
Ага, а еще лучше их вообще сразу с кормы запускать
|
|
|
Tybloman
85 EGP
 Рейтинг канала: 2(14) Репутация: 12 Сообщения: 184 Откуда: Санкт Петербург Зарегистрирован: 24.09.2007
 |
|
Значит думал над тем, как на перехват идти одной кнопкой, и чтоб всё чётко получилось. Потом понял, что это ж для ракеты тоже годится
Варианты:
1)
Ракета и цель неподвижны друг относительно друга
решение - направить ускорение в сторону цели.
2)
Цель движется относительно ракеты, но без ускорения
решение - направить ускорение на погашение относительной скорости,
потом смотри пункт 1
3)
Цель еще и имеет ускорение
решение - Ускорение разбить на два вектора.
первый равен ускорению цели,
с остатком смотри пункт 2
И оно работает! Тупит иногда конечно )
единственное, это дёрганье большое при относительно низких скоростях.
w,s,a,d - перемещаться по карте,
q,e - масштаб карты
http://www.miola3d.ru/tmp/spaceNA1.html
по мому понял чего тупит, в пункте 3, надо не такое же ускорение,
а гасить его отклонение от себя... как то так )))
да! еще есть пункт 4)
там нужно раскрыть тему скорости изменения ускорения, и компенсировать его
script (кликните здесь для просмотра)
//delta A
var dA:Object = new Object;
dA.aTGTx = KKs[1].Va * Math.cos(KKs[1].angl);
dA.aTGTy = KKs[1].Va * Math.sin(KKs[1].angl);
dA.aOWNx = KKs[i].Va * Math.cos(KKs[i].angl);
dA.aOWNy = KKs[i].Va * Math.sin(KKs[i].angl);
dA.x = dA.aOWNx - dA.aTGTx;
dA.y = dA.aOWNy - dA.aTGTy;
dA.m = Math.sqrt(dA.x*dA.x+dA.y*dA.y);
dA.dm = (KKs[i].Va - KKs[1].Va);
//delta speed
var dV:Object = new Object;
dV.x = KKs[i].Vv.x - KKs[1].Vv.x;
dV.y = KKs[i].Vv.y - KKs[1].Vv.y;
dV.m = Math.sqrt(dV.x*dV.x+dV.y*dV.y);
//vector to TGT
var toTGT:Object = new Object;
toTGT.x = KKs[1].x - KKs[i].x;
toTGT.y = KKs[1].y - KKs[i].y;
toTGT.m = Math.sqrt(toTGT.x*toTGT.x+toTGT.y*toTGT.y);
toTGT.nx = toTGT.x/toTGT.m;
toTGT.ny = toTGT.y/toTGT.m;
//delta speed correction
var dVc:Object = new Object;
trace(toTGT.nx * dV.m +"-"+dV.x+"=" + (toTGT.nx * dV.m - dV.x));
dVc.x = -toTGT.nx * dV.m + dV.x;
dVc.y = -toTGT.ny * dV.m + dV.y;
dVc.m = Math.sqrt(dVc.x*dVc.x+dVc.y*dVc.y);
//over "delta speed correction"
var dVO:Object = new Object;
dVO.x = 0; dVO.y = 0;
if(dVc.m < dA.dm)
{
dVO.m = dA.dm - dVc.m;
dVO.x = -dVO.m * toTGT.x;
dVO.y = -dVO.m * toTGT.y;
}
//angle
var angle:Object = new Object;
angle.x = dVc.x + dVO.x - dA.aTGTx;
angle.y = dVc.y + dVO.y - dA.aTGTy;
angle.m = Math.sqrt(angle.x*angle.x+angle.y*angle.y);
angle.nx = angle.x/angle.m;
angle.ny = angle.y/angle.m;
angle.angle = Math.atan(angle.ny/angle.nx);
if(angle.nx>0){angle.angle += Math.PI};
//rotation
var dAngle = angle.angle - KKs[i].angl;
var speedRot = 4 * 2*Math.PI/180;
if(dAngle > Math.PI){angle.angle-=2*Math.PI; dAngle = angle.angle - KKs[i].angl};
if(dAngle <-Math.PI){angle.angle+=2*Math.PI; dAngle = angle.angle - KKs[i].angl};
if(dAngle > speedRot){dAngle = speedRot;}
if(dAngle <-speedRot){dAngle = -speedRot;}
KKs[i].angl += dAngle;
//KKs[i].angl = angle.angle;
while(KKs[i].angl<0){KKs[i].angl+=2*Math.PI;}
while(KKs[i].angl>2*Math.PI){KKs[i].angl-=2*Math.PI;}
|
, где KKs[1] это цель, а KKs[i] - ракета
|
|
|
Aerton
70 EGP
 Рейтинг канала: 1(8) Репутация: 4 Сообщения: 67 Откуда: Новосибирск Зарегистрирован: 20.08.2004
 |
|
Честно говоря, из описания мало что понял. Мне кажется, куда проще оставить прежний алгоритм, только в качестве координат цели использовать не положение корабля, а сделать отдельный блок - предсказатель траектории мишени, который и будет выдавать предполагаемые координаты на момент столкновения.
|
|
|
Tybloman
85 EGP
 Рейтинг канала: 2(14) Репутация: 12 Сообщения: 184 Откуда: Санкт Петербург Зарегистрирован: 24.09.2007
 |
|
Да в принципе наверно почти тоже самое что и тот вариант.
Я тут понял ошибку: Я скорость направлял на абсолютные координаты цели.
А нужно было работать с относительной скоростью.
т.е. из своей скорости вычесть скорость цели. Полученный вектор уже направлять в сторону цели.
где Цель летит со скоростью V1 относительно зелёной точки.
Как видно из рисунка, ракета сама полетит в точку встречи.
Последний раз редактировалось: Tybloman (09:23 04-04-2011), всего редактировалось 4 раз(а) |
|
|
|
|
|
Канал Игры Мечты: «Самонаводящаяся ракета в космосе» |
|
К списку каналов | Наверх страницы |
Цитата не в тему: Мы сами дяди взрослые и крышу снесем кому надо без чьей-то помощи! (похвастался Strange®)
|
» Самонаводящаяся ракета в космосе | страница 3 |
|