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

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

Жанры

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

Трухильо Стэн

Шрифт:

void Sprite::CalcVector {

 xinc=(rand%7)-3;

 yinc=(rand%7)-3;

}

Функция CalcVector инициализирует переменные xinc и yinc с помощью генератора случайных чисел rand. Полученное от rand значение преобразуется так, чтобы оно принадлежало интервалу от –3 до 3. Эти значения будут использоваться для перемещения спрайта при очередном обновлении экрана. Обратите внимание — одна или обе переменные вполне могут быть равны нулю. Если нулю равна только одна переменная, перемещение спрайта ограничивается осью X или Y. Если нулю равны обе переменные, спрайт вообще

не двигается.

Функция 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 рассматривается в следующих разделах. 

Класс BumperWin 

Программа 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);

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

Флеш Рояль

Тоцка Тала
Детективы:
триллеры
7.11
рейтинг книги
Флеш Рояль

Паладин из прошлого тысячелетия

Еслер Андрей
1. Соприкосновение миров
Фантастика:
боевая фантастика
попаданцы
6.25
рейтинг книги
Паладин из прошлого тысячелетия

Ученик

Первухин Андрей Евгеньевич
1. Ученик
Фантастика:
фэнтези
6.20
рейтинг книги
Ученик

Бастард Императора. Том 4

Орлов Андрей Юрьевич
4. Бастард Императора
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Бастард Императора. Том 4

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

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

Вперед в прошлое 10

Ратманов Денис
10. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 10

Волхв пятого разряда

Дроздов Анатолий Федорович
2. Ледащий
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Волхв пятого разряда

Кодекс Крови. Книга Х

Борзых М.
10. РОС: Кодекс Крови
Фантастика:
фэнтези
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга Х

Осознание. Пятый пояс

Игнатов Михаил Павлович
14. Путь
Фантастика:
героическая фантастика
5.00
рейтинг книги
Осознание. Пятый пояс

Леди Малиновой пустоши

Шах Ольга
Любовные романы:
любовно-фантастические романы
6.20
рейтинг книги
Леди Малиновой пустоши

Измена. Не прощу

Леманн Анастасия
1. Измены
Любовные романы:
современные любовные романы
4.00
рейтинг книги
Измена. Не прощу

Господин следователь 6

Шалашов Евгений Васильевич
6. Господин следователь
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Господин следователь 6

Тепла хватит на всех

Котов Сергей
1. Миры Пентакля
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Тепла хватит на всех

Отмороженный 4.0

Гарцевич Евгений Александрович
4. Отмороженный
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Отмороженный 4.0