Стэн Трухильо - Графика для Windows средствами DirectDraw
- Название:Графика для Windows средствами DirectDraw
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стэн Трухильо - Графика для Windows средствами DirectDraw краткое содержание
Графика для Windows средствами DirectDraw - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
int BumperWin::SelectDriver() {
int numdrivers=GetNumDrivers();
if (numdrivers==1) return 0;
CArray drivers;
for (int i=0;i
LPSTR desc, name;
GetDriverInfo(i, 0, &desc, &name);
drivers.Add(desc);
}
DriverDialog dialog;
dialog.SetContents(&drivers);
if (dialog.DoModal()!=IDOK) return -1;
return dialog.GetSelection();
}
С помощью класса DriverDialogпрограмма выводит меню со списком драйверов и использует драйвер, выбранный пользователем. Наши функции проверки столкновений предназначены только для 8-битных поверхностей, поэтому драйверы, не поддерживающие 8-битных видеорежимов (скажем, драйверы 3Dfx), в этой программе не работают. Следовательно, функция SelectInitialDisplayMode()должна правильно реагировать на выбор такого драйвера.
Функция SelectInitialDisplayMode()вызывается после функции SelectDriver(), но перед созданием поверхностей. Функция выглядит так:
int BumperWin::SelectInitialDisplayMode() {
DWORD curdepth=GetDisplayDepth();
int i, nummodes=GetNumDisplayModes();
DWORD w,h,d;
if (curdepth!=desireddepth) ddraw2->SetDisplayMode(640, 480, curdepth, 0, 0);
for (i=0;i
GetDisplayModeDimensions(i, w, h, d);
if (w==desiredwidth && h==desiredheight && d==desireddepth) return i;
}
ddraw2->RestoreDisplayMode();
ddraw2->Release(), ddraw2=0;
AfxMessageBox("Can't find 8-bit mode on this device");
return -1;
}
Функция SelectInitialDisplayMode()ищет конкретный видеорежим 640x480x8. Если этот режим не найден, она выводит сообщение и возвращает –1, говоря тем самым классу DirectDrawWinо том, что приложение следует завершить. Если режим будет найден, функция возвращает его индекс. По этому индексу класс DirectDrawWinузнает о том, какой видеорежим следует активизировать.
Если функция SelectInitialDisplayMode()находит нужный видеорежим, класс DirectDrawWinвызывает функцию CreateCustomSurfaces(). Она создает поверхности наших восьми спрайтов, а также поверхность меню. Функция CreateCustomSurfaces()приведена в листинге 9.3.
Листинг 9.3. Функция CreateCustomSurfaces()
BOOL BumperWin::CreateCustomSurfaces() {
DDCOLORKEY ddck;
ddck.dwColorSpaceLowValue = 0;
ddck.dwColorSpaceHighValue = 0;
LPDIRECTDRAWSURFACE surf;
srand(time(0));
CString msg="Can't find ";
surf=CreateSurface("diamond.bmp", TRUE);
if (surf==0) {
msg+="diamond.bmp";
Fatal(msg);
}
surf->SetColorKey(DDCKEY_SRCBLT, &ddck);
sprite[nsprites++]=new Sprite(surf, 0, 0);
sprite[nsprites++]=new Sprite(surf, 150, 0);
surf=CreateSurface("triangle.bmp");
if (surf==0) {
msg+="triangle.bmp";
Fatal(msg);
}
surf->SetColorKey(DDCKEY_SRCBLT, &ddck);
sprite[nsprites++]=new Sprite(surf, 0, 150);
sprite[nsprites++]=new Sprite(surf, 150, 150);
surf=CreateSurface("rect.bmp");
if (surf==0) {
msg+="rect.bmp";
Fatal(msg);
}
surf->SetColorKey(DDCKEY_SRCBLT, &ddck);
sprite[nsprites++]=new Sprite(surf, 0, 300);
sprite[nsprites++]=new Sprite(surf, 150, 300);
surf=CreateSurface("oval.bmp");
if (surf==0) {
msg+="oval.bmp";
Fatal(msg);
}
surf->SetColorKey(DDCKEY_SRCBLT, &ddck);
sprite[nsprites++]=new Sprite(surf, 300, 0);
sprite[nsprites++]=new Sprite(surf, 300, 150);
text=CreateSurface("text.bmp");
if (text==0) {
msg+="text.bmp";
Fatal(msg);
}
text->SetColorKey(DDCKEY_SRCBLT, &ddck);
return TRUE;
}
Функция CreateCustomSurfaces()«раскручивает» генератор случайных чисел с помощью функции time(), возвращающей системное время в секундах. Благодаря этому при каждом запуске программы будут генерироваться разные случайные числа.
Затем для каждой создаваемой поверхности готовится структура DDCOLORKEY. Для всех поверхностей этого приложения прозрачным является черный цвет (то есть нулевое значение).
Функция создает четыре поверхности, и по каждой поверхности — два спрайта. Если хотя бы один из BMP-файлов, по которым создаются поверхности, не будет найден, функция Fatal()выводит сообщение и завершает программу. Для успешно созданных поверхностей с помощью функции SetColorKey()интерфейса DirectDrawSurfaceактивизируются цветовые ключи.
Наконец, поверхность меню textинициализируется содержимым файла TEXT.BMP. Функция SetColorKey(), как и в случае спрайтовых поверхностей, определяет прозрачный цвет. Код возврата TRUEявляется признаком успешного завершения.
Инициализация приложения завершена, теперь можно заняться функцией DrawScene(). Эта функция выполняет проверку столкновений, строит кадр во вторичном буфере и переключает страницы. В программе Bumper()функция DrawScene()выглядит так:
void BumperWin::DrawScene() {
ASSERT(nsprites>0);
ASSERT(text);
for (int s1=0;s1nsprites;s2++) if (SpritesCollide(sprite[s1], sprite[s2])) {
sprite[s1]->Hit(sprite[s2]);
sprite[s2]->Hit(sprite[s1]);
}
for (int i=0;iUpdate();
ClearSurface(backsurf, 0);
for (i=0;i
Sprite* s=sprite[i];
BltSurface(backsurf, *s, s->GetX(), s->GetY(), TRUE);
}
BltSurface(backsurf, text, 0, 448, TRUE);
primsurf->Flip(0, DDFLIP_WAIT);
}
Проверка столкновений осуществляется во вложенном цикле. Для каждой пары спрайтов вызывается функция SpritesCollide(), а при обнаруженном столкновении вызывается функция Hit(), которой в качестве аргументов передаются оба столкнувшихся спрайта. Напомню, что функция Sprite::Hit()реализует стадию подтверждения в нашей модели проверки столкновений. Она сохраняет данные о столкновении, но не вносит никаких изменений в состояние спрайтов.
В отдельном цикле для каждого спрайта вызывается функция Update(). На этом шаге реализуется стадия реакции. При обнаруженном столкновении функция Update()определяет новую траекторию спрайта по сохраненным ранее данным. Кроме того, функция Update()изменяет текущее положение спрайта.
После того как все столкновения будут обнаружены и обработаны, мы стираем вторичный буфер функцией DirectDrawWin::ClearSurface()и выводим каждый спрайт функцией BltSurface(). Обратите внимание на то, что вторым аргументом BltSurface()является указатель на сам объект Sprite. В данном случае оператор LPDIRECTDRAWSURFACE()преобразует объект Spriteв указатель на поверхность, соответствующую данному спрайту. Также стоит заметить, что координаты спрайтов определяются функциями GetX()и GetY(). После прорисовки всех спрайтов в левом нижнем углу вторичного буфера выводится поверхность меню. Функция Flip()переключает страницы и отображает кадр на экране.
Как видно из меню, программа Bumper реагирует на две клавиши: пробел и Escape. Нажатие пробела приводит к тому, что векторы направлений каждого спрайта пересчитываются заново, а Escapeзавершает работу программы. Функция OnKeyDown()выглядит так:
void BumperWin::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
Интервал:
Закладка: