/// <summary> /// 更新粒子物理属性,如果粒子超过边界,将其回收 /// </summary> /// <param name="elapsedTime"></param> /// <param name="size"></param> public void Update(float elapsedTime, Vector2 size) { { if (surfaceLoaded) { for (int i = ActiveParticles.Count - 1; i >= 0; i--) { var p = ActiveParticles[i]; if (p == null) { ActiveParticles.RemoveAt(i); return; } if (p.Position.X > 0 - size.Y * (float)Math.Tan(1.5708 - (minRotationAngle + maxRotationAngle) / 2) && p.Position.X <= size.X && p.Position.Y <= size.Y) { p.Update(elapsedTime); } else { ActiveParticles.RemoveAt(i); FreeParticles.Push(p); } } } } }
public override void AddParticle() { Particle Snowflake = new Particle(Texture, LifeTime); Snowflake.Color = Color.White; Snowflake.Scale = new Vector2(1, 1); Snowflake.Alpha = 1.0f; Snowflake.LayerDepth = 0.81f; //RANDOM POSITION OF SNOW float X = (float)Randomizer.Next((int)startPosition.X, topLength); float Y = (float)Randomizer.Next((int)startPosition.Y, sideLength); Snowflake.Position = new Vector2(X, Y); //RANDOM VELOCITY OF SNOW Snowflake.Velocity.X = 0; Snowflake.Velocity.Y = 100; Snowflake.Alive = true; ActiveParticles.Add(Snowflake); //MAKES THE PARTICLE ACTIVE } //THE LOGIC BEHIND WHEN TO ADD MORE PARTICLES
public override void AddParticles(Vector2 size) { if (surfaceLoaded) { if (!inited) { InitSmoke(size); } // 添加的数量 var m = (int)(size.X * minDensity); var n = (int)(size.X * maxDensity); var actualAdd = Tools.Random.Next(m, n) - ActiveParticles.Count; if (actualAdd < 0) { actualAdd = 0; } // 激活这些粒子 for (int i = 0; i < actualAdd; i++) { // 从空闲粒子堆里取粒子,如果没有,那么就 new 一个 Particle particle = (FreeParticles.Count > 0) ? FreeParticles.Pop() : new Particle(); particle.Key = Tools.Random.Next(0, smokeSurfaceName[flag].Length); var where = new Vector2(0 - (float)(surfacesBounds[particle.Key].Width / 2), Tools.RandomBetween(0 - (float)(surfacesBounds[particle.Key].Height / 2), size.Y / 5 - (float)(surfacesBounds[particle.Key].Height / 2))); // 初始化粒子参数 InitializeParticle(particle, where); // 将此粒子加入激活粒子队列 if (ActiveParticles.Capacity <= ActiveParticles.Count) { ActiveParticles.Capacity = ActiveParticles.Count * 2; } ActiveParticles.Add(particle); } } }
public void RemoveRecent() { DefaultSprite3DBillboardParticle cparticle = ActiveParticles.Last.Value; ActiveParticles.RemoveLast(); ActiveParticles.RemoveLast(); ActiveParticles.AddLast(cparticle); }
public override void AddParticle() { if (elaspedtime > mSpawnTime && ActiveParticles.Count < mMaxParticles) { ActiveParticles.Add(Randomize_Particle()); elaspedtime = 0; } }
internal void ImmersiveOut() { inited = false; for (int i = ActiveParticles.Count - 1; i >= 0; i--) { var p = ActiveParticles[i]; ActiveParticles.RemoveAt(i); FreeParticles.Push(p); } isImmersive = false; }
public void Dispose() { if (surfaceLoaded && bitmap != null) { bitmap.Dispose(); surfaceLoaded = false; } freeParticles.Clear(); ActiveParticles.Clear(); }
//=========================================================== // Particle System Update Functions //=========================================================== /// <summary> /// Sorts the particles to draw particles furthest from the camera first, in order to achieve proper depth perspective. /// /// <para>NOTE: This operation is very expensive and should only be used when you are /// drawing particles with both opaque and semi-transparent portions, and not using additive blending.</para> /// <para>Merge Sort is the sorting algorithm used, as it tends to be best for linked lists. /// TODO - WHILE MERGE SORT SHOULD BE USED, DUE TO TIME CONSTRAINTS A (PROBABLY) SLOWER METHOD (QUICK-SORT) /// IS BEING USED INSTEAD. THIS FUNCTION NEEDS TO BE UPDATED TO USE MERGE SORT STILL. /// THE LINKED LIST MERGE SORT ALGORITHM CAN BE FOUND AT http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html</para> /// </summary> /// <param name="fElapsedTimeInSeconds">How long it has been since the last update</param> protected void UpdateParticleSystemToSortParticlesByDistanceFromCamera(float fElapsedTimeInSeconds) { // Store the Number of Active Particles to sort int iNumberOfActiveParticles = ActiveParticles.Count; // If there is nothing to sort if (iNumberOfActiveParticles <= 1) { // Exit without sorting return; } // Create a List to put the Active Particles in to be sorted List <Particle> cActiveParticleList = new List <Particle>(iNumberOfActiveParticles); // Add all of the Particles to the List LinkedListNode <Particle> cNode = ActiveParticles.First; while (cNode != null) { // Copy this Particle into the Array cActiveParticleList.Add(cNode.Value); // Move to the next Active Particle cNode = cNode.Next; } // Now that the List is full, sort it cActiveParticleList.Sort(delegate(Particle Particle1, Particle Particle2) { DefaultSprite3DBillboardParticle cParticle1 = (DefaultSprite3DBillboardParticle)(DPSFParticle)Particle1; DefaultSprite3DBillboardParticle cParticle2 = (DefaultSprite3DBillboardParticle)(DPSFParticle)Particle2; return(cParticle1.DistanceFromCameraSquared.CompareTo(cParticle2.DistanceFromCameraSquared)); }); // Now that the List is sorted, add the Particles into the Active Particles Linked List in sorted order ActiveParticles.Clear(); for (int iIndex = 0; iIndex < iNumberOfActiveParticles; iIndex++) { // Add this Particle to the Active Particles Linked List. // List is sorted from smallest to largest, but we want // our Linked List sorted from largest to smallest, since // the Particles at the end of the Linked List are drawn last. ActiveParticles.AddFirst(cActiveParticleList[iIndex]); } }
public override void AddParticle() { Particle SnowTrail = new Particle(Texture, LifeTime); SnowTrail.Color = Color.White; SnowTrail.Scale = new Vector2(0.9f, 0.7f); SnowTrail.Alpha = 1.0f; SnowTrail.Position = EmitterPosition; SnowTrail.LayerDepth = 0.01f; SnowTrail.Alive = true; ActiveParticles.Add(SnowTrail); }
/// <summary> /// 获得画布尺寸,在画布顶部生成粒子 /// </summary> /// <param name="size"></param> public void AddRainDrop(Vector2 size) { { if (surfaceLoaded) { numParticles += (Tools.RandomBetween(minDensity, maxDensity) * size.X); var actualAdd = (int)numParticles; numParticles %= 1; for (int i = 0; i < actualAdd; i++) { Particle particle = (FreeParticles.Count > 0) ? FreeParticles.Pop() : new Particle(); float x = Tools.RandomBetween(0 - size.Y * (float)Math.Tan(1.5708 - (minRotationAngle + maxRotationAngle) / 2), size.X); InitializeParticle(particle, new Vector2(x, -5)); if (ActiveParticles.Capacity <= ActiveParticles.Count) { ActiveParticles.Capacity = ActiveParticles.Count * 2; } ActiveParticles.Add(particle); } } } }
// 刷新所有的激活粒子 public virtual void Update(float elapsedTime) { if (surfaceLoaded) { // 从队列的末尾向前遍历,这样执行 Remove 的时候不会出错 for (int i = activeParticles.Count - 1; i >= 0; i--) { Particle particle = activeParticles[i]; if (particle == null) { ActiveParticles.RemoveAt(i); return; } if (!particle.Update(elapsedTime)) { // 如果粒子不再存活,将它去掉 activeParticles.RemoveAt(i); freeParticles.Push(particle); } } } }
/// <summary> /// 更新粒子物理属性,如果粒子超过边界,将其回收 /// </summary> /// <param name="elapsedTime"></param> /// <param name="size"></param> public void Update(float elapsedTime, Vector2 size) { if (surfaceLoaded) { for (int i = ActiveParticles.Count - 1; i >= 0; i--) { var p = ActiveParticles[i]; if (p == null) { ActiveParticles.RemoveAt(i); return; } if (p.Position.X < (size.X + (surfacesBounds[p.Key].Width) / 2)) { p.Update(elapsedTime); } else { ActiveParticles.RemoveAt(i); FreeParticles.Push(p); } } } }
private void InitSmoke(Vector2 size) { var m = (int)(size.X * minDensity); var n = (int)(size.X * maxDensity); var add = Tools.Random.Next(m, n); for (int i = 0; i < add; i++) { // 从空闲粒子堆里取粒子,如果没有,那么就 new 一个 Particle particle = (FreeParticles.Count > 0) ? FreeParticles.Pop() : new Particle(); particle.Key = Tools.Random.Next(0, smokeSurfaceName[flag].Length); var where = new Vector2(Tools.RandomBetween(0 - (float)(surfacesBounds[particle.Key].Width / 2), size.X + (float)(surfacesBounds[particle.Key].Width / 2)), Tools.RandomBetween((0 - (float)(surfacesBounds[particle.Key].Height / 2)), size.Y / 5 - (float)(surfacesBounds[particle.Key].Height / 2))); // 初始化粒子参数 InitializeParticle(particle, where); // 将此粒子加入激活粒子队列 if (ActiveParticles.Capacity <= ActiveParticles.Count) { ActiveParticles.Capacity = ActiveParticles.Count * 2; } ActiveParticles.Add(particle); } inited = true; }
/// <summary> /// Returns a string describing the status of the Emitter. The string is formatted as /// [#active particles]/[budget]. /// </summary> /// <returns></returns> public string Status() { return(ActiveParticles.ToString() + "\\" + _budget.ToString()); }
public override void AddParticle() { ActiveParticles.Add(RandomizeParticle()); }