private void Grid(int s, int e) { int count = 16 * 14; float scale = 1.3f; float rotation = (float)-Math.PI / 6; Func <int, Vector2> pattern = (int i) => { return(Patterns.Grid2D( Vectors.ScreenTopLeft.scaled(scale), Vectors.ScreenBottomRight.scaled(scale), 16, 9)(i) .up(100).rotated(rotation).scaled(1.2)); }; var sprites = new SpriteSet( layer, i => BlurredSquareOutline, i => OsbOrigin.Centre, i => pattern(i) , count ); float fade = 0.4f; //sprites.Fade(s, s + 200, 0.0f, fade); double wavelength = 0.4f; double duration = 5000; double[] shifts = new double[count]; for (int i = 0; i < count; i++) { shifts[i] = 1000 * (sprites.Get(i).InitialPosition - Vectors.Centre.left(Vectors.ScreenSize.X / 2)).Length / Vectors.ScreenSize.X / wavelength; } for (double t = s + 200; t < e - 200; t += duration) { int i = 0; foreach (var sprite in sprites.Sprites) { sprite.Fade(OsbEasing.InOutSine, t + shifts[i], t + duration / 2 + shifts[i], 0.02f, fade); sprite.Fade(OsbEasing.InOutSine, t + duration / 2 + shifts[i], t + duration + shifts[i], fade, 0.02f); i++; } } //sprites.Fade(e - 200, e, fade, 0.0); sprites.Scale(.7 * 1 / .7); sprites.Rotate(rotation); Vector2 d = Vectors.polar(rotation, 50); sprites.MoveRelative(OsbEasing.None, s, e, d, -d); var flashes = new SpriteSet( layer, i => BlurredSquareFilled, i => OsbOrigin.Centre, i => pattern(i), count ); float flashFade = 0.7f; flashes.MoveRelative(OsbEasing.None, s, e, d, -d); flashes.UseScalesOf(sprites); flashes.UseRotationsOf(sprites); flashes.Fade(s, 0); double[] prevTimes = new double[count]; for (int i = 0; i < count; i++) { prevTimes[i] = s; } for (double t = s; t < e; t += 50) { while (true) { int index = Random(0, count); float flashFade2 = flashFade * sprites.Get(index).OpacityAt(t) / fade; if (prevTimes[index] <= t) { flashes.Fade(OsbEasing.OutExpo, t, t + 100, 0, flashFade2, index, 1); flashes.Fade(OsbEasing.Out, t + 100, t + 2000, flashFade2, 0, index, 1); prevTimes[index] = t + 2000; break; } } } flashes.Additive(); }