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;
 }
Exemple #4
0
        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);
                }
            }
        }