Стэн Трухильо - Графика для Windows средствами DirectDraw
- Название:Графика для Windows средствами DirectDraw
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стэн Трухильо - Графика для Windows средствами DirectDraw краткое содержание
Графика для Windows средствами DirectDraw - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Функция GetRect()инициализирует объект CRect()данными о положении и размерах спрайта. Эта функция определяется так:
CRect Sprite::GetRect() {
CRect r;
r.left=x;
r.top=y;
r.right=x+w;
r.bottom=y+h;
return r;
}
Перейдем к функции Hit(). Напомню, что эта функция вызывается при обнаружении столкновения. Функции Hit()передается один аргумент — указатель на спрайт, с которым произошло столкновение. Она выглядит так:
void Sprite::Hit(Sprite* s) {
if (!collide) {
collideinfo.x=s->GetCenterX();
collideinfo.y=s->GetCenterY();
collide=TRUE;
}
}
Функция Hit()реализует стадию подтверждения столкновений. В нашем случае она сохраняет положение каждого из столкнувшихся спрайтов и присваивает логической переменной collideзначение TRUE. Обратите внимание — сохраняется лишь положение спрайта, а не указатель на сам спрайт. Это сделано намеренно, чтобы мы не смогли обратиться к спрайту во время реакции на столкновение (о ней говорится ниже). Следовательно, если вам потребуется другая информация о столкнувшемся спрайте, кроме его положения (например, тип спрайта или уровень его «здоровья» для компьютерной игры), ее необходимо сохранить в функции Hit(). Эту информацию следует получить немедленно, не дожидаясь стадии реакции, потому что к этому времени статус другого спрайта может измениться.
Функция Sprite::Update()выполняет две задачи: обновляет положение спрайта и, в случае столкновения, изменяет переменные, определяющие направление его перемещения ( xincи yinc). Функция Update()приведена в листинге 9.2.
Листинг 9.2. Функция Sprite::Update()
void Sprite::Update() {
if (collide) {
int centerx=GetCenterX();
int centery=GetCenterY();
int xvect=collideinfo.x-centerx;
int yvect=collideinfo.y-centery;
if ((xinc>0 && xvect>0) || (xinc<0 && xvect<0)) xinc=-xinc;
if ((yinc>0 && yvect>0) || (yinc<0 && yvect<0)) yinc=-yinc;
collide=FALSE;
}
x+=xinc;
y+=yinc;
if (x>640-w/2) {
xinc=-xinc;
x=640-w/2;
}
if (x<-(w/2)) {
xinc=-xinc;
x=-(w/2);
}
if (y>480-h/2) {
yinc=-yinc;
y=480-h/2;
}
if (y<-(h/2)) {
yinc=-yinc;
y=-(h/2);
}
}
Сначала Update()проверяет состояние логической переменной collide. Если переменная равна TRUE, мы получаем данные о положении двух спрайтов (текущего и столкнувшегося с ним) и используем их для вычисления новой траектории текущего спрайта. При этом используется схема, очень далекая от настоящей физической модели — при столкновении каждый спрайт отлетает в направлении, противоположном направлению удара.
Затем переменные xи yобновляются с учетом значений xincи yinc. Новое положение спрайта проверяется и при необходимости корректируется. Корректировка происходит, когда спрайт более чем наполовину уходит за край экрана.
Возможно, вы заметили некоторую ограниченность в реализации класса Sprite: при каждом обновлении спрайт может отреагировать лишь на одно столкновение. При одновременном столкновении с несколькими спрайтами для расчета реакции будет использован лишь один из них. Чтобы изменить такое поведение, можно создать массив структур CollideInfoи отдельно сохранять информацию о каждом спрайте, полученную функцией Hit(). В этом случае при вычислении новой траектории курса на стадии реакции будет учитываться положение каждого спрайта, участвующего в столкновении. Однако на практике в подавляющем большинстве столкновений участвуют всего два спрайта.
Программа Bumper
Для проверки алгоритма мы напишем демонстрационную программу. Программа Bumper выполняет отображение и анимацию восьми спрайтов. Как я упоминал, при столкновении спрайты разлетаются в противоположных направлениях. Программа Bumper изображена на рис. 9.4.

Рис. 9.4. Программа Bumper
Восемь спрайтов, показанных на рисунке, представлены четырьмя разными поверхностями — по каждой поверхности создаются два спрайта. Исходные векторы направления, по которым перемещаются спрайты, определяются случайным образом. В начале своей работы программа «раскручивает» генератор случайных чисел, чтобы результаты ее работы не были всегда одинаковыми. При нажатии клавиши пробела векторы направления пересчитываются заново. Код программы Bumper рассматривается в следующих разделах.
Программа Bumper, как и все остальные программы в этой книге, построена на основе базового класса DirectDrawWin. Производный от него класс BumperWinопределяется так:
class BumperWin : public DirectDrawWin {
public:
BumperWin();
protected:
//{{AFX_MSG(BumperWin)
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnDestroy();
//}}
AFX_MSG DECLARE_MESSAGE_MAP()
private:
int SelectDriver();
int SelectInitialDisplayMode();
BOOL CreateCustomSurfaces();
void DrawScene();
void RestoreSurfaces();
BOOL SpritesCollide(Sprite* s1, Sprite* s2);
BOOL SpritesCollideRect(Sprite* s1, Sprite* s2);
BOOL SpritesCollidePixel(Sprite* s1, Sprite* s2);
private:
Sprite* sprite[MAX_SPRITES];
int nsprites;
LPDIRECTDRAWSURFACE text;
};
В нем объявляются два обработчика сообщений. Функция OnKeyDown()обрабатывает нажатия клавиш, а функция OnDestroy()освобождает спрайты в конце работы программы.
Функции SelectDriver(), SelectInitialDisplayMode(), CreateCustomSurfaces(), DrawScene()и RestoreSurfaces()наследуются от класса DirectDrawWin. Вскоре мы подробно рассмотрим каждую из этих функций. Функции SpritesCollide(), SpritesCollideRect() и SpritesCollidePixel()совпадают с одноименными функциями, описанными выше, однако на этот раз они принадлежат классу BumperWin. Поскольку эти функции уже рассматривались, мы не будем обсуждать их снова.
В классе объявлены три переменные: массив указателей на объекты Sprite, целая переменная для хранения общего количества спрайтов и указатель textна интерфейс DirectDrawSurface. Первые две переменные предназначены для хранения спрайтов и последующих обращений к ним. Указатель textиспользуется для отображения меню, находящегося в левом нижнем углу экрана.
При запуске программы Bumper прежде всего вызывается функция SelectDriver(). Чтобы добиться максимальной гибкости, при наличии нескольких драйверов DirectDraw программа Bumper выводит меню. Функция SelectDriver()выглядит так:
Читать дальшеИнтервал:
Закладка: