private void UpdateVisualProperties(Particle particle, ParticleValues values) { particle.LayerDepth = particle.AgeInFrames / (float)values.AgeInFrames; particle.Scale = values.Scale[particle.AgeInFrames] + particle.PengInput * _scaleInputScale; particle.Alpha = values.Alpha[particle.AgeInFrames] + particle.PengInput * _alphaInputScale; }
public bool Update(Particle particle) { // Note: This method is run potentially very often. It must be kept quick. var precalcIndex = Math.Abs(particle.Random) % PRECALC_COUNT; var values = _precalculatedValues[precalcIndex]; if (particle.AgeInFrames >= values.AgeInFrames) { if (_areParticlesImmortal) particle.AgeInFrames -= values.AgeInFrames; // Restart iteration through precalculated values. else return true; } UpdateVisualProperties(particle, values); UpdatePhysicalProperties(particle, values); particle.AgeInFrames++; return false; }
private void UpdatePhysicalProperties(Particle particle, ParticleValues values) { var acceleration = values.Acceleration[particle.AgeInFrames] + particle.PengInput * _accelerationInputScale; var rotationSpeed = values.RotationSpeed[particle.AgeInFrames] + particle.PengInput * _rotationSpeedInputScale; particle.Pos += particle.Move * _elapsedSeconds; particle.Move += particle.DirectionVector * acceleration * _elapsedSeconds; particle.Rotation += rotationSpeed * _elapsedSeconds; particle.Move *= _dragMultiplier; }
private void GobCreation(Gob gob, int createCount, int i, int emitType, ref List<Particle> particles) { // Find out emission parameters. // We have to loop because some choices of parameters may not be wanted. int maxAttempts = 20; bool attemptOk = false; for (int attempt = 0; !attemptOk && attempt < maxAttempts; ++attempt) { bool lastAttempt = attempt == maxAttempts - 1; attemptOk = true; int random = RandomHelper.GetRandomInt(); float directionAngle, rotation; Vector2 directionUnit, pos, move; switch (Peng.ParticleCoordinates) { case Peng.CoordinateSystem.Peng: RandomHelper.GetRandomCirclePoint(_radius, -_sprayAngle, _sprayAngle, out pos, out directionUnit, out directionAngle); move = _initialVelocity.GetValue(0, random) * directionUnit; switch (_facingType) { case FacingType.Directed: rotation = 0; break; case FacingType.Forward: rotation = directionAngle; break; case FacingType.Random: rotation = RandomHelper.GetRandomFloat(0, MathHelper.TwoPi); break; default: throw new Exception("SprayEmitter: Unhandled particle facing type " + _facingType); } break; case Peng.CoordinateSystem.Game: { float posWeight = (i + 1) / (float)createCount; var startPos = Peng.OldDrawPos; var endPos = Peng.Pos + Peng.DrawPosOffset; var iPos = Vector2.Lerp(startPos, endPos, posWeight); var drawRotation = Peng.Rotation + Peng.DrawRotationOffset; RandomHelper.GetRandomCirclePoint(_radius, drawRotation - _sprayAngle, drawRotation + _sprayAngle, out pos, out directionUnit, out directionAngle); pos += iPos; move = Peng.Move + _initialVelocity.GetValue(0, random) * directionUnit; // HACK: 'move' will be added to 'pos' in PhysicalUpdater during this same frame pos -= move * (float)Peng.Game.GameTime.ElapsedGameTime.TotalSeconds; switch (_facingType) { case FacingType.Directed: rotation = Peng.Rotation; break; case FacingType.Forward: rotation = directionAngle; break; case FacingType.Random: rotation = RandomHelper.GetRandomFloat(0, MathHelper.TwoPi); break; default: throw new Exception("SprayEmitter: Unhandled particle facing type " + _facingType); } } break; case Peng.CoordinateSystem.FixedToPeng: pos = Vector2.Zero; move = Vector2.Zero; rotation = 0; directionAngle = 0; break; default: throw new ApplicationException("SprayEmitter: Unhandled peng coordinate system " + Peng.ParticleCoordinates); } // Set the thing's parameters. if (emitType < TextureNames.Length) { var particle = new Particle { Alpha = 1, Move = move, PengInput = Peng.Input, Pos = pos, Random = random, Direction = directionAngle, DirectionVector = Vector2.UnitX.Rotate(directionAngle), Rotation = rotation, Scale = 1, Texture = Peng.Game.Content.Load<Texture2D>(TextureNames[emitType]), }; particles.Add(particle); } else { // Bail out if the position is not free for the gob. if (!lastAttempt && !Peng.Arena.IsFreePosition(new Circle(pos, Gob.SMALL_GOB_PHYSICAL_RADIUS))) { attemptOk = false; continue; } gob.Owner = Peng.Owner; gob.ResetPos(pos, move, rotation); Peng.Arena.Gobs.Add(gob); } } }