Итак, у нас есть спрайты. Они рисуются, двигаются, но не взаимодействуют друг с
другом. И вот для того, что бы мячики отскакивали, пули попадали во врага, а
герои не проваливались сквозь пол, в DelphiX есть замечательная вещь как
проверка на столкновение, которая в большинстве случаев поможет избежать
написание собственного движка.
Есть два метода определение столкновений.
- Проверка столкновения рамок: Простой тип, слежение идет за взаимным
положением рамок спрайтов. При обнаружении пересечения координат, ябъявляется
событие "столкновение"
- Проверка столкновения точек: Сложный тип. Слежение ведется не только за
взаимным положением рамок спрайтов, но и за взаимным положением самих
изображений. Событие "столкновение" объявляется при обнаружении пересечения
точек изображений.
|
Рамка
Рамка определят размер спрайта, что дает
взаимодействовать спрайтам друг с другом. Так же
рамка нужна для определения момента обрезания
спрайта, при выходе за экран. Одним словом вещь
крайне важная. Если не указать ширину и высоту
рамки, DelphiX будет выводить спрайт, но не
сможет определять столкновения |
Проверка на столкновение рамок 1
столкновение есть |
Столкновение рамок
Как вы видите столкновение произошло. Но сами
спрайты не коснулись друг-друга.Это не очень
красиво, но зато очень быстро. |
столкновения нет
столкновение есть
|
Проверка на столкновение рамок 2
Есть ещё один способ проверки столкновения без
PixelCheck.
const Border = ...;
with TAnyObject.Create(MyForm.DXSpriteEngine.Engine) do
begin
Image:=...;
Width:=Image.PatternWidth - 2*Border;
Height:=Image.PatternHeight - 2*Border;
...
end;
В этом случае картинка будет выводиться
полностью, но квадрат столкновений уменьшится.
Необходимо изменить также и DoMove, ведь
X = OldX + Border и Y = OldY + Border.
Именно этот способ как правило используется в
аркадах. |
Проверка на столкновение точек
столкновения нет |
Проверка на столкновение точек
Более точный и красивый. Проверка на
столкновение самих изображений. Больше подходит
для сложных спрайтов. Требует большей загрузки
процессора.. |
Проверка на столкновение точек
столкновение есть |
Более точное определение столкновения
Два пиксела проверяют спрайты на столкновение.
Как видно рамки давно столкнулись, но событие
поизошло только когда столкнулись непрозрачные
части. |
Проверка на столкновение рамки и
точки
столкновения нет |
Смешивание типов обнаружения столкновения
Спрайты, использующие разные методы определения
столкновения то-же будут сталкиваться друг с
другом. Один спрайт использует определение по
рамке, другой по точке. Иногда смешиванием можно
добиться неплохих, реалистичных результатов.. |
Проверка на столкновение рамки и
точки
столкновение есть |
Альтернатива -(не лучшее решение, но
альтернативное...)
Как вы видите это не слишком великолепно. Игрок
может видет, что спрайты не столкнулись на самом
деле, а игра будет определять, что стокновение
произошло после попадания рамки одного спрайта
на непрозрачную точку другого. |
Выбор метода зависит от игры. Если это активная Аркада, то Проверка на
столкновение точек в ней ни к чему. Глаз не будет успевать замечать, что
столкновения произошло на пяток пикселей раньше, чем положено. А если это
размеренная, несуетливая РПГ, то без этого метода не обойтись.
Настройка обнаружения столкновений
Основные шаги, необходимые для этого.
- Создаем класс спрайта в обычном порядке
- Включаем DoMove процедуру
- Включаем (override)DoCollision процедуру
- Устанавливаем высоту и ширину спрайта.
- В процедуре DoMove вызываем метод Collision.
- В методе DoCollision, помещаем код, для обработки последствий столкновения.
- Выбираем метод обнаружения столкновений.
|