public int Fade(Particle particle, float ParticleLifeTime) { int fade = particle.Fade; if (ParticleFadeIn && ParticleFadeOut) { FadeDelay = (int)ParticleLifeTime / 2; } // Fade in if (ParticleFadeIn) { if (particle.TotalLifetime <= ParticleLifeTime - FadeDelay) { fade = (int)(((particle.TotalLifetime) / (ParticleLifeTime - FadeDelay)) * particle.InitialOpacity); } } // Fade out if (ParticleFadeOut) { if (particle.TotalLifetime > FadeDelay) { fade = particle.InitialOpacity - (int)(((particle.TotalLifetime - FadeDelay) / (ParticleLifeTime - FadeDelay)) * particle.InitialOpacity); } } return fade; }
protected override void ResetParticle(Particle p) { p.Position = Position; p.VelocityPerTick = PVector2.Zero; p.MaxAge = Random.Next(-AgeVarience, AgeVarience) + MaxAge; p.Age = 0; }
public Constrained(Particle pa1, Particle pa2) { p1 = pa1; p2 = pa2; restLength = p1.position.distanceTo(p2.position); }
/// <summary> /// create a particle emmitter /// </summary> /// <param name="template">the template particle to use</param> /// <param name="pos">the start position of the emmitter</param> /// <param name="pow">the emmission power vector to use</param> /// <param name="rate">the rate to use</param> /// <param name="count">the count of particles per emmission</param> public Emitter(Particle template, Vector2 pos, Vector2 pow, float rate, int count) : this() { //tParticleTexture = tex; particleTemplate = new Particle(template); position = pos; power = pow; emitRate = rate; emitCount = count; }
public Particle(Particle particle) { position = new Vector3(particle.position.X, particle.position.Y, particle.position.Z); velocity = new Vector3(particle.velocity.X, particle.velocity.Y, particle.velocity.Z); acceleration = particle.acceleration; lifeSpan = particle.lifeSpan; age = 0f; size = particle.size; rotationVelocity = particle.rotationVelocity; rotationAngle = 0; SizeIncrease = particle.SizeIncrease; }
public void Scale(Particle particle, float ParticleLifeTime) { if (particle.TotalLifetime < ScaleStartTime) { particle.Scale = ScaleFrom; } else if (particle.TotalLifetime >= ScaleEndTime) { particle.Scale = ScaleTo; } else { particle.Scale = ScaleFrom + (((particle.TotalLifetime - ScaleStartTime) / (ScaleEndTime - ScaleStartTime)) * (ScaleTo - ScaleFrom)); } }
private void CalculateForces(Particle p, Attractor a) { // F = G(m1 * m2) / r^2 PVector2.Sub(ref a.Position, ref p.Position, out scratchV); scratchV.LengthSquared(out scratchF); if (scratchF > minDistanceSquared) { FInt.Divide(ref FInt.OneF, ref scratchF, out scratchF); if (scratchF != FInt.ZeroF) { // force along direction between FInt.Divide(ref scratchF, ref ratio, out scratchF); PVector2.Multiply(ref scratchV, ref scratchF, out scratchV); PVector2.Add(ref p.VelocityPerTick, ref scratchV, out p.VelocityPerTick); //p.VelocityPerTick += scratchV; } } }
public void CreateParticles() { Console.WriteLine("CreateParticles"); int u; int v; particles = new Particle[0]; // Create particles for (v = 0; v <= NrV; v++) { for (u = 0; u <= NrU; u++) { double up = u / (double)NrU; double vp = v / (double)NrV; THREE.Vector3 pos = ParamFunction(up, vp); double mass = ParticleConstants.MASS; particles.Push(new Particle(mass, pos)); } } }
/// <summary> /// Generate a single particle in the system. /// This function is used when particles are first created, and when they are regenerated /// </summary> /// <returns>New particle</returns> protected override Particle GenerateParticle() { // Generate random direction & speed for new particle float rndX = 2 * ((float)m_rand.NextDouble() - 0.5f); float rndY = 2 * ((float)m_rand.NextDouble() - 0.5f); float rndZ = 2 * ((float)m_rand.NextDouble() - 0.5f); // Create new particle at system's starting position Particle part = new Particle(m_Position, // With generated direction and speed new Vector(rndX, rndY, rndZ), m_Color, // And a random starting life m_rand.Next(50)); // Return newly created particle return part; }
private void Spawn() { if (particles.Count >= maxParticles) return; float x = (float)rng.Next(-1000, 1000) / 1000; float y = (float)rng.Next(-1000, 1000) / 1000; float a = (float)rng.Next(0, (int)(spawnArea * 1000)) / 1000; Vector2 offset = new Vector2(x, y); offset.Normalize(); offset *= a; Particle particle = new Particle(texture, spriteBatch, position + offset, rotation); if (rotateDirection == RotateDirection.RAND) { int roll = rng.Next(0, 2); particle.rotateDirection = roll == 0 ? RotateDirection.CW : RotateDirection.CCW; } else particle.rotateDirection = rotateDirection; particle.lifeTime = lifeTime.Next(rng); particle.startSize = startSize.Next(rng); particle.endSize = endSize.Next(rng); particle.normSize = normSize; particle.startRotation = startRotation.Next(rng); particle.endRotation = endRotation.Next(rng); particle.normRotation = normRotation; particle.startSpeed = startSpeed.Next(rng); particle.endSpeed = endSpeed.Next(rng); particle.normSpeed = normSpeed; particle.startAlpha = startAlpha.Next(rng); particle.endAlpha = endAlpha.Next(rng); particle.normAlpha = normAlpha; particle.startColor = startColor; particle.endColor = endColor; particle.normColor = normColor; particle.startStretch = startStretch.Next(rng); particle.endStretch = endStretch.Next(rng); particle.normStretch = normStretch; int angle = (int)(spawnAngle / 2 * 1000); float rot = rotation + ((float)rng.Next(-angle, angle) / 1000); particle.direction = new Vector2((float)Math.Sin(rot), (float)-Math.Cos(rot)); particle.facingDirection = rot; particle.randomDirection = randomAngle; particle.PreWarm(); particles.Add(particle); }
public void SpawnParticle(Point3D position, double speed, double size, double life) { if (this.particleList.Count > this.maxParticleCount) return; Particle p = new Particle(); p.Position = position; p.StartLife = life; p.Life = life; p.StartSize = size; p.Size = size; float x = 1.0f - (float)rand.NextDouble() * 2.0f; float z = 1.0f - (float)rand.NextDouble() * 2.0f; Vector3D v = new Vector3D(x, z, 0.0); v.Normalize(); v *= ((float)rand.NextDouble() + 0.25f) * (float)speed; p.Velocity = new Vector3D(v.X, v.Y, v.Z); p.Decay = 1.0f;// 0.5 + rand.NextDouble(); //if (p.Decay > 1.0) // p.Decay = 1.0; this.particleList.Add(p); }
// This method is called 60 times per second and is used to update positions, determine collisions, // get user input, and in this case, add new particles to the partiList if the user holds the left // mouse button. It also removes any dead particles that are taking up memory! protected override void Update(GameTime gameTime) { // Allows the game to exit - I added the "Escape" key part, so if the user presses it, we stop if ((GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)|| (Keyboard.GetState().IsKeyDown(Keys.Escape))) this.Exit(); // Grab the current mouse position and store it into "mouseX" and "mouseY" int mouseX = Mouse.GetState().X; int mouseY = Mouse.GetState().Y; // If the user presses the left mouse button, then we're going to generate 10 particles - // each going in a random direction! We'll add each one to the partiList. if (Mouse.GetState().LeftButton == ButtonState.Pressed) { for (int i = 0; i < 10; i++) { // Calculate a random direction (rotation) from 0 to 2 PI (it's in radians) double rot = generator.NextDouble() * Math.PI*2.0; // The particle's position will originate from the mouse position partPos = new Vector2(mouseX, mouseY); // It's velocity is based on using Sin and Cos of the rotation (from above). // If you have a question about this, please let me know! partVel = new Vector2((float)(Math.Cos(rot)*6.0), (float)(Math.Sin(rot) * 4.0 - 2.0)); // Bring the temp particle to life tempParticle = new Particle(this, partTex, partPos, partVel); // and add it to the partiList partiList.Add(tempParticle); } } // Call the Update() method for each particle in the partiList foreach (Particle p in partiList) { p.Update(); } // This is funky, but it's the way that we remove dead particles from the list. // You CANNOT use a foreach loop to do this (because it breaks the Iterator) for (int i = partiList.Count - 1; i >= 0; i--) { Particle temp = partiList[i]; if (!temp.isAlive) { partiList.Remove(temp); } } base.Update(gameTime); }
protected abstract void ResetParticle(Particle p);
/// <summary> /// Initialize the system /// </summary> private void InitSystem() { // Generate random direction & speed for new particle float rndX = 1 * ((float)m_rand.NextDouble() - 0.5f); float rndY = -2f - 1 * ((float)m_rand.NextDouble()); float rndZ = 1 * ((float)m_rand.NextDouble() - 0.5f); // Create new particle at system's starting position Particle part = new Particle(m_Position, // With generated direction and speed new Vector(rndX, rndY, rndZ), m_Color, // And a random starting life m_rand.Next(50)); // Create particle, and add it to the list of particles m_Particles.Add(part); }
/// <summary> /// Update all the particles in the system /// </summary> /// <returns>False - if there are no more particles in system /// True - otherwise</returns> public override bool Update() { Particle part; // Get number of particles in the system int count = m_Particles.Count; // If we're at the "rocket" stage if (stageRocket) { // Get single particle part = (Particle)m_Particles[0]; // Update the particle part.Update(); // If the particle is old enough if (part.Life > particleMaxLife) { // Change to firework stage stageRocket = !stageRocket; // Create all particles for (int i = 0; i < DEFAULT_NUM_PARTICLES; i++) { Particle newPart = new Particle(part.Position, // With generated direction and speed new Vector((float)Math.Cos(Math.PI * 2 * i/DEFAULT_NUM_PARTICLES), ((float)Math.Sin(Math.PI * 2 * i/DEFAULT_NUM_PARTICLES)/2)-0.75f, 0), m_Color, 0); m_Particles.Add(newPart); } // Remove "rocket" particle m_Particles.RemoveAt(0); } return true; } // If we're at the firework stage // For each particle for (int i=0; i<count; i++) { // Get particle from list part = (Particle)m_Particles[i]; // Update particle and check age part.Update(); if (part.Life > particleMaxLife) { // Remove old particles m_Particles.RemoveAt(i); // Update counter and index i--; count = m_Particles.Count; } } // If there are no more particles in the system if (m_Particles.Count <= 0) return false; return true; }
/// <summary> /// load emitter data /// </summary> /// <param name="contentManager">the game ContentManager</param> /// <param name="xmlFile">the xml file</param> /// <returns>error code, 0 is no error</returns> public int Load(ContentManager contentManager, string xmlFile) { Dictionary<string, Texture2D> loadedTextures = new Dictionary<string, Texture2D>(); Dictionary<string, VectorGraph> loadedGraphs = new Dictionary<string, VectorGraph>(); Dictionary<string, Particle> loadedParticles = new Dictionary<string, Particle>(); XElement document = XElement.Load(Path.Combine(contentManager.RootDirectory, xmlFile) + ".xml"); int end = xmlFile.LastIndexOf('\\') + 1; string directory = xmlFile.Remove(end, xmlFile.Length - end); //XElement multiEmitter = document.Element("MultiEmitter"); ///////////////////////////// //Textures #region Textures foreach (XElement texture in document.Element("Textures").Elements()) { Texture2D newTexture = contentManager.Load<Texture2D>(directory + texture.Attribute("texture").Value); loadedTextures.Add(texture.Name.LocalName, newTexture); } #endregion ///////////////////////////// //Graphs #region Graphs foreach (XElement graph in document.Element("Graphs").Elements()) { //make new graph VectorGraph newGraph; switch (graph.Attribute("type").Value) { case "Basic": newGraph = new BasicVectorGraph(); break; case "Bezier": newGraph = new BezierVectorGraph(); break; default: newGraph = new EmptyVectorGraph(); break; } //read through points in graph foreach (XElement point in graph.Elements()) { double x, y; if (double.TryParse(point.Attribute("x").Value, out x) && double.TryParse(point.Attribute("y").Value, out y)) { newGraph.AddPoint(new Vector2((float)x, (float)y)); } } //add graph to list loadedGraphs.Add(graph.Name.LocalName, newGraph); } #endregion ///////////////////////////// //Particles #region Particles foreach (XElement particle in document.Element("Particles").Elements()) { //make new Particle newParticle = new Particle(); //read through attributes //double angle; double length; double scale; int r, g, b, a; double x, y; //texture loadedTextures.TryGetValue(particle.Element("Texture").Attribute("texture").Value, out newParticle.texture); //life length if (double.TryParse(particle.Element("Life").Attribute("length").Value, out length)) { newParticle.lifeLength = (float)length; } //size scale and graph if (double.TryParse(particle.Element("Size").Attribute("scale").Value, out scale)) { newParticle.SetPixelScale((float)scale); } if (particle.Element("Size").Attribute("graph").Value != "") { loadedGraphs.TryGetValue(particle.Element("Size").Attribute("graph").Value, out newParticle.sizeGraph); } //colour and graph if (int.TryParse(particle.Element("Colour").Attribute("r").Value, out r) && int.TryParse(particle.Element("Colour").Attribute("g").Value, out g) && int.TryParse(particle.Element("Colour").Attribute("b").Value, out b) && int.TryParse(particle.Element("Colour").Attribute("a").Value, out a)) { newParticle.colour = new Color(r, g, b, a); } if (particle.Element("Colour").Attribute("graph").Value != "") { loadedGraphs.TryGetValue(particle.Element("Colour").Attribute("graph").Value, out newParticle.colourGraph); } // angle and graph //if (double.TryParse(particle.Element("Rotation").Attribute("angle").Value, out angle)) //{ // newParticle.rotation = (float)angle; //} if (particle.Element("Rotation").Attribute("graph").Value != "") { loadedGraphs.TryGetValue(particle.Element("Rotation").Attribute("graph").Value, out newParticle.rotationGraph); } //acceleration if (double.TryParse(particle.Element("Acceleration").Attribute("x").Value, out x) && double.TryParse(particle.Element("Acceleration").Attribute("y").Value, out y)) { newParticle.acceleration = new Vector2((float)x, (float)y); } //decay if (double.TryParse(particle.Element("Decay").Attribute("x").Value, out x) && double.TryParse(particle.Element("Decay").Attribute("y").Value, out y)) { newParticle.decay = new Vector2((float)x, (float)y); } //add loadedParticles.Add(particle.Name.LocalName, newParticle); } #endregion ///////////////////////////// //Emitters #region Emitters foreach (XElement emitter in document.Element("Emitters").Elements()) { //make new Emitter newEmitter;// = new Emitter(); Vector2 newOrigin = new Vector2(); Vector2 newPower = new Vector2(); float newDepth = 0.0f; float newRate = 0.0f; int newCount = 0; double x, y, depth; double rate; int count; List<BlendState> blendstateList = new List<BlendState>(); //read through attributes //Origin if (double.TryParse(emitter.Element("Origin").Attribute("x").Value, out x) && double.TryParse(emitter.Element("Origin").Attribute("y").Value, out y) && double.TryParse(emitter.Element("Origin").Attribute("depth").Value, out depth)) { newOrigin = new Vector2((float)x, (float)y); newDepth = (float)depth; } //power if (double.TryParse(emitter.Element("Power").Attribute("x").Value, out x) && double.TryParse(emitter.Element("Power").Attribute("y").Value, out y)) { newPower = new Vector2((float)x, (float)y); } //rate if (double.TryParse(emitter.Element("Rate").Attribute("rate").Value, out rate)) { newRate = (float)rate; } if (int.TryParse(emitter.Element("Rate").Attribute("count").Value, out count)) { newCount = count; } //blendstates foreach (XElement state in emitter.Element("BlendStates").Elements()) { switch (state.Attribute("state").Value) { case "Additive": blendstateList.Add(BlendState.Additive); break; case "NonPremultiplied": blendstateList.Add(BlendState.NonPremultiplied); break; case "Opaque": blendstateList.Add(BlendState.Opaque); break; default: blendstateList.Add(BlendState.AlphaBlend); break; } } //initialise and add Particle newParticle; if (loadedParticles.TryGetValue(emitter.Name.LocalName, out newParticle)) { newEmitter = new Emitter(newParticle, new Vector2(), newPower, newRate, newCount); newEmitter.blendStates = blendstateList; newEmitter.origin = newOrigin; newEmitter.depth = newDepth; newEmitter.emitFromSelf = emitFromSelf; EmitterList.Add(newEmitter); } } #endregion /////////////////// // Exit out return 0; }
/// <summary> /// emission logic /// </summary> /// <param name="position">position to emit at</param> public void Emit(Vector2 emitPos) { //thread sync updateParticles.WaitOne(); for (int i = 0; i < emitCount; ++i) { Particle newParticle = new Particle(particleTemplate); newParticle.position = emitPos; newParticle.depth = depth; double angle = Math.PI * 2.0 * random.NextDouble(); float scale = (float)random.NextDouble(); newParticle.velocity.X = (float)Math.Sin(angle) * scale * power.X; newParticle.velocity.Y = (float)Math.Cos(angle) * scale * power.Y; particles.Add(newParticle); } updateParticles.Set(); }
//Pure public static Tuple <Photon, Photon> Annialation(Particles.Particle Particle, Particles.Particle AntiParticle, FRandom Rand) // Simple collision { return(VectorFunctions.OppositeEjections(CreateAnnialationPhoton(Particle, AntiParticle), CreateAnnialationPhoton(Particle, AntiParticle), Rand)); }
/// <summary> /// copy constructor /// </summary> /// <param name="p">existing particle to copy</param> public Particle(Particle p) : this() { lifeLeft = p.lifeLeft; lifeLength = p.lifeLength; position = p.position; velocity = p.velocity; acceleration = p.acceleration; decay = p.decay; texture = p.texture; colour = p.colour; sizeScale = p.sizeScale; depth = p.depth; colourGraph = p.colourGraph; sizeGraph = p.sizeGraph; rotationGraph = p.rotationGraph; }
private void EmitParticle() { if (i > TextureList.Count - 1) i = 0; Particle particle = new Particle(TextureList[i], Position, (float)RandomizedDouble(ParticleSpeed), (float)RandomizedDouble(ParticleDirection), MathHelper.ToRadians((float)RandomizedDouble(ParticleRotation)), (float)RandomizedDouble(RotationSpeed), Opacity); ParticleList.Add(particle); EmittedNewParticle = true; LastEmittedParticle = particle; i++; }