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

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

Шрифт:

surf1->Unlock(surfptr1);

return ret;

Этот фрагмент похож на приведенный выше, за исключением того, что в нем блокируются обе поверхности и каждая из них просматривается по отдельности. Столкновение снова обнаруживается по совпадению двух непрозрачных пикселей. Перед тем как функция возвращает TRUE или FALSE, она снимает блокировку с обеих поверхностей.

Класс Sprite 

В коде предыдущего раздела класс Sprite использовался для представления спрайтов, проверяемых на столкновение. Давайте посмотрим, как он реализован.

Как мы уже видели, класс Sprite содержит ряд функций, с помощью которых при проверке столкновений можно получить сведения о каждом спрайте. В частности, функция GetRect возвращает контурный прямоугольник спрайта, а функция GetSurf — поверхность, на которой находится спрайт. Однако класс Sprite не ограничивается функциями простого контейнера для данных спрайта. Он предназначен не столько для обнаружения столкновений, сколько для их обработки.

На обнаруженное столкновение необходимо как-то прореагировать. Подробности обработки столкновения определяются приложением, но как проверка, так и обработка подчиняются некоторым общим правилам.

При столкновении двух спрайтов каждый из них может изменить направление движения или измениться иным образом (например, исчезнуть из кадра, как это бывает при уничтожении цели в компьютерных играх). Тем не менее необходимо соблюдать осторожность и не изменять статус спрайта до тех пор, пока проверка столкновений не будет выполнена для всех спрайтов. В противном случае могут возникнуть непредсказуемые ошибки.

Рассмотрим столкновение, в котором участвуют два спрайта. Наш код должен обнаруживать столкновение и сообщать об этом спрайтам. Предположим, один из спрайтов получает уведомление, немедленно вычисляет новую траекторию и изменяет свое положение. Когда сообщение о столкновении дойдет до второго спрайта, столкнувшийся с ним спрайт уже будет находиться в новом месте. Более того, перемещение первого спрайта может привести к тому, что для второго спрайта предыдущего столкновения как бы и не будет.

Чтобы избежать подобных неприятностей, необходимо соблюдать два правила:

1. Положение спрайтов не должно изменяться до завершения цикла проверок.

2. Каждый спрайт должен хранить информацию о положении спрайта, с которым он столкнулся, вместо того, чтобы обращаться к нему с запросом при обработке столкновения.

Класс Sprite эти правила соблюдает и, следовательно, справляется со всеми проблемами. Для этого обработка каждого столкновения осуществляется за две стадии, которые мы назовем подтверждением (acknowledgment) и реакцией (reaction). На стадии подтверждения спрайт всего лишь сохраняет статус и положение другого спрайта — его собственное положение и статус остаются неизменными. Затем, на стадии реакции, по ранее сохраненным данным определяются дальнейшие действия, вызванные столкновением. На этой стадии положение и статус спрайта могут изменяться. Функция Hit класса Sprite используется для подтверждения, а функция Update — для реакции. Класс Sprite определяется так:

class Sprite {

public:

 Sprite(LPDIRECTDRAWSURFACE, int x, int y);

 LPDIRECTDRAWSURFACE GetSurf {

return surf;

 }

 operator LPDIRECTDRAWSURFACE const {

return surf;

 }

 int GetX {

return x;

 }

 int GetY {

return y;

 }

 int GetCenterX {

return x+w/2;

 }

 int GetCenterY {

return y+h/2;

 }

 void SetXY(int xx, int yy) {

x=xx;

y=yy;

 }

 void SetXYrel(int xx,int yy) {

x+=xx;

y+=yy;

 }

 CRect GetRect;

 virtual void Update;

 void Hit(Sprite*);

 void CalcVector;

private:

 LPDIRECTDRAWSURFACE surf;

 int x, y;

 int w, h;

 int xinc, yinc;

 BOOL collide;

 struct CollideInfo {

int x, y;

 } collideinfo;

};

Конструктор класса Sprite получает три аргумента: указатель на поверхность DirectDraw, изображающую новый спрайт, и два целых числа, определяющих начальное положение спрайта. Так как конструктору передается поверхность DirectDraw, одна и та же поверхность может использоваться для нескольких спрайтов. Конструктор можно было бы написать так, чтобы в качестве аргумента он получал имя BMP-файла и сам создавал поверхность, но тогда каждый спрайт был бы связан с отдельной поверхностью — даже если для создания нескольких спрайтов используется один и тот же BMP-файл.

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

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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