Графика для Windows средствами DirectDraw
Шрифт:
Функция CreateCustomSurfaces «раскручивает» генератор случайных чисел с помощью функции time, возвращающей системное время в секундах. Благодаря этому при каждом запуске программы будут генерироваться разные случайные числа.
Затем для каждой создаваемой поверхности готовится структура DDCOLORKEY. Для всех поверхностей этого приложения прозрачным является черный цвет (то есть нулевое значение).
Функция создает четыре поверхности, и по каждой поверхности — два спрайта. Если хотя бы один из BMP-файлов, по которым создаются поверхности, не будет найден,
Наконец, поверхность меню text инициализируется содержимым файла TEXT.BMP. Функция SetColorKey, как и в случае спрайтовых поверхностей, определяет прозрачный цвет. Код возврата TRUE является признаком успешного завершения.
Инициализация приложения завершена, теперь можно заняться функцией DrawScene. Эта функция выполняет проверку столкновений, строит кадр во вторичном буфере и переключает страницы. В программе Bumper функция DrawScene выглядит так:
Проверка столкновений осуществляется во вложенном цикле. Для каждой пары спрайтов вызывается функция SpritesCollide, а при обнаруженном столкновении вызывается функция Hit, которой в качестве аргументов передаются оба столкнувшихся спрайта. Напомню, что функция Sprite::Hit реализует стадию подтверждения в нашей модели проверки столкновений. Она сохраняет данные о столкновении, но не вносит никаких изменений в состояние спрайтов.
В отдельном цикле для каждого спрайта вызывается функция Update. На этом шаге реализуется стадия реакции. При обнаруженном столкновении функция Update определяет новую траекторию спрайта по сохраненным ранее данным. Кроме того, функция Update изменяет текущее положение спрайта.
После того как все столкновения будут обнаружены и обработаны, мы стираем вторичный буфер функцией DirectDrawWin::ClearSurface и выводим каждый спрайт функцией BltSurface. Обратите внимание на то, что вторым аргументом BltSurface является указатель на сам объект Sprite. В данном случае оператор LPDIRECTDRAWSURFACE преобразует объект Sprite в указатель на поверхность, соответствующую данному спрайту. Также стоит заметить, что координаты спрайтов определяются
функциями GetX и GetY. После прорисовки всех спрайтов в левом нижнем углу вторичного буфера выводится поверхность меню. Функция Flip переключает страницы и отображает кадр на экране.Как видно из меню, программа Bumper реагирует на две клавиши: пробел и Escape. Нажатие пробела приводит к тому, что векторы направлений каждого спрайта пересчитываются заново, а Escape завершает работу программы. Функция OnKeyDown выглядит так:
Прежде чем расставаться с программой Bumper, мы должны посмотреть, как происходит восстановление потерянных поверхностей. Как обычно, для этого служит функция RestoreSurfaces:
Сначала область памяти каждой поверхности восстанавливается функцией Restore (если поверхность не была потеряна, вызов Restore игнорируется). Затем функция LoadSurface восстанавливает содержимое поверхности. Обратите внимание — здесь, как и в функции DrawScene, используется оператор LPDIRECTDRAWSURFACE, позволяющий передавать объекты Sprite вместо указателей на поверхности. Работа функции завершается восстановлением поверхности меню (text).
Если запустить программу Bumper (даже на относительно медленном компьютере), становится очевидно, что наши функции проверки столкновений работают достаточно эффективно. Даже когда спрайты сближаются на близкое расстояние и активизируется проверка на уровне пикселей, замедления работы не ощущается. Отчасти это объясняется оптимизацией, а отчасти — тем обстоятельством, что мы непосредственно обращаемся к памяти поверхности. Конечно, если бы обращение к каждому пикселю осуществлялось через специальную функцию DirectDraw, программа работала бы намного медленнее.