Чтение онлайн

на главную - закладки

Жанры

Графика для 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.

На этапе 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). Это объясняется тем, что поля right и bottom объектов CRect будут использоваться для обращений к поверхностям обоих спрайтов, а это требует перехода к локальным системам координат этих поверхностей.

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

Матабар. II

Клеванский Кирилл Сергеевич
2. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар. II

Архил...?

Кожевников Павел
1. Архил...?
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Архил...?

Жандарм

Семин Никита
1. Жандарм
Фантастика:
попаданцы
альтернативная история
аниме
4.11
рейтинг книги
Жандарм

На границе империй. Том 8. Часть 2

INDIGO
13. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 8. Часть 2

Проводник

Кораблев Родион
2. Другая сторона
Фантастика:
боевая фантастика
рпг
7.41
рейтинг книги
Проводник

Эволюционер из трущоб. Том 5

Панарин Антон
5. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 5

Кротовский, сколько можно?

Парсиев Дмитрий
5. РОС: Изнанка Империи
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Кротовский, сколько можно?

Отверженный. Дилогия

Опсокополос Алексис
Отверженный
Фантастика:
фэнтези
7.51
рейтинг книги
Отверженный. Дилогия

Имя нам Легион. Том 3

Дорничев Дмитрий
3. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 3

Отморозок 4

Поповский Андрей Владимирович
4. Отморозок
Фантастика:
попаданцы
фантастика: прочее
5.00
рейтинг книги
Отморозок 4

Идеальный мир для Лекаря 21

Сапфир Олег
21. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 21

Невеста инопланетянина

Дроздов Анатолий Федорович
2. Зубных дел мастер
Фантастика:
космическая фантастика
попаданцы
альтернативная история
5.25
рейтинг книги
Невеста инопланетянина

Здравствуй, 1984-й

Иванов Дмитрий
1. Девяностые
Фантастика:
альтернативная история
6.42
рейтинг книги
Здравствуй, 1984-й

Экзо

Катлас Эдуард
2. Экзо
Фантастика:
боевая фантастика
постапокалипсис
8.33
рейтинг книги
Экзо