Графика для Windows средствами DirectDraw
Шрифт:
Итак, как же будет выглядеть код проверки? Начнем с верхнего уровня и будем постепенно продвигаться вниз. Прежде всего нам понадобится цикл, который бы выполнял проверку столкновений для каждой пары спрайтов. Возникает искушение написать вложенный цикл следующего вида:
Однако приведенный фрагмент обладает двумя недостатками.
Этот фрагмент гарантирует, что каждая пара спрайтов будет передаваться функции SpritesCollide ровно один раз, и спрайты не будут проверяться на столкновения с собой.
Теперь давайте рассмотрим функцию SpritesCollide. Как видно из кода, аргументами этой функции являются два спрайта. Функция SpritesCollide возвращает TRUE, если спрайты сталкиваются, и FALSE в противном случае.
Реализация функции SpritesCollide будет начинаться с проверки столкновений на уровне ограничивающих прямоугольников. Если результат окажется положительным (то есть ограничивающие прямоугольники пересекаются), следует перейти к проверке на уровне пикселей; в противном случае функция возвращает FALSE.
Обратите внимание на то, что функция SpritesCollide должна получать два аргумента — два указателя на объекты Sprite (класс Sprite рассматривается ниже). Сначала функция проверяет, что оба указателя отличны от нуля, с помощью макроса ASSERT.
ASSERT в DirectDraw
Хотя в библиотеку MFC входит макрос ASSERT, он плохо подходит для полноэкранных приложений DirectDraw. В приложении А описана нестандартная версия ASSERT, использованная в программах этой книги.
Затем функция SpritesCollide проверяет, пересекаются ли ограничивающие прямоугольники двух спрайтов. Эта проверка выполняется функцией SpritesCollideRect, которая, как и SpritesCollide, получает два указателя на объекты Sprite и возвращает логическое значение. Если прямоугольники не пересекаются (то есть SpritesCollideRect
Если ограничивающие прямоугольники пересекаются, необходимо продолжить проверку. Мы вызываем функцию SpritesCollidePixel и также передаем ей два указателя на объекты Sprite. Если эта проверка окажется неудачной, SpritesCollide возвращает FALSE; в противном случае она возвращает TRUE, что говорит о столкновении спрайтов.
Перед тем как рассматривать процедуру проверки на уровне пикселей, давайте рассмотрим функцию SpritesCollideRect, в которой проверяется пересечение ограничивающих прямоугольников:
Пересечение ограничивающих прямоугольников проверяется в функции SpritesCollideRect с помощью класса MFC CRect. Сначала для каждого спрайта вызывается функция Sprite::GetRect. Она возвращает объект CRect, определяющий текущее положение и размеры каждого спрайта. Затем третий объект CRect инициализируется оператором пересечения класса CRect (& ), который вычисляет область пересечения двух своих операндов. Если пересечения не существует (два прямоугольника не перекрываются), все четыре поля CRect обнуляются. Этот признак используется для возврата TRUE в случае пересечения прямоугольников, и FALSE — в противном случае.
Функция SpritesCollidePixel работает на уровне пикселей и потому выглядит значительно сложнее, чем ее аналог для ограничивающих прямоугольников. Функция SpritesCollidePixel приведена в листинге 9.1.
Листинг 9.1. Функция SpritesCollidePixel