Частицы обычно используются для улучшения внешнего вида игры. Игровой движок может использовать сотни полигонов для одного эффекта. По этой причине очень важным является использование как можно меньшего количества частиц и периодическое удаление старых частиц, которые уже больше не используются.
Например, попадание в стену из лазерной винтовки может породить группу частиц, представляющих летящие осколки. Эти осколки быстро отлетают и рассеиваются. Это типично для большинства используемых частиц - они существуют только в течение короткого интервала времени, а потом исчезают. Конечно есть исключения, когда частицы существуют всю игру. Например, возьмите биллбордные деревья или знаки, которые наполняют ландшафт. Эти частицы никогда не двигаются и не исчезают (если только их не растопчет монстр). Лучшим способом управления этими долго существующими объектами является рисование только тех, которые находятся в пределах определенного расстояния от смотрящего, таким образом уменьшая количество частиц, рисуемых за каждый кадр. Для демонстрационных программ, содержащихся на компакт-диске, я использовал частицы деревьев и людей, которые не уничтожаются. Также я использовал частицы клубов дыма - эти частицы уничтожаются после непродолжительного времени.
Реализовать список активных частиц легко с помощью связанного списка. Для каждой активной частицы существует соответствующая структура в связанном списке частиц. Как только вы хотите обновить частицы вашего движка, вы просматриваете весь связанный список и обновляете частицы, содержащиеся в нем. Если частица больше не нужна, ее структура освобождается и удаляется из связанного списка.
Возвращаясь к элементарному классу cParticle, созданному ранее в этой главе, вы можете добавить несколько указателей для создания связанного списка частиц. Также вы можете добавить в класс конструктор и деструктор, которые бы управляли этими указателями при создании и удалении экземпляра класса.
class cParticle
{
public:
// Предыдущие данные частицы, такие как тип, положение и т.д. cParticle *m_Prev; // Предыдущая частица в связанном списке cParticle *m_Next; // Следующая частица в связанном списке public:
// Конструктор и деструктор для очистки и освобождения данных
cParticle () { m_Prev = NULL; m_Next = NULL; }
-cParticle () { delete m_Next; m_Next=NULL; m_Prev=NULL; }
Т. к. используется связанный список, одна частица становиться корневой и к ней привязываются все остальные. Т. к. эта частица может уничтожаться, корневая частица может меняться со временем. Вы можете установить все добавляемые в связанный список частицы в качестве корневых, а потом привязать старую корневую частицу в качестве следующей (используя указатели rn_Prev и m_Next).
// pRoot = текущая корневая частица списка
// Создать новый экземпляр используемого класса частиц cParticle *pParticle = new cParticle() ;
// Связать новую частицу в качестве корня и привязать к старому корню
pParticle->m_Prev = NULL; // Очистить указатель на предыдущий объект pParticle->m_Next = pRoot; // Привязать новую частицу к старой корневой
pRoot->m_Prev = pParticle; // Привязать корневую частицу к новой pRoot = pParticle; // Переприсвоить корневую частицу новой
Для удаления заданной частицы, вы можете использовать указатели связанного списка, чтобы соединить связанные частицы и освободить ресурсы, удаляемой частицы.
// pParticle = указатель удаляемой частицы // pRoot = корневая частица
// Привязать предыдущую частицу к следующей if(pParticle->m_Prev) {
pParticle->m_Prev->m_Next = pParticle->m_Next; } else {
// Если предыдущей частицы нет, значит текущая частица является корневой.
// Теперь необходимо сделать корневой следующую частицу pRoot = pParticle->m_Next;
}
// Привязать следующую частицу к предыдущей if(pParticle->m_Next)
pParticle->m_Next->m_Prev = pParticle->m_Prev;
// Очистить указатели частицы и освободить ресурсы pParticle->m_Prev = pParticle->m_Next = NULL; delete pParticle;
Использование связанного списка является обычным программистским приемом, так что нет никакой нужды углубляться в детали. Я уверен, что существуют намного более эффективные способы управления списком частиц, но чтобы быть предельно честным (и я уверен, что получу немало электронных писем на этот счет!), использование связанного списка очень быстро и просто.
Я оставляю вам самостоятельно посмотреть исходный код демонстрационной программы Particles, чтобы увидеть, как использовать связанный список для хранения большого числа частиц. А пока, читайте, как использовать связанный список частиц для их визуализации.
⇐Использование интеллекта при обработке || Оглавление || Рисование частиц⇒