Графика для Windows средствами DirectDraw


Функции проверки столкновений - часть 4


br>Функция SpritesCollidePixel() состоит из четырех этапов. Она делает следующее:

  1. Определяет положения и размеры обоих спрайтов, а также вычисляет область их пересечения.

  2. Вычисляет области спрайтов, для которых потребуется проверка на уровне пикселей.

  3. Если оба спрайта находятся на одной поверхности — выполняет проверку, для чего сначала блокирует поверхность, а затем просматривает ее память в соответствии с положением обоих спрайтов. Если спрайты находятся на разных поверхностях, функция блокирует обе поверхности и просматривает память каждой из них.

  4. Снимает блокировку с обеих поверхностей и возвращает TRUE или FALSE.

На этапе 1 мы инициализируем два объекта CRect функцией Sprite::GetRect(). Функция GetRect() возвращает прямоугольник CRect, представляющий положение и размеры спрайта. Затем оператор & (оператор пересечения класса CRect) определяет область пересечения двух прямоугольников. Ниже снова приведен соответствующий фрагмент листинга 9.1:


CRect rect1=sprite1->GetRect(); CRect rect2=sprite2->GetRect();

CRect irect = rect1 & rect2;

ASSERT(!(irect.left==0 && irect.top==0 && irect.right==0 && irect.bottom==0));


Как мы узнали из функции SpritesCollideRect(), оператор пересечения класса CRect обнуляет все четыре поля CRect, если операнды не пересекаются. В этом случае функцию SpritesCollidePixel() вызывать не следует, поэтому о такой ситуации сообщает макрос ASSERT().

На этапе 2 мы вычисляем область каждого спрайта, для которой должна осуществляться проверка пикселей. Для этого снова используется оператор пересечения:


CRect r1target = rect1 & irect; r1target.OffsetRect( -rect1.left, -rect1.top ); r1target.right--; r1target.bottom--;

CRect r2target = rect2 & irect; r2target.OffsetRect( -rect2.left, -rect2.top ); r2target.right--; r2target.bottom--;


В прямоугольниках r1target и r2target

хранятся области спрайтов, для которых потребуется проверка на уровне пикселей. После того как пересечение будет найдено, оба прямоугольника сдвигаются функцией CRect::OffsetRect() так, чтобы левый верхний угол имел координаты (0, 0).


Начало  Назад  Вперед