Ejemplo n.º 1
0
        public virtual void Update(LevelTime levelTime)
        {
            songPosition = levelTime.SongPosition; // used in draw call

            /* I'm either insane or insanely brilliant, but it's probably the former.
             * The problem: Replays kept desyncing because spawner movement was still
             *   framerate-dependent due to accumulating floating point errors
             *   (or something like that).
             * A normal person would've just locked the update loop to n ticks/s
             *   and called it a day, but in MonoGame, as far as I'm aware,
             *   that also caps the framerate at n fps, and I didn't want to do that.
             * Instead, I decided to calculate the spawner positions independent of
             *   game state to sidestep this problem.
             * To do this, I turn the SR and TW node lists into piecewise functions,
             *   multiply them to get a combined movement function, and then,
             *   for each frame, multiply the rotation/ms factor by the integral
             *   of that function between 0 and the current song position.
             * This appears to have sorted out my issues for the most part. Spawner
             *   movement still varies a little bit in moments with high SR*TW values,
             *   but since these variances don't accumulate anymore, it always
             *   catches itself when the rotation slows down.
             */
            var totalIntegral = combinedSpinWarpFunction.IntegralTo(songPosition);

            for (int i = 0; i < Spawners.Count; i++)
            {
                var spawner = Spawners[i];
                if (spawner.IsStillInUse(levelTime.SongPosition) || spawner.ActiveFlares.Count > 0)
                {
                    spawner.Angle = (float)(spawnerAngles[i]
                                            + MathEx.WrapAngle(totalIntegral * Spawner.RotationPerMs));
                    spawner.Update(levelTime);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates one wave of a shot.
        /// </summary>
        public List <Bullet> Create(Vector2 spawnPoint, float spawnerAngle, Vector2 playerCenter,
                                    LevelColors colors)
        {
            var bullets = new List <Bullet>(Amount);

            double waveAngle = spawnerAngle + (90 * MathEx.DegToRad);

            if (Amount > 1)
            {
                waveAngle += Angle / -2;
            }

            if (Aim == Aim.Player)
            {
                float playerAngle = (float)Math.Atan2(
                    spawnPoint.Y - playerCenter.Y,
                    spawnPoint.X - playerCenter.X)
                                    - spawnerAngle;
                waveAngle += playerAngle;
            }

            MathEx.WrapAngle(waveAngle);

            var angleStep = Angle / (Amount - 1);

            for (int i = 0; i < Amount; i++)
            {
                var bulletAngle = waveAngle + Offset;

                if (BulletType == BulletType.Homing)
                {
                    bullets.Add(CreateHomingBullet(spawnPoint, (float)bulletAngle,
                                                   (float)Speed, (float)HomingLifespan, colors));
                }
                else
                {
                    bullets.Add(CreateBullet(BulletType, spawnPoint, (float)bulletAngle,
                                             (float)Speed, colors));
                }
                waveAngle += angleStep;
            }

            return(bullets);
        }