Вход/Регистрация
Графика для Windows средствами DirectDraw
вернуться

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

Шрифт:

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

  • Читать дальше
  • 1
  • ...
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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