netlib.narod.ru< Назад | Оглавление | Далее >

Реализация системы частиц

Теперь загрузите проект D3D_Particles, если вы еще не сделали этого, и скомпилируйте его. Запустите программу и вы увидите сцену, похожую на ту, что показана на рис. 13.3.


Рис. 13.3. Окно программы D3D_Particles

Рис. 13.3. Окно программы D3D_Particles


Обратите внимание на разбросанные по экрану разноцветные частицы. Программа показывает как создать случайный набор частиц и подбрасывать их в воздух. Вы можете назвать это демонстрацией попкорна, я оставляю выбор за вами. Кажется я знаю, что вы думаете сейчас: «Какое это имеет отношение к программированию стратегических игр?». Ответ прост — предполагается, что программа покажет вам как можно быстро начать работать с частицами. Более сложные формирования, такие как взрывы и ударные волны, придут позднее, когда вы освоитесь с основными приемами использования частиц.

Проект состоит из четырех файлов: main.cpp, main.h, CParticle.cpp и CParticle.h. Кроме того, для компиляции потребуются следующие библиотеки: d3d9.lib, dxguid.lib, d3dx9dt.lib и d3dxof.lib.

Структура проекта D3D_Particles

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


Рис. 13.4. Ход выполнения программы D3D_Particles

Рис. 13.4. Ход выполнения программы D3D_Particles


На рис. 13.4 видно, как функция WinMain() выполняет инициализацию системы, последовательно обращаясь к функциям InitD3D(), vInitInterfaceObjects() и vInitParticles(). С первыми двумя функциями мы уже встречались в предыдущих примерах, а вот функция инициазизации частиц новая и появляется в этом примере впервые. Ее цель — создание частиц для сцены и установка их атрибутов для анимации.

Инициализация частиц

Код инициализации частиц выглядит следующим образом:

void vInitParticles(void)
{
   // Инициализация каждой частицы
   for(int i = 0; i < TOTAL_PARTICLES; i++) {
      // Установка последовательности анимации текстур
      g_partExplosion[i].vSetTextures(
         rand() % 3, // Тип анимации
         0,          // Начальная текстура
         5,          // Конечная текстура
         10);        // Пауза между сменой текстур
      // Установка начального местоположения
      g_partExplosion[i].vSetPos(
         0.0f + (rand() % g_iWindowWidth),     // X
         0.0f + (rand() % g_iWindowHeight),    // Y
         0.0f);                                // Z
      // Установка начальной скорости
      g_partExplosion[i].vSetSpeed(
         -1.0f + rand() % 2,                   // X
         -8.0f + rand() % 4,                   // Y
         0.0f);                                // Z
      // Установка гравитационного воздействия
      g_partExplosion[i].vSetGravity(
         0.0f,                             // X
         0.1f,                            // Y
         0.0f);                           // Z
      // Установка длительности жизни частицы
      g_partExplosion[i].vSetLife(200);
   }
}

Функция в цикле перебирает все частицы, количество которых задается определенной в заголовочном файле константой TOTAL_PARTICLES. Для каждой частицы задается случайное местоположение и скорость. Затем задается гравитационное воздействие и, в самом конце, продолжительность жизни частицы устанавливается равной 200. Это сообщает системе, что частица будет существовать в течение 200 игровых тактов.

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

Тип анимации выбирается случайным образом, а диапазон используемых при анимации текстур для всех частиц будет от 0 до 5. Кроме того, я задаю паузу между сменой текстур, равной 10 для того, чтобы кадры анимации не сменяли друг друга слишком быстро.

Визуализация частиц

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

// Цикл перебора частиц
for(int i = 0; i < TOTAL_PARTICLES; i++) {
   // Проверяем, жива ли частица
   if(g_partExplosion[i].bIsAlive()) {
       // Визуализация частицы
       vDrawInterfaceObject(g_partExplosion[i].m_vecPos.fX,
                    g_partExplosion[i].m_vecPos.fY,
                    (float)g_iParticleSize,
                    (float)g_iParticleSize,
                    g_pTexture[
                    g_partExplosion[i].m_iTextureCur
                    ]);
       // Обновление частицы
       g_partExplosion[i].vUpdate();
   }
   else {
      // Сброс частицы, если она уничтожена
      vInitParticles();
   }
}

Функция визуализации в цикле перебирает все частицы, количество которых задается определенной в заголовочном файле константой TOTAL_PARTICLES. Для каждой частицы функция сперва проверяет жива ли она еще. Если частица жива, функция отображает ее в текущем местоположении. Чтобы сообщить функции визуализации, какую текстуру следует использовать, применяется хранящийся в объекте частицы номер текущей текстуры. После визуализации частицы ее данные обновляются путем вызова функции vUpdate().

СОВЕТ
Если вы хотите увеличить или уменьшить количество частиц, поменяйте значение константы TOTAL_PARTICLES в заголовочном файле. Попробуйте делать его больше и больше, пока не заметите влияние на систему. Мой компьютер заметно замедляет работу, когда я создаю около 6000 частиц.

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


netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz