Там где дым, огонь и взрывы…, там 3D-движок Tranquility

Грэг Дункан

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

Скажем, вы пишете классную игру и нуждаетесь во взрыве для завершения. Вы не хотите убогого взрыва, но что же делать?

Идем сюда…

3D-движок Tranquility

Tranquility (спокойствие) – это компактная, простая в использовании и расширяемая трехмерная система моделирования частиц для проектов Windows Phone 7 XNA.

clip_image002

Для установки или интеграции системы в проект прочтите Руководство начинающего. Чтобы узнать, как использовать Tranquility прочтите Использование Tranquility.

Использование Tranquility

Использовать Tranquility крайне просто, большинство задач решаются с помощью пары строк кода. Демонстрационный проект, приведенный в исходниках, показывает более сложные сценарии, включая примеры пламени, дыма и взрывов.

Управление частицами

Все свойства частиц поведение и прорисовка управляются, включенным в Tranquility модулем ParticleManager . Это компонент типа DrawableGameComponent , который просто добавляется к коллекции компонентов игры.

...

ParticleManagerдолжен знать как отображать ваш мир. Используйте метод SetMatricesдля задания матриц отображения и проектирования.

Системычастиц

ParticleSystem определяет группу частиц с общим представлением текстуры. Есть два основных типа систем частиц в Tranquility:

  • StaticParticleSystem: У всех частиц в этой системе статические свойства. Если к системе добавляется частица, она не может перемещаться, расти, изменять цвет и т. п. Хотя частицы могут таким образом добавляться в систему и убираться из нее «на лету», этот способ идеален для статически размещаемых частиц.
  • DynamicParticleSystem : система динамических частиц содержит набор частиц, у которых есть скорость, вращение, время жизни и на которые могут влиять различные объекты.

Созданиеирегистрациясистемычастиц

Чтобы задать систему, определите максимальный объем и текстуру, которые будут использованы в системе, в методе LoadContent . Например, создайте динамическую систему частиц:

    • ..
    • Частицы

Перегруженный метод AddParticle можно использовать для добавления частиц в любую систему. Класс RandomHelper применяется для реализации случайной генерации частиц. Например:

particleSystem.AddParticle(
RandomHelper.Vector3Between(Vector3.Up, Vector3.Down),
RandomHelper.Color(),
RandomHelper.NormalizedVector3(),
RandomHelper.Float(),
TimeSpan.FromSeconds(RandomHelper.IntBetween(1, 3))
);

Генерация частиц

Генерация частиц автоматизирована с помощью специального генератора частиц. Для создания собственных генераторов предназначен интерфейс IParticleEmitter:

1: public class CustomParticleEmitter : IParticleEmitter

Реализация метода Updateпозволяет генератору автоматически порождать частицы в систему, для которой он вызывается. Метод Emitприменяется для ручной генерации частиц.

...

  • Аффекторы частиц

Аффектор частицы (particle affector) может оказывать влияние на одно или несколько свойств всех частиц в системе. В Tranquillity есть три стандартных аффектора, использующих возраст частицы как временной фактор:

  • Замедление: Останавливает частицы вплоть до полной остановки к концу времени жизни. Влияет только на движущиеся частицы.
  • Исчезновение: Уменьшает параметр альфа частицы, пока она не станет полностью прозрачной в конце жизни.
  • Сокращение: Уменьшает размеры частицы до полного исчезновения в конце жизни.
    • ...

Вот фрагмент решения. Как видно, оно не выглядит сумасшедшим или невозможно сложным (и не использует никакие другие библиотеки).

clip_image004clip_image006clip_image008

Фрагмент кода демонстрационного приложения:

 public FireParticleSystem(int maxCapacity, Texture2D texture)
     : base(maxCapacity, texture)
{
}
public override void Update(GameTime gameTime)
{
      EmitParticles(gameTime);
      foreach (DynamicParticle particle in liveParticles)
      {
         particle.Color = Color.Lerp(particle.InitialColor, new Color(1.0f, 1.0f, 1.0f, 0.0f), 1.0f - particle.Age.Value);
         particle.Scale += 0.001f;
      }
      base.Update(gameTime);
}

 
private void EmitParticles(GameTime gameTime)
{
      particlesEmitted += (float)gameTime.ElapsedGameTime.TotalSeconds * (float)EmissionRate;
      int emittedCount = (int)particlesEmitted;
      if (emittedCount > 0)
      {
         for (int i = 0; i < emittedCount; i++)
         {
             AddParticle(
                 RandomPointOnCircle(),
                 new Color(255, 255, 255, 100),
                 RandomHelper.Vector3Between(new Vector3(-0.25f, 0.0f, 0.0f), new Vector3(0.25f, 1.0f, 0.0f)),
                 RandomHelper.FloatBetween(-0.01f, 0.1f),
                 TimeSpan.FromSeconds(RandomHelper.IntBetween(1, 2)),
                 true,
                 RandomHelper.FloatBetween(0.0f, MathHelper.TwoPi),
                 RandomHelper.FloatBetween(0.05f, 0.075f));
         }
 
         particlesEmitted -= emittedCount;
     }
}

Это один из проектов, которые помогут добавить последний штрих, отполировать ваше приложение или игру…