Стэн Трухильо - Графика для Windows средствами DirectDraw

Тут можно читать онлайн Стэн Трухильо - Графика для Windows средствами DirectDraw - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    Графика для Windows средствами DirectDraw
  • Автор:
  • Жанр:
  • Издательство:
    неизвестно
  • Год:
    неизвестен
  • ISBN:
    нет данных
  • Рейтинг:
    4.88/5. Голосов: 81
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 100
    • 1
    • 2
    • 3
    • 4
    • 5

Стэн Трухильо - Графика для Windows средствами DirectDraw краткое содержание

Графика для Windows средствами DirectDraw - описание и краткое содержание, автор Стэн Трухильо, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Графика для Windows средствами DirectDraw - читать онлайн бесплатно полную версию (весь текст целиком)

Графика для Windows средствами DirectDraw - читать книгу онлайн бесплатно, автор Стэн Трухильо
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Итак, как же будет выглядеть код проверки? Начнем с верхнего уровня и будем постепенно продвигаться вниз. Прежде всего нам понадобится цикл, который бы выполнял проверку столкновений для каждой пары спрайтов. Возникает искушение написать вложенный цикл следующего вида:

for (int i=0;insprites;j++) if (SpritesCollide(sprite[i], sprite[j])) {

sprite[i]->Hit(sprite[j]);

sprite[j]->Hit(sprite[i]);

}

Однако приведенный фрагмент обладает двумя недостатками. Во-первых, каждая пара спрайтов проверяется дважды, потому что и внешний, и внутренний циклы перебирают все элементы массива спрайтов. Это вызывает напрасную трату времени и может стать источником ошибок, потому что о каждом столкновении будет сообщено дважды. Во-вторых, мы проверяем каждый спрайт, чтобы узнать, не столкнулся ли он с самим собой — полученную информацию вряд ли можно назвать полезной. Чтобы избавиться от этих проблем, следует изменить цикл:

for (int i=0;insprites;j++) if (SpritesCollide(sprite[i], sprite[j])) {

sprite[i]->Hit(sprite[j]);

sprite[j]->Hit(sprite[i]);

}

Этот фрагмент гарантирует, что каждая пара спрайтов будет передаваться функции SpritesCollide()ровно один раз, и спрайты не будут проверяться на столкновения с собой.

Теперь давайте рассмотрим функцию SpritesCollide(). Как видно из кода, аргументами этой функции являются два спрайта. Функция SpritesCollide()возвращает TRUE, если спрайты сталкиваются, и FALSEв противном случае.

Реализация функции SpritesCollide()будет начинаться с проверки столкновений на уровне ограничивающих прямоугольников. Если результат окажется положительным (то есть ограничивающие прямоугольники пересекаются), следует перейти к проверке на уровне пикселей; в противном случае функция возвращает FALSE.

BOOL SpritesCollide(Sprite* sprite1, Sprite* sprite2) {

ASSERT(sprite1 && sprite2);

if (SpritesCollideRect(sprite1, sprite2)) if (SpritesCollidePixel(sprite1, sprite2)) return TRUE;

return FALSE;

}

Обратите внимание на то, что функция SpritesCollide()должна получать два аргумента — два указателя на объекты Sprite(класс Spriteрассматривается ниже). Сначала функция проверяет, что оба указателя отличны от нуля, с помощью макроса ASSERT().

СОВЕТ

ASSERT() в DirectDraw

Хотя в библиотеку MFC входит макрос ASSERT(), он плохо подходит для полноэкранных приложений DirectDraw. В приложении А описана нестандартная версия ASSERT(), использованная в программах этой книги.

Затем функция SpritesCollide()проверяет, пересекаются ли ограничивающие прямоугольники двух спрайтов. Эта проверка выполняется функцией SpritesCollideRect(), которая, как и SpritesCollide(), получает два указателя на объекты Spriteи возвращает логическое значение. Если прямоугольники не пересекаются (то есть SpritesCollideRect()возвращает FALSE), дальнейшая проверка не нужна, и функция возвращает FALSE— это означает, что два спрайта не сталкиваются.

Если ограничивающие прямоугольники пересекаются, необходимо продолжить проверку. Мы вызываем функцию SpritesCollidePixel()и также передаем ей два указателя на объекты Sprite. Если эта проверка окажется неудачной, SpritesCollide()возвращает FALSE; в противном случае она возвращает TRUE, что говорит о столкновении спрайтов.

Перед тем как рассматривать процедуру проверки на уровне пикселей, давайте рассмотрим функцию SpritesCollideRect(), в которой проверяется пересечение ограничивающих прямоугольников:

BOOL SpritesCollideRect(Sprite* sprite1, Sprite* sprite2) {

CRect rect1 = sprite1->GetRect();

CRect rect2 = sprite2->GetRect();

CRect r = rect1 & rect2;

// Если все поля равны нулю, прямоугольники не пересекаются

return !(r.left==0 && r.top==0 && r.right==0 && r.bottom==0);

}

Пересечение ограничивающих прямоугольников проверяется в функции SpritesCollideRect()с помощью класса MFC CRect. Сначала для каждого спрайта вызывается функция Sprite::GetRect(). Она возвращает объект CRect, определяющий текущее положение и размеры каждого спрайта. Затем третий объект CRectинициализируется оператором пересечения класса CRect( &), который вычисляет область пересечения двух своих операндов. Если пересечения не существует (два прямоугольника не перекрываются), все четыре поля CRectобнуляются. Этот признак используется для возврата TRUEв случае пересечения прямоугольников, и FALSE — в противном случае.

Функция SpritesCollidePixel()работает на уровне пикселей и потому выглядит значительно сложнее, чем ее аналог для ограничивающих прямоугольников. Функция SpritesCollidePixel()приведена в листинге 9.1.

Листинг 9.1. Функция SpritesCollidePixel()

BOOL SpritesCollidePixel(Sprite* sprite1, Sprite* sprite2) {

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));

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--;

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

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

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. Вычисляет области спрайтов, для которых потребуется проверка на уровне пикселей.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Стэн Трухильо читать все книги автора по порядку

Стэн Трухильо - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




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


Отзывы читателей о книге Графика для Windows средствами DirectDraw, автор: Стэн Трухильо. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x