Тема: Пули.
Показать сообщение отдельно
Старый 18.03.2012, 23:46   #1
mr.DIMAS
Дэвелопер
 
Аватар для mr.DIMAS
 
Регистрация: 26.12.2006
Адрес: Санкт-Петербург
Сообщений: 1,572
Написано 547 полезных сообщений
(для 1,540 пользователей)
Пули.

Пули? Да, да. Тема-то заезжена, но не все знают как их правильно реализовывать. При стрельбе медленными снарядами( ракетами

и т.п. ) обычная блицевская коллизия работает прекрасно. С повышением скоростей объект часто не успевает столкнуться из-за

больших временных шагов при обработке столкновений. Как же этого избежать? Очень просто. Использовать комбинацию луч +

ентити.

Type Bullet
 Field entity
 Field target
 Field lifeTime
 Field speed
End Type
Это наша структура пули. Поле target предназначено для пивота с помощью которого определяются конечные координаты луча.

Инициализация происходит так.

Function CreateBullet( from% )
 bul.Bullet = New Bullet
 bul\entity = CreateSphere()
 bul\target = CreatePivot( bul\entity )
 bbPositionEntity( bul\target, 0, 0, 1000 ) ; отодвигаем "цель" подальше

 bbPositionEntity( bul\entity, EntityX( from, 1 ), EntityY( from, 1 ), EntityZ( from, 1 )
 bbRotateEntity( bul\entity, EntityPitch( from, 1 ), EntityYaw( from, 1 ), EntityRoll( from, 1)

 lifeTime = 0
 speed = 2
End Function
from - тот объект из которого пускается пуля - например моделька оружия
Теперь самая главная часть
Function UpdateBullets()
 For bul.Bullet = Each Bullet

  

  sx# = bbEntityX( bul\entity, 1 )
  sy# = bbEntityY( bul\entity, 1 )
  sz# = bbEntityZ( bul\entity, 1 )

  ex# = bbEntityX( bul\target, 1 )
  ey# = bbEntityY( bul\target, 1 )
  ez# = bbEntityZ( bul\target, 1 )

  MoveEntity( bul\entity, 0, 0, speed )
  dx# = sx - ex
  dy# = sy - ey
  dz# = sz - ez

  ent = LinePick( sx, sy, sz, dx, dy, dz, 1000 )
  if ent <> 0
  px# = PickedX()
  py# = PickedY()
  pz# = PickedZ()

  dx# = sx - px
  dy# = sy - py
  dz# = sz - pz

  dist2# = dx * dx + dy * dy + dz * dz
  
  if dist2 < speed * speed ; Попали
    FreeEntity bul\entity
    delete bul
  end if
 end if
 Next
End function
Как это работает? Пуля двигается как обычно - MoveEntity. В каждую итерацию цикла происходит проверка пересечения луча( пущенного из центра пули до цели ) с объектами сцены. Если пересечение есть, и расстояние от точки пересечения до центра пули меньше её скорости, то пуля попала в цель.

Почему условием попадания является "расстояние меньше скорости". Чтобы "столкновение" пули с объектом было устойчивым даже при маленьких дистанциях до цели. Пример: стрельба в упор из пистолета

Все объекты сцены должны быть "пикабельны" - EntityPickMode entity, 2

зы. Давно на блице не писал, поэтому могут быть ошибки в синтаксисе

Я сказал всё.
__________________

(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо mr.DIMAS за это полезное сообщение:
RlexGm (22.06.2012), St_AnGer (20.03.2012)