Пули? Да, да. Тема-то заезжена, но не все знают как их правильно реализовывать. При стрельбе медленными снарядами( ракетами
и т.п. ) обычная блицевская коллизия работает прекрасно. С повышением скоростей объект часто не успевает столкнуться из-за
больших временных шагов при обработке столкновений. Как же этого избежать? Очень просто. Использовать комбинацию луч +
ентити.
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
зы. Давно на блице не писал, поэтому могут быть ошибки в синтаксисе
Я сказал всё.