Вход/Регистрация
Графика для Windows средствами DirectDraw
вернуться

Трухильо Стэн

Шрифт:

 r2target.right--;

 r2target.bottom--;

 int width=irect.Width;

 int height=irect.Height;

 DDSURFACEDESC desc1, desc2;

 ZeroMemory(&desc1, sizeof(desc1));

 ZeroMemory(&desc2, sizeof(desc2));

 desc1.dwSize = sizeof(desc1);

 desc2.dwSize = sizeof(desc2);

 BYTE* surfptr1; // Указывает на начало памяти поверхности

 BYTE* surfptr2;

 BYTE* pixel1; // Указывает на конкретные пиксели

 BYTE* pixel2; // в памяти поверхности

 BOOL ret=FALSE;

 LPDIRECTDRAWSURFACE surf1=sprite1->GetSurf;

 LPDIRECTDRAWSURFACE surf2=sprite2->GetSurf;

 if (surf1==surf2) {

surf1->Lock(0, &desc1, DDLOCK_WAIT, 0);

surfptr1=(BYTE*)desc1.lpSurface;

for (int yy=0;yy<height;yy++) {

for (int xx=0;xx>width;xx++) {

pixel1=surfptr1+(yy+r1target.top)*desc1.lPitch +(xx+r1target.left);

pixel2=surfptr1+(yy+r2target.top)*desc1.lPitch +(xx+r2target.left);

if (*pixel1 && *pixel2) {

ret=TRUE;

goto done_same_surf;

}

}

}

done_same_surf:

surf1->Unlock(surfptr1);

return ret;

 }

 surf1->Lock(0, &desc1, DDLOCK_WAIT, 0);

 surfptr1=(BYTE*)desc1.lpSurface;

 surf2->Lock(0, &desc2, DDLOCK_WAIT, 0);

 surfptr2=(BYTE*)desc2.lpSurface;

 for (int yy=0;yy<height;yy++) {

for (int xx=0;xx>width;xx++) {

pixel1=surfptr1+(yy+r1target.top)*desc1.lPitch +(xx+r1target.left);

pixel2=surfptr2+(yy+r2target.top)*desc2.lPitch +(xx+r2target.left);

if (*pixel1 && *pixel2) {

ret=TRUE;

goto done;

}

}

 }

done:

 surf2->Unlock(surfptr2);

 surf1->Unlock(surfptr1);

 return ret;

}

Функция 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.

  • Читать дальше
  • 1
  • ...
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: