forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   3D-программирование (http://forum.boolean.name/forumdisplay.php?f=12)
-   -   Метод попадания пуль (http://forum.boolean.name/showthread.php?t=14028)

Halk-DS 10.01.2011 05:16

Метод попадания пуль
 
Главний вопрос, кто может поделится своим опытом и рассказать о самом приемлимом методе, по какому вычисляется попала ли пуля в нужную нам цель?

И одновременно выставляю на критику свою мыслю, которая может пригодится при особых случаях, когда скорость пули больше толщины игрока...
Бегают игроки, они все маленькие размером, и по сравнению со скоростю пуль, метод колизии пули с игроком в некоторых случаях просто безнадежен ибо пуля просто может протлитеть сквозь персонажа и даже его незаметить. Будит ли глючным способом решить ету проблему так:

В каждую пулю вставляем припаренченую к ним камеру
Код:

Local TempPivot=CreatePivot()

If EntityDistance(Пуля,Игрок)<5 -Ето условие только для того чтоб лишний раз не юзать CameraPick(), и значение может быть не 5 а любое зависящее примерно от размера игрока, чтоб его пуля случайно не пролетела.
Hit=CameraPick(Камера та что в пуле, центр екрана)-Переверяем есть ли перед нами игрок?
If Hit<>0 PositionEntity TempPivot,PickedX#(),PickedY#(),PickedZ#(),1-Если он есть, ставим в точку попадания пивот, для вычислений.
If EntityDistance(TempPivot,Пуля)<Cкорость пули Then Пуля попала в цель  -Если расстояние до игрока достаточное, убираем игроку хелсы.
EndIf
EndIf


FreeEntity TempPivot

Будет ли ето слишком тормозить систему, если у меня способных стрелять будет максимум 4 игрока?

п.с. Надеюсь я пояснил доступно, если кто нипонял могу нарисовать...

HolyDel 10.01.2011 06:04

Ответ: Метод попадания пуль
 
В WarTech был такой метод. у снаряда есть текущая позиция и позиция на прошлом кадре. Получается отрезок, который прошел снаряд, далее находится пересечение етого отрезка и bounding сферы противника. если пересечение есть - значит попали.

Venom2 10.01.2011 06:49

Ответ: Метод попадания пуль
 
Цитата:

Сообщение от Halk-DS (Сообщение 175061)
Главний вопрос, кто может поделится своим опытом и рассказать о самом приемлимом методе, по какому вычисляется попала ли пуля в нужную нам цель?

CameraPick для первого лица, LinePick для других. Если нужна баллистика, то обычная проверка на столкновение - EntityCollided

Цитата:

Сообщение от Halk-DS (Сообщение 175061)
метод колизии пули с игроком в некоторых случаях просто безнадежен ибо пуля просто может протлитеть сквозь персонажа и даже его незаметить.

Нет, коллизия всегда сработает независимо от размера и скорости пули, там уже применяется метод описаный HolyDel выше.
Для подтверждения:
Код:

Graphics3D(800, 600, 32, 2)
SetBuffer(BackBuffer())

; игрок [0.5, 1.85, 0.5] метра
Local Player% = CreateCube()
ScaleEntity(Player, 0.5, 1.85, 0.5)
EntityType(Player, 1)

; пуля 2 см радиус, отдалена от игрока на 10 метров
Local Bullet% = CreateSphere(3)
ScaleEntity(Bullet, 0.002, 0.002, 0.002)
PositionEntity(Bullet, -10.0, 0.0, 0.0)
EntityRadius(Bullet, 0.002, 0.002)
EntityType(Bullet, 2)

Local Camera% = CreateCamera()
PositionEntity(Camera, 0.0, 0.0, -10.0)

Collisions(2, 1, 2, 1)

Repeat
       
        If EntityCollided(Bullet, 1) Then
                EntityColor(Player, 255, 0, 0)
        Else
                ; скорость движения на игрока 1000 м\с (60 - кадров в сек)
                TranslateEntity(Bullet, 1000.0 / 60, 0, 0)
        End If
       
        UpdateWorld()
        RenderWorld()
        Flip()
Until KeyDown(1)
End


Halk-DS 10.01.2011 07:18

Ответ: Метод попадания пуль
 
Спасибо за ответы, в моем случае колизий в игре небудет вообще. У меня массив с клетками проходимости.
п.с. Думаю буду юзать LinePick

Reizel 10.01.2011 13:15

Ответ: Метод попадания пуль
 
Вложений: 1
Товарищи! Что ж вы!
Просто помним координаты в предыдущем кадре, и с текущем.
По ним строим уравнение прямой:
Ax+By+Cz+D=0 (в Википедии можно найти уравнения для нахождения коэффициентов).
Потом подставляем координаты игрока в соответствующие места:

Dist#=A*EntityX(E)+B*ENtityy(E)+C*EntityZ(E)+D

Теперь мы имеем расстояние от игрока до прямой, осталось вычислить, принадлежит ли прозиция игрока к отрезку. Как сделать пока не думал, но знаю что несложно

Randomize 10.01.2011 15:39

Ответ: Метод попадания пуль
 
http://mathworld.wolfram.com/Circle-...ersection.html
http://local.wasp.uwa.edu.au/~pbourk...ry/sphereline/
И реализация на c++
PHP код:

bool IntersectCircleLine(const Vec2&center,float radius,const Vec2&p1,const Vec2&p2)
{
  
float x01=p1.x-center.x;
  
float y01=p1.y-center.y;
  
float x02=p2.x-center.x;
  
float y02=p2.y-center.y;

  
float dx=x02-x01;
  
float dy=y02-y01;

  
float a=dx*dx+dy*dy;
  
float b=2.0f*(x01*dx+y01*dy);
  
float c=x01*x01+y01*y01-radius*radius;

  if(-
b<0)return (c<0);
  if(-
b<(2.0f*a))return (4.0f*a*c-b*b<0);
  return (
a+b+c<0);


Перевести думаю не трудно.

Upd. Хмм... А у меня тут оказывается в закромах лежит такой алгоритм:
PHP код:

Function LineToCirclelx1#, ly1#, lx2#, ly2#, cx#, cy#, r#)

dx# = lx2 - lx1
dy# = ly2 - ly1
ld# = Sqr((dx*dx) + (dy*dy))
lux# = dx / ld
luy# = dy / ld
lnx# = luy
lny# = -lux
dx1# = cx - (lx1 - lux*r)
dy1# = cy - (ly1 - luy*r)
d# = Sqr((dx1*dx1) + (dy1*dy1))
dx1 dx1 d
dy1 
dy1d
dx2
# = cx - (lx2 + lux * r)
dy2# = cy - (ly2 + luy*r)
Sqr((dx2*dx2) + (dy2*dy2))
dx2 dx2  d
dy2 
dy2 d
dot1
# = (dx1 * lux) + (dy1 * luy)
dot2# = (dx2 * lux) + (dy2 * luy)
px#=lx1-cx
py#=ly1-cy
distsq# = Abs((dx * py - px * dy)  / ld )

;Следуещее можно разкоментарить и выводить точку пересечения в глобалы
;LineColX# = cx - lnx * sqr(distsq) 
;LineColY# = cy - lny * sqr(distsq)


Return (( dot1>=And dot2<=0) Or (dot1<=And dot2>=0)) And (distsq <= r)


End Function 

Грубо перевёл с блицмакса, но оно работает.

Venom2 11.01.2011 02:33

Ответ: Метод попадания пуль
 
Павел
Randomize
LinePick\EntityPick делает практически тоже самое, только еще использует Space Partition алгоритм (незнаю какой именно) вместо перебора всех юнитов, который будет в вашем случае. Ваш К.О. :)
ЗЫ
3\5 квадратных корней для Ray-Sphere intersection (да еще вдобавок только 2д) это сильно, да :))

EvilChaotic 11.01.2011 02:42

Ответ: Метод попадания пуль
 
Цитата:

Сообщение от Venom2 (Сообщение 175198)
Павел
Randomize
LinePick\EntityPick делает практически тоже самое, только еще использует Space Partition алгоритм (незнаю какой именно) вместо перебора всех юнитов, который будет в вашем случае. Ваш К.О. :)

Перебрать можно не все юниты, это зависит от того, как реализована эта система. Я бы предложил секторное разделение карты, получать для пули список объектов в определенной области и их перебрать. На карте может быть до сотни танков или чего там у вас, а в области например всего 5. И ты не забывай, что Pick не работает без PickMode на ентити, которым ты нагнешь свой двиг. Легче взять два отрезка, построить вектор и проверить на пересечение... Но это по сути тот же EntityDistance ..с еще большем вычислениями..

impersonalis 11.01.2011 02:47

Ответ: Метод попадания пуль
 
Ээээ EvilChaotic в ТЗ не было пункта " у нас уже есть супер-двиг с хитрыми оптимизациями и разибенеиями на группы по произвольному критерию за 0msec".
Уводишь несолкько задчау, имхо.
С точки зрения вопроса глобальной оптимизации - прав, но автор спрашивает не про это (возможно у него это и так реализовано), осталось дело за малым (разработка сверху-вниз).
Решение Venom2 подкупает ещё и тем, что даже EntityDistance пашет быстрее чем ручная реализация Т.Пифагора: втроенные методы предпочтительнее, хотя бы из-за уровня удаления от ядра.
Пост Randomize обязателен к изучению:
1) понимание механизма
2) подобные алгоритмы имеют множесто применений (маст рид!)

Venom2 11.01.2011 03:05

Ответ: Метод попадания пуль
 
Цитата:

Сообщение от EvilChaotic (Сообщение 175199)
Перебрать можно не все юниты, это зависит от того, как реализована эта система. Я бы предложил секторное разделение карты, получать для пули список объектов в определенной области и их перебрать. На карте может быть до сотни танков или чего там у вас, а в области например всего 5.

Да-да, ты вообще читал первый пост? Автор предложил камеры к пуле крепить (!) для определения попаданий, а ты ему про какое-то там хитрое деление карты :D
Цитата:

Сообщение от EvilChaotic (Сообщение 175199)
И ты не забывай, что Pick не работает без PickMode на ентити, которым ты нагнешь свой двиг.

С чего вдруг? Режим 1 в PickMode - проверка только по описывающей сфере, а это и есть ваш велосипед, только не на убогом блиц-бейсике, а встроеный в движок с соответствующими оптимизациями.
ЗЫ
Про лагоритм пересечения советую глянуть сюда , не стоит для игр применять математику "влоб", в большинстве случаев оригинальные алгоритмы слишком тяжелы для этого, поэтому стоит потратить немного времени на поиски соответствующих адаптаций ;)

moka 11.01.2011 04:20

Ответ: Метод попадания пуль
 
Народ, без секторных реализаций (у автора массив, он может выступать в роли хотя бы стандартного сравнения боунти бокса отрезка и объектов попадания, и то, это уже накладно.
При пулемёте, со скоростью стрельбы в 15 патронов в секунду. Если вокруг 10 объектов. Ладно один стреляет, а если двое - то уже "уопа".
Это получается на каждую пулю, будет просчёт, при этом жизнь пули примерно 50мс (например), то количество просчётов просто нарастает с каждым выстрелом.
При фиксированном цикле в 19мс (60ups), будет 60 обновлений, при этом жизнь пули примерно 3 цикла. Получается в итоге (15*1)*10*3=450, вычислений в секунду, от одного пулемётчика. А что если их 32, и они все стреляют в один момент? (15*32)*32*3=46080 вычислений в секунду! Этож полнейшая уопа.
Поэтому обязательные оптимизации в первую очередь разбиение глобального списка по секторам. (это не только к пулям относится).
Далее другие оптимизации, сокращения списков, для индор, это порталы.
Также для больших пространств, и большого количества объектов, нужно кластеровать сектора..

Короче говоря, пока у вас бегает кое как 10 мобов, и стрельба медленная, но как только что-то увеличивается, по геометрической прогрессии вырастает нагрузка вычислений.
Логика никогда не должна утеснять рендер, даже на слабых параметрах компьютера (это же не симулятор чястиц галактик с их звёздами и планетами, это простая игра).
Тем более, где сейчас встретишь игру, в которой требования к железу, будут выше на процессор, или ваш процессор вас "подведёт?" (в разумных ситуациях), нету такого.

Оптимизации нужны, но согласен, автор ещё не совсем готов к ним..

HolyDel 11.01.2011 05:56

Ответ: Метод попадания пуль
 
Цитата:

Сообщение от impersonalis (Сообщение 175200)
Решение Venom2 подкупает ещё и тем, что даже EntityDistance пашет быстрее чем ручная реализация Т.Пифагора: втроенные методы предпочтительнее, хотя бы из-за уровня удаления от ядра.

золотые слова!

Halk-DS 11.01.2011 22:32

Ответ: Метод попадания пуль
 
Цитата:

Сообщение от Venom2 (Сообщение 175201)
Да-да, ты вообще читал первый пост? Автор предложил камеры к пуле крепить (!) для определения попаданий.

Ну если ты внимательно прочитал первый пост то я нехотел вставлять камеры в пули, я выставил етот вариант на вашу критику. Я догадывался о глючности моего предположения...
А создал я етот топик, не потому что собираюсь камеры в пули пхать:
Цитата:

Главний вопрос, кто может поделится своим опытом и рассказать о самом приемлимом методе, по какому вычисляется попала ли пуля в нужную нам цель?
И еще добавлю, как только мне написали пост с командами ЕнтитиПик и ЛайнПик, начал бится головой об клавиатуру, ибо реально вылетели ети команды из головы, а я знал об тоб что они в моем случае уж куда лучше камер.(перерыв в программировании два года, поетому приходится счяс многое вспоминать)

Цитата:

Сообщение от Venom2 (Сообщение 175201)
а ты ему про какое-то там хитрое деление карты :D

Ну я конешно согласен что до некоторых людей в плане програмирования мне еще очень далеко, но если судить по твоей логике, вообще зачем я задал вопрос, если предполагать заранее, что я нифига непойму?(уж извини с твоего топика мне так показалось)

Ну и относительно темы пару слов :-D
Насчет количества стреляемых я уже говорил:
Цитата:

у меня способных стрелять будет максимум 4 игрока
Если я дорасту хотя б до бета версии, буду думать о "Ботах". Потому что игра ета на 4-х за одной клавой. В любом случае их много не будет.

А насчет деления карты, я например так понимаю.
Есть карта 300х300(например). По ней ездят толпами танки. Нам нужно поделить всю карту на кубики типа 10х10(например) и призначить им свой ID. Выходит 30 кубиков с ID от 1 до 30. Мы берем всем танкам и пулям назначаем тот ID в кубике которого они находятся.
И так у нас получается группа пуль и танков с одинаковым ID какие мы и проверяем между собой на попадание не трогае все остальные танки с другими ID.
Надеюсь я правильно понимаю?:4to:

impersonalis 12.01.2011 02:11

Ответ: Метод попадания пуль
 
Цитата:

Потому что игра ета на 4-х за одной клавой. В любом случае их много не будет.
ого. Ты в курсе, что в сумме (на "буквенную" и "numlock" клавы) не более 6 клавиш для обычной клавы одновременно?
http://www.forum.boolean.name/showthread.php?t=13361

Reizel 12.01.2011 02:12

Ответ: Метод попадания пуль
 
в Cortex Command играл? Мы в четвером резались за одной клавой...значит можно :)


Часовой пояс GMT +4, время: 10:20.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot